COOP_PINVOKE_HELPER(void, RhpCopyContextFromExInfo, (void * pOSContext, int32_t cbOSContext, PAL_LIMITED_CONTEXT * pPalContext))
{
- UNREFERENCED_PARAMETER(cbOSContext);
ASSERT((size_t)cbOSContext >= sizeof(CONTEXT));
CONTEXT* pContext = (CONTEXT *)pOSContext;
+
+#ifndef HOST_WASM
+
+ memset(pOSContext, 0, cbOSContext);
+ pContext->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
+
+ // Fill in CONTEXT_CONTROL registers that were not captured in PAL_LIMITED_CONTEXT.
+ PopulateControlSegmentRegisters(pContext);
+
+#endif // !HOST_WASM
+
#if defined(UNIX_AMD64_ABI)
pContext->Rip = pPalContext->IP;
pContext->Rsp = pPalContext->Rsp;
#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;
} 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
} 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
#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.
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`.
+REDHAWK_PALIMPORT void REDHAWK_PALAPI PopulateControlSegmentRegisters(CONTEXT* pContext);
+
REDHAWK_PALIMPORT int32_t REDHAWK_PALAPI PalGetProcessCpuCount();
// Retrieves the entire range of memory dedicated to the calling thread's stack. This does
return strcasecmp(string1, string2);
}
+REDHAWK_PALIMPORT void REDHAWK_PALAPI PopulateControlSegmentRegisters(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.
+#endif
+}
+
uint32_t g_RhNumberOfProcessors;
REDHAWK_PALEXPORT int32_t PalGetProcessCpuCount()
RtlRestoreContext(pCtx, NULL);
}
+REDHAWK_PALIMPORT void REDHAWK_PALAPI PopulateControlSegmentRegisters(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)
+}
+
static PalHijackCallback g_pHijackCallback;
#ifdef FEATURE_SPECIAL_USER_MODE_APC