// in context2.S
extern void CONTEXT_CaptureContext(LPCONTEXT lpContext);
+#define CONTEXT_AREA_MASK 0xffff
#ifdef _X86_
#define CONTEXT_ALL_FLOATING (CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS)
#elif defined(_AMD64_)
}
if (lpContext->ContextFlags &
- (CONTEXT_CONTROL | CONTEXT_INTEGER))
+ (CONTEXT_CONTROL | CONTEXT_INTEGER) & CONTEXT_AREA_MASK)
{
if (CONTEXT_GetRegisters(dwProcessId, lpContext) == FALSE)
{
}
if (lpContext->ContextFlags &
- (CONTEXT_CONTROL | CONTEXT_INTEGER))
+ (CONTEXT_CONTROL | CONTEXT_INTEGER) & CONTEXT_AREA_MASK)
{
#if HAVE_PT_REGS
if (ptrace((__ptrace_request)PT_GETREGS, dwProcessId, (caddr_t)&ptrace_registers, 0) == -1)
ASSERT("Don't know how to set the context of another process on this platform!");
return FALSE;
#endif
- if (lpContext->ContextFlags & CONTEXT_CONTROL)
+ if (lpContext->ContextFlags & CONTEXT_CONTROL & CONTEXT_AREA_MASK)
{
ASSIGN_CONTROL_REGS
}
- if (lpContext->ContextFlags & CONTEXT_INTEGER)
+ if (lpContext->ContextFlags & CONTEXT_INTEGER & CONTEXT_AREA_MASK)
{
ASSIGN_INTEGER_REGS
}
mach_msg_type_number_t StateCount;
thread_state_flavor_t StateFlavor;
- if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS))
+ if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK)
{
#ifdef _X86_
x86_thread_state32_t State;
CONTEXT_GetThreadContextFromThreadState(StateFlavor, (thread_state_t)&State, lpContext);
}
- if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING) {
+ if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING & CONTEXT_AREA_MASK) {
#ifdef _X86_
x86_float_state32_t State;
StateFlavor = x86_FLOAT_STATE32;
CONTEXT_GetThreadContextFromThreadState(StateFlavor, (thread_state_t)&State, lpContext);
}
+#if defined(_AMD64_) && defined(XSTATE_SUPPORTED)
+ if (lpContext->ContextFlags & CONTEXT_XSTATE & CONTEXT_AREA_MASK) {
+ x86_avx_state64_t State;
+ StateFlavor = x86_AVX_STATE64;
+ StateCount = sizeof(State) / sizeof(natural_t);
+ MachRet = thread_get_state(Port, StateFlavor, (thread_state_t)&State, &StateCount);
+ if (MachRet != KERN_SUCCESS)
+ {
+ ASSERT("thread_get_state(XSTATE) failed: %d\n", MachRet);
+ goto exit;
+ }
+
+ CONTEXT_GetThreadContextFromThreadState(StateFlavor, (thread_state_t)&State, lpContext);
+ }
+#endif
+
exit:
return MachRet;
}
{
#ifdef _X86_
case x86_THREAD_STATE32:
- if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS))
+ if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK)
{
x86_thread_state32_t *pState = (x86_thread_state32_t *)threadState;
{
x86_float_state32_t *pState = (x86_float_state32_t *)threadState;
- if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT)
+ if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT & CONTEXT_AREA_MASK)
{
lpContext->FloatSave.ControlWord = *(DWORD*)&pState->fpu_fcw;
lpContext->FloatSave.StatusWord = *(DWORD*)&pState->fpu_fsw;
memcpy(&lpContext->FloatSave.RegisterArea[i * 10], (&pState->fpu_stmm0)[i].mmst_reg, 10);
}
- if (lpContext->ContextFlags & CONTEXT_EXTENDED_REGISTERS)
+ if (lpContext->ContextFlags & CONTEXT_EXTENDED_REGISTERS & CONTEXT_AREA_MASK)
{
// The only extended register information that Mach will tell us about are the xmm register values.
// Both Windows and Mach store the registers in a packed layout (each of the 8 registers is 16 bytes)
#elif defined(_AMD64_)
case x86_THREAD_STATE64:
- if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS))
+ if (lpContext->ContextFlags & (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) & CONTEXT_AREA_MASK)
{
x86_thread_state64_t *pState = (x86_thread_state64_t *)threadState;
break;
case x86_FLOAT_STATE64:
- if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT)
+ if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT & CONTEXT_AREA_MASK)
{
x86_float_state64_t *pState = (x86_float_state64_t *)threadState;
memcpy(&lpContext->Xmm0, &pState->__fpu_xmm0, 16 * 16);
}
break;
+
+#ifdef XSTATE_SUPPORTED
+ case x86_AVX_STATE64:
+ if (lpContext->ContextFlags & CONTEXT_XSTATE & CONTEXT_AREA_MASK)
+ {
+ x86_avx_state64_t *pState = (x86_avx_state64_t *)threadState;
+ memcpy(&lpContext->VectorRegister, &pState->__fpu_ymmh0, 16 * 16);
+ }
+ break;
+#endif
#else
#error Unexpected architecture.
#endif
mach_msg_type_number_t StateCount;
thread_state_flavor_t StateFlavor;
- if (lpContext->ContextFlags & (CONTEXT_CONTROL|CONTEXT_INTEGER))
+ if (lpContext->ContextFlags & (CONTEXT_CONTROL|CONTEXT_INTEGER) & CONTEXT_AREA_MASK)
{
#ifdef _X86_
x86_thread_state32_t State;
}
}
- if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING)
+ if (lpContext->ContextFlags & CONTEXT_ALL_FLOATING & CONTEXT_AREA_MASK)
{
#ifdef _X86_
x86_float_state32_t State;
StateFlavor = x86_FLOAT_STATE32;
+ StateCount = sizeof(State) / sizeof(natural_t);
#elif defined(_AMD64_)
+#ifdef XSTATE_SUPPORTED
+ // We're relying on the fact that the initial portion of
+ // x86_avx_state64_t is identical to x86_float_state64_t.
+ // Check a few fields to make sure the assumption is correct.
+ static_assert_no_msg(sizeof(x86_avx_state64_t) > sizeof(x86_float_state64_t));
+ static_assert_no_msg(offsetof(x86_avx_state64_t, __fpu_fcw) == offsetof(x86_float_state64_t, __fpu_fcw));
+ static_assert_no_msg(offsetof(x86_avx_state64_t, __fpu_xmm0) == offsetof(x86_float_state64_t, __fpu_xmm0));
+
+ x86_avx_state64_t State;
+ if (lpContext->ContextFlags & CONTEXT_XSTATE & CONTEXT_AREA_MASK)
+ {
+ StateFlavor = x86_AVX_STATE64;
+ StateCount = sizeof(State) / sizeof(natural_t);
+ }
+ else
+ {
+ StateFlavor = x86_FLOAT_STATE64;
+ StateCount = sizeof(x86_float_state64_t) / sizeof(natural_t);
+ }
+#else
x86_float_state64_t State;
StateFlavor = x86_FLOAT_STATE64;
+ StateCount = sizeof(State) / sizeof(natural_t);
+#endif
#else
#error Unexpected architecture.
#endif
- StateCount = sizeof(State) / sizeof(natural_t);
-
// If we're setting only one of the floating point or extended registers (of which Mach supports only
// the xmm values) then we don't have values for the other set. This is a problem since Mach only
// supports setting both groups as a single unit. So in this case we'll need to fetch the current
_ASSERTE(StateCountGet == StateCount);
}
- if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT)
+ if (lpContext->ContextFlags & CONTEXT_FLOATING_POINT & CONTEXT_AREA_MASK)
{
#ifdef _X86_
*(DWORD*)&State.fpu_fcw = lpContext->FloatSave.ControlWord;
}
#ifdef _X86_
- if (lpContext->ContextFlags & CONTEXT_EXTENDED_REGISTERS)
+ if (lpContext->ContextFlags & CONTEXT_EXTENDED_REGISTERS & CONTEXT_AREA_MASK)
{
// The only extended register information that Mach will tell us about are the xmm register
// values. Both Windows and Mach store the registers in a packed layout (each of the 8 registers
}
#endif // _X86_
+#if defined(_AMD64_) && defined(XSTATE_SUPPORTED)
+ if (lpContext->ContextFlags & CONTEXT_XSTATE & CONTEXT_AREA_MASK)
+ {
+ memcpy(&State.__fpu_ymmh0, lpContext->VectorRegister, 16 * 16);
+ }
+#endif
+
MachRet = thread_set_state(Port,
StateFlavor,
(thread_state_t)&State,