From: Jacek Caban Subject: [PATCH 3/3] ntdll: Fix compacted legacy xsave area handling. Message-Id: <422ec75a-51dc-c7b5-0406-23297b481a0c@codeweavers.com> Date: Tue, 23 Feb 2021 17:55:15 +0100 Signed-off-by: Jacek Caban --- dlls/ntdll/unix/signal_x86_64.c | 37 +++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index baeb472d126..7d760e338dc 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1846,6 +1846,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) if (flags & CONTEXT_FLOATING_POINT) { xsave->xsave = context->u.FltSave; + xsave->xstate.Mask |= XSTATE_MASK_LEGACY; } if ((cpu_info.FeatureSet & CPU_FEATURE_AVX) && (xs = xstate_from_context( context ))) { @@ -1939,8 +1940,40 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context ) } if (needed_flags & CONTEXT_FLOATING_POINT) { - context->u.FltSave = get_syscall_xsave(frame)->xsave; - context->MxCsr = context->u.FltSave.MxCsr; + struct syscall_xsave *xsave = get_syscall_xsave( frame ); + + if (!(cpu_info.FeatureSet & CPU_FEATURE_XSAVEC) || + (xsave->xstate.Mask & XSTATE_MASK_LEGACY_FLOATING_POINT)) + { + memcpy( &context->u.FltSave, &xsave->xsave, FIELD_OFFSET( XSAVE_FORMAT, MxCsr )); + memcpy( context->u.FltSave.FloatRegisters, xsave->xsave.FloatRegisters, + sizeof( context->u.FltSave.FloatRegisters )); + } + else + { + memset( &context->u.FltSave, 0, FIELD_OFFSET( XSAVE_FORMAT, MxCsr )); + memset( context->u.FltSave.FloatRegisters, 0, + sizeof( context->u.FltSave.FloatRegisters )); + context->u.FltSave.ControlWord = 0x37f; + } + + if (!(cpu_info.FeatureSet & CPU_FEATURE_XSAVEC) || + (xsave->xstate.Mask & XSTATE_MASK_LEGACY_SSE)) + { + memcpy( context->u.FltSave.XmmRegisters, xsave->xsave.XmmRegisters, + sizeof( context->u.FltSave.XmmRegisters )); + context->u.FltSave.MxCsr = xsave->xsave.MxCsr; + context->u.FltSave.MxCsr_Mask = xsave->xsave.MxCsr_Mask; + } + else + { + memset( context->u.FltSave.XmmRegisters, 0, + sizeof( context->u.FltSave.XmmRegisters )); + context->u.FltSave.MxCsr = 0x1f80; + context->u.FltSave.MxCsr_Mask = 0x2ffff; + } + + context->MxCsr = context->u.FltSave.MxCsr; context->ContextFlags |= CONTEXT_FLOATING_POINT; } /* update the cached version of the debug registers */