Skip to content

Commit 667caac

Browse files
committed
[NativeAOT] correctly initalize CONTEXT before failing fast
1 parent f60d188 commit 667caac

File tree

4 files changed

+70
-3
lines changed

4 files changed

+70
-3
lines changed

src/coreclr/nativeaot/Runtime/EHHelpers.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,18 @@ COOP_PINVOKE_HELPER(int32_t, RhGetModuleFileName, (HANDLE moduleHandle, _Out_ co
9090

9191
COOP_PINVOKE_HELPER(void, RhpCopyContextFromExInfo, (void * pOSContext, int32_t cbOSContext, PAL_LIMITED_CONTEXT * pPalContext))
9292
{
93-
UNREFERENCED_PARAMETER(cbOSContext);
9493
ASSERT((size_t)cbOSContext >= sizeof(CONTEXT));
94+
memset(pOSContext, 0, cbOSContext);
9595
CONTEXT* pContext = (CONTEXT *)pOSContext;
96+
97+
#ifndef HOST_WASM
98+
if (TryPopulateControlSegmentRegisters(pContext))
99+
{
100+
pContext->ContextFlags |= CONTEXT_CONTROL;
101+
}
102+
pContext->ContextFlags |= CONTEXT_INTEGER;
103+
#endif
104+
96105
#if defined(UNIX_AMD64_ABI)
97106
pContext->Rip = pPalContext->IP;
98107
pContext->Rsp = pPalContext->Rsp;

src/coreclr/nativeaot/Runtime/PalRedhawk.h

Lines changed: 29 additions & 2 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;
@@ -232,6 +237,11 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
232237
} CONTEXT, *PCONTEXT;
233238
#elif defined(HOST_ARM)
234239

240+
#define CONTEXT_ARM 0x00200000L
241+
242+
#define CONTEXT_CONTROL (CONTEXT_ARM | 0x1L)
243+
#define CONTEXT_INTEGER (CONTEXT_ARM | 0x2L)
244+
235245
#define ARM_MAX_BREAKPOINTS 8
236246
#define ARM_MAX_WATCHPOINTS 1
237247

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

277287
#elif defined(HOST_X86)
288+
289+
#define CONTEXT_i386 0x00010000L
290+
291+
#define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
292+
#define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
293+
278294
#define SIZE_OF_80387_REGISTERS 80
279295
#define MAXIMUM_SUPPORTED_EXTENSION 512
280296

@@ -329,6 +345,11 @@ typedef struct _CONTEXT {
329345

330346
#elif defined(HOST_ARM64)
331347

348+
#define CONTEXT_ARM64 0x00400000L
349+
350+
#define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x1L)
351+
#define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x2L)
352+
332353
// Specify the number of breakpoints and watchpoints that the OS
333354
// will track. Architecturally, ARM64 supports up to 16. In practice,
334355
// however, almost no one implements more than 4 of each.
@@ -484,8 +505,6 @@ typedef enum _EXCEPTION_DISPOSITION {
484505
//#endif // !DACCESS_COMPILE
485506
#endif // !_INC_WINDOWS
486507

487-
488-
489508
#ifndef DACCESS_COMPILE
490509
#ifndef _INC_WINDOWS
491510

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

636+
// For platforms that have segment registers in the CONTEXT_CONTROL set that
637+
// are not saved in PAL_LIMITED_CONTEXT, this captures them from the current
638+
// thread and saves them in `pContext`.
639+
// This function returns true if the current plateform has no such registers or
640+
// if the registers are successfully saved in `pContext`.
641+
// Other false is returned.
642+
REDHAWK_PALIMPORT bool REDHAWK_PALAPI TryPopulateControlSegmentRegisters(CONTEXT* pContext);
643+
617644
REDHAWK_PALIMPORT int32_t REDHAWK_PALAPI PalGetProcessCpuCount();
618645

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

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,16 @@ extern "C" int32_t _stricmp(const char *string1, const char *string2)
10681068
return strcasecmp(string1, string2);
10691069
}
10701070

1071+
REDHAWK_PALIMPORT bool REDHAWK_PALAPI TryPopulateControlSegmentRegisters(CONTEXT* pContext)
1072+
{
1073+
#if defined(TARGET_X86) || defined(TARGET_AMD64)
1074+
// TODO: attempt to fill in SegCs and SegSs
1075+
return false;
1076+
#else
1077+
return true;
1078+
#endif
1079+
}
1080+
10711081
uint32_t g_RhNumberOfProcessors;
10721082

10731083
REDHAWK_PALEXPORT int32_t PalGetProcessCpuCount()

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,27 @@ REDHAWK_PALEXPORT void REDHAWK_PALAPI PalRestoreContext(CONTEXT * pCtx)
446446
RtlRestoreContext(pCtx, NULL);
447447
}
448448

449+
REDHAWK_PALIMPORT bool REDHAWK_PALAPI TryPopulateControlSegmentRegisters(CONTEXT* pContext)
450+
{
451+
#if defined(TARGET_X86) || defined(TARGET_AMD64)
452+
HANDLE hThread = GetCurrentThread();
453+
454+
CONTEXT ctx;
455+
memset(&ctx, 0, sizeof(ctx));
456+
ctx.ContextFlags = CONTEXT_CONTROL;
457+
458+
if (!GetThreadContext(hThread, &ctx))
459+
{
460+
return false;
461+
}
462+
463+
pContext->SegCs = ctx.SegCs;
464+
pContext->SegSs = ctx.SegSs;
465+
#endif //defined(TARGET_X86) || defined(TARGET_AMD64)
466+
467+
return true;
468+
}
469+
449470
static PalHijackCallback g_pHijackCallback;
450471

451472
#ifdef FEATURE_SPECIAL_USER_MODE_APC

0 commit comments

Comments
 (0)