Skip to content

Commit b4f6d21

Browse files
github-actions[bot]AustinWiseVSadov
authored
[release/7.0] [NativeAOT] correctly initalize CONTEXT before failing fast (#81837)
* [NativeAOT] correctly initalize CONTEXT before failing fast * Switch from using GetThreadContext to RtlCaptureContext. * Add a better explination of why the function is unimplmented on Unix. * Update src/coreclr/nativeaot/Runtime/PalRedhawk.h Co-authored-by: Vladimir Sadov <[email protected]> * Respond to feedback: unconditionally set CONTEXT_CONTROL * Respond to feedback: consolidate setting of ContextFlags. * On second thought, don't add a second layer of ifdef nesting. --------- Co-authored-by: Austin Wise <[email protected]> Co-authored-by: Vladimir Sadov <[email protected]>
1 parent 3c73365 commit b4f6d21

File tree

4 files changed

+57
-1
lines changed

4 files changed

+57
-1
lines changed

src/coreclr/nativeaot/Runtime/EHHelpers.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,19 @@ COOP_PINVOKE_HELPER(int32_t, RhGetModuleFileName, (HANDLE moduleHandle, _Out_ co
9191

9292
COOP_PINVOKE_HELPER(void, RhpCopyContextFromExInfo, (void * pOSContext, int32_t cbOSContext, PAL_LIMITED_CONTEXT * pPalContext))
9393
{
94-
UNREFERENCED_PARAMETER(cbOSContext);
9594
ASSERT((size_t)cbOSContext >= sizeof(CONTEXT));
9695
CONTEXT* pContext = (CONTEXT *)pOSContext;
96+
97+
#ifndef HOST_WASM
98+
99+
memset(pOSContext, 0, cbOSContext);
100+
pContext->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
101+
102+
// Fill in CONTEXT_CONTROL registers that were not captured in PAL_LIMITED_CONTEXT.
103+
PopulateControlSegmentRegisters(pContext);
104+
105+
#endif // !HOST_WASM
106+
97107
#if defined(UNIX_AMD64_ABI)
98108
pContext->Rip = pPalContext->IP;
99109
pContext->Rsp = pPalContext->Rsp;

src/coreclr/nativeaot/Runtime/PalRedhawk.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ struct FILETIME
112112

113113
#ifdef HOST_AMD64
114114

115+
#define CONTEXT_AMD64 0x00100000L
116+
117+
#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x00000001L)
118+
#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x00000002L)
119+
115120
typedef struct DECLSPEC_ALIGN(16) _XSAVE_FORMAT {
116121
uint16_t ControlWord;
117122
uint16_t StatusWord;
@@ -224,6 +229,11 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
224229
} CONTEXT, *PCONTEXT;
225230
#elif defined(HOST_ARM)
226231

232+
#define CONTEXT_ARM 0x00200000L
233+
234+
#define CONTEXT_CONTROL (CONTEXT_ARM | 0x1L)
235+
#define CONTEXT_INTEGER (CONTEXT_ARM | 0x2L)
236+
227237
#define ARM_MAX_BREAKPOINTS 8
228238
#define ARM_MAX_WATCHPOINTS 1
229239

@@ -267,6 +277,12 @@ typedef struct DECLSPEC_ALIGN(8) _CONTEXT {
267277
} CONTEXT, *PCONTEXT;
268278

269279
#elif defined(HOST_X86)
280+
281+
#define CONTEXT_i386 0x00010000L
282+
283+
#define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
284+
#define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
285+
270286
#define SIZE_OF_80387_REGISTERS 80
271287
#define MAXIMUM_SUPPORTED_EXTENSION 512
272288

@@ -321,6 +337,11 @@ typedef struct _CONTEXT {
321337

322338
#elif defined(HOST_ARM64)
323339

340+
#define CONTEXT_ARM64 0x00400000L
341+
342+
#define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x1L)
343+
#define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x2L)
344+
324345
// Specify the number of breakpoints and watchpoints that the OS
325346
// will track. Architecturally, ARM64 supports up to 16. In practice,
326347
// however, almost no one implements more than 4 of each.
@@ -596,6 +617,11 @@ REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalGetCompleteThreadContext(HANDLE hThread
596617
REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalSetThreadContext(HANDLE hThread, _Out_ CONTEXT * pCtx);
597618
REDHAWK_PALIMPORT void REDHAWK_PALAPI PalRestoreContext(CONTEXT * pCtx);
598619

620+
// For platforms that have segment registers in the CONTEXT_CONTROL set that
621+
// are not saved in PAL_LIMITED_CONTEXT, this captures them from the current
622+
// thread and saves them in `pContext`.
623+
REDHAWK_PALIMPORT void REDHAWK_PALAPI PopulateControlSegmentRegisters(CONTEXT* pContext);
624+
599625
REDHAWK_PALIMPORT int32_t REDHAWK_PALAPI PalGetProcessCpuCount();
600626

601627
// Retrieves the entire range of memory dedicated to the calling thread's stack. This does

src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,14 @@ extern "C" int32_t _stricmp(const char *string1, const char *string2)
11001100
return strcasecmp(string1, string2);
11011101
}
11021102

1103+
REDHAWK_PALIMPORT void REDHAWK_PALAPI PopulateControlSegmentRegisters(CONTEXT* pContext)
1104+
{
1105+
#if defined(TARGET_X86) || defined(TARGET_AMD64)
1106+
// Currently the CONTEXT is only used on Windows for RaiseFailFastException.
1107+
// So we punt on filling in SegCs and SegSs for now.
1108+
#endif
1109+
}
1110+
11031111
uint32_t g_RhNumberOfProcessors;
11041112

11051113
REDHAWK_PALEXPORT int32_t PalGetProcessCpuCount()

src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,18 @@ REDHAWK_PALEXPORT void REDHAWK_PALAPI PalRestoreContext(CONTEXT * pCtx)
437437
RtlRestoreContext(pCtx, NULL);
438438
}
439439

440+
REDHAWK_PALIMPORT void REDHAWK_PALAPI PopulateControlSegmentRegisters(CONTEXT* pContext)
441+
{
442+
#if defined(TARGET_X86) || defined(TARGET_AMD64)
443+
CONTEXT ctx;
444+
445+
RtlCaptureContext(&ctx);
446+
447+
pContext->SegCs = ctx.SegCs;
448+
pContext->SegSs = ctx.SegSs;
449+
#endif //defined(TARGET_X86) || defined(TARGET_AMD64)
450+
}
451+
440452
static PalHijackCallback g_pHijackCallback;
441453

442454
REDHAWK_PALEXPORT UInt32_BOOL REDHAWK_PALAPI PalRegisterHijackCallback(_In_ PalHijackCallback callback)

0 commit comments

Comments
 (0)