Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NativeAOT] correctly initalize CONTEXT before failing fast #81010

Merged
merged 7 commits into from
Feb 6, 2023
11 changes: 10 additions & 1 deletion src/coreclr/nativeaot/Runtime/EHHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,18 @@ COOP_PINVOKE_HELPER(int32_t, RhGetModuleFileName, (HANDLE moduleHandle, _Out_ co

COOP_PINVOKE_HELPER(void, RhpCopyContextFromExInfo, (void * pOSContext, int32_t cbOSContext, PAL_LIMITED_CONTEXT * pPalContext))
{
UNREFERENCED_PARAMETER(cbOSContext);
ASSERT((size_t)cbOSContext >= sizeof(CONTEXT));
memset(pOSContext, 0, cbOSContext);
CONTEXT* pContext = (CONTEXT *)pOSContext;

#ifndef HOST_WASM
if (TryPopulateControlSegmentRegisters(pContext))
{
pContext->ContextFlags |= CONTEXT_CONTROL;
AustinWise marked this conversation as resolved.
Show resolved Hide resolved
}
pContext->ContextFlags |= CONTEXT_INTEGER;
#endif

#if defined(UNIX_AMD64_ABI)
pContext->Rip = pPalContext->IP;
pContext->Rsp = pPalContext->Rsp;
Expand Down
31 changes: 29 additions & 2 deletions src/coreclr/nativeaot/Runtime/PalRedhawk.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ struct FILETIME

#ifdef HOST_AMD64

#define CONTEXT_AMD64 0x00100000L

#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x00000001L)
#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x00000002L)

typedef struct DECLSPEC_ALIGN(16) _XSAVE_FORMAT {
uint16_t ControlWord;
uint16_t StatusWord;
Expand Down Expand Up @@ -232,6 +237,11 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
} CONTEXT, *PCONTEXT;
#elif defined(HOST_ARM)

#define CONTEXT_ARM 0x00200000L

#define CONTEXT_CONTROL (CONTEXT_ARM | 0x1L)
#define CONTEXT_INTEGER (CONTEXT_ARM | 0x2L)

#define ARM_MAX_BREAKPOINTS 8
#define ARM_MAX_WATCHPOINTS 1

Expand Down Expand Up @@ -275,6 +285,12 @@ typedef struct DECLSPEC_ALIGN(8) _CONTEXT {
} CONTEXT, *PCONTEXT;

#elif defined(HOST_X86)

#define CONTEXT_i386 0x00010000L

#define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
#define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI

#define SIZE_OF_80387_REGISTERS 80
#define MAXIMUM_SUPPORTED_EXTENSION 512

Expand Down Expand Up @@ -329,6 +345,11 @@ typedef struct _CONTEXT {

#elif defined(HOST_ARM64)

#define CONTEXT_ARM64 0x00400000L

#define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x1L)
#define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x2L)

// Specify the number of breakpoints and watchpoints that the OS
// will track. Architecturally, ARM64 supports up to 16. In practice,
// however, almost no one implements more than 4 of each.
Expand Down Expand Up @@ -484,8 +505,6 @@ typedef enum _EXCEPTION_DISPOSITION {
//#endif // !DACCESS_COMPILE
#endif // !_INC_WINDOWS



#ifndef DACCESS_COMPILE
#ifndef _INC_WINDOWS

Expand Down Expand Up @@ -614,6 +633,14 @@ REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalGetCompleteThreadContext(HANDLE hThread
REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalSetThreadContext(HANDLE hThread, _Out_ CONTEXT * pCtx);
REDHAWK_PALIMPORT void REDHAWK_PALAPI PalRestoreContext(CONTEXT * pCtx);

// For platforms that have segment registers in the CONTEXT_CONTROL set that
// are not saved in PAL_LIMITED_CONTEXT, this captures them from the current
// thread and saves them in `pContext`.
// This function returns true if the current plateform has no such registers or
AustinWise marked this conversation as resolved.
Show resolved Hide resolved
// if the registers are successfully saved in `pContext`.
// Other false is returned.
REDHAWK_PALIMPORT bool REDHAWK_PALAPI TryPopulateControlSegmentRegisters(CONTEXT* pContext);

REDHAWK_PALIMPORT int32_t REDHAWK_PALAPI PalGetProcessCpuCount();

// Retrieves the entire range of memory dedicated to the calling thread's stack. This does
Expand Down
11 changes: 11 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,17 @@ extern "C" int32_t _stricmp(const char *string1, const char *string2)
return strcasecmp(string1, string2);
}

REDHAWK_PALIMPORT bool REDHAWK_PALAPI TryPopulateControlSegmentRegisters(CONTEXT* pContext)
{
#if defined(TARGET_X86) || defined(TARGET_AMD64)
// Currently the CONTEXT is only used on Windows for RaiseFailFastException.
// So we punt on filling in SegCs and SegSs for now.
return false;
#else
return true;
#endif
}

uint32_t g_RhNumberOfProcessors;

REDHAWK_PALEXPORT int32_t PalGetProcessCpuCount()
Expand Down
14 changes: 14 additions & 0 deletions src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,20 @@ REDHAWK_PALEXPORT void REDHAWK_PALAPI PalRestoreContext(CONTEXT * pCtx)
RtlRestoreContext(pCtx, NULL);
}

REDHAWK_PALIMPORT bool REDHAWK_PALAPI TryPopulateControlSegmentRegisters(CONTEXT* pContext)
{
#if defined(TARGET_X86) || defined(TARGET_AMD64)
CONTEXT ctx;

RtlCaptureContext(&ctx);

pContext->SegCs = ctx.SegCs;
pContext->SegSs = ctx.SegSs;
#endif //defined(TARGET_X86) || defined(TARGET_AMD64)

return true;
}

static PalHijackCallback g_pHijackCallback;

#ifdef FEATURE_SPECIAL_USER_MODE_APC
Expand Down