Jacek Caban : ntdll: Use syscall frame for FPU and XMM contexts in NtGetContextThread.

Alexandre Julliard julliard at winehq.org
Mon Mar 1 15:54:05 CST 2021


Module: wine
Branch: master
Commit: e5d671bee5dc78235c5c9942b4cb43853d0f045c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e5d671bee5dc78235c5c9942b4cb43853d0f045c

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Mar  1 16:51:48 2021 +0100

ntdll: Use syscall frame for FPU and XMM contexts in NtGetContextThread.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/signal_i386.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 7e383bdcaba..cec2a89c7bf 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -530,6 +530,11 @@ void set_syscall_frame(void *frame)
     x86_thread_data()->syscall_frame = frame;
 }
 
+static struct syscall_xsave *get_syscall_xsave( struct syscall_frame *frame )
+{
+    return (struct syscall_xsave *)((ULONG_PTR)((struct syscall_xsave *)frame - 1) & ~63);
+}
+
 static inline WORD get_cs(void) { WORD res; __asm__( "movw %%cs,%0" : "=r" (res) ); return res; }
 static inline WORD get_ds(void) { WORD res; __asm__( "movw %%ds,%0" : "=r" (res) ); return res; }
 static inline WORD get_fs(void) { WORD res; __asm__( "movw %%fs,%0" : "=r" (res) ); return res; }
@@ -701,23 +706,6 @@ static inline void save_fpu( CONTEXT *context )
 }
 
 
-/***********************************************************************
- *           save_fpux
- *
- * Save the thread FPU extended context.
- */
-static inline void save_fpux( CONTEXT *context )
-{
-    /* we have to enforce alignment by hand */
-    char buffer[sizeof(XSAVE_FORMAT) + 16];
-    XSAVE_FORMAT *state = (XSAVE_FORMAT *)(((ULONG_PTR)buffer + 15) & ~15);
-
-    context->ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
-    __asm__ __volatile__( "fxsave %0" : "=m" (*state) );
-    memcpy( context->ExtendedRegisters, state, sizeof(*state) );
-}
-
-
 /***********************************************************************
  *           save_xstate
  *
@@ -1328,6 +1316,7 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
 
     if (self)
     {
+        struct syscall_xsave *xsave = get_syscall_xsave( frame );
         if (needed_flags & CONTEXT_INTEGER)
         {
             context->Eax = frame->eax;
@@ -1356,8 +1345,19 @@ NTSTATUS WINAPI NtGetContextThread( HANDLE handle, CONTEXT *context )
             context->SegGs = frame->gs;
             context->ContextFlags |= CONTEXT_SEGMENTS;
         }
-        if (needed_flags & CONTEXT_FLOATING_POINT) save_fpu( context );
-        if (needed_flags & CONTEXT_EXTENDED_REGISTERS) save_fpux( context );
+        if (needed_flags & CONTEXT_FLOATING_POINT)
+        {
+            if (cpu_info.FeatureSet & CPU_FEATURE_FXSR)
+                fpux_to_fpu( &context->FloatSave, &xsave->u.xsave );
+            else
+                context->FloatSave = xsave->u.fsave;
+            context->ContextFlags |= CONTEXT_FLOATING_POINT;
+        }
+        if (needed_flags & CONTEXT_EXTENDED_REGISTERS)
+        {
+            memcpy( context->ExtendedRegisters, &xsave->u.xsave, sizeof(xsave->u.xsave) );
+            context->ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
+        }
         /* update the cached version of the debug registers */
         if (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))
         {




More information about the wine-cvs mailing list