Jacek Caban : ntdll: Use syscall dispatcher to restore context in NtSetContextThread.

Alexandre Julliard julliard at winehq.org
Tue Mar 2 15:35:59 CST 2021


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Mar  2 18:52:44 2021 +0100

ntdll: Use syscall dispatcher to restore context in NtSetContextThread.

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

---

 dlls/ntdll/tests/exception.c  |  2 +-
 dlls/ntdll/unix/signal_i386.c | 21 ++++++++++++++++-----
 tools/winebuild/import.c      | 10 +++++++++-
 3 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 397de7dad98..8418f925565 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -7762,7 +7762,7 @@ static void test_extended_context(void)
     memset(&xs->YmmContext, 0xcc, sizeof(xs->YmmContext));
     bret = GetThreadContext(thread, context);
     ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
-    ok(xs->Mask == (sizeof(void *) == 4 ? 4 : 0) || broken(sizeof(void *) == 4 && !xs->Mask) /* Win7u */,
+    ok(!xs->Mask || (sizeof(void *) == 4 && xs->Mask == 4),
             "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask));
     for (i = 0; i < 16 * 4; ++i)
         ok(((ULONG *)&xs->YmmContext)[i] == (xs->Mask ? (i < 8 * 4 ? 0 : 0x48484848) : 0xcccccccc),
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index fd3c42c571c..0153f772b6d 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -1258,8 +1258,6 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
             xsave->xstate.mask &= ~XSTATE_MASK_GSSE;
     }
 
-    if (!(flags & CONTEXT_INTEGER)) frame->eax = STATUS_SUCCESS;
-    signal_restore_full_cpu_context();
     return STATUS_SUCCESS;
 }
 
@@ -2176,9 +2174,22 @@ static void usr1_handler( int signal, siginfo_t *siginfo, void *sigcontext )
     struct xcontext xcontext;
 
     init_handler( sigcontext );
-    save_context( &xcontext, sigcontext );
-    wait_suspend( &xcontext.c );
-    restore_context( &xcontext, sigcontext );
+    if (x86_thread_data()->syscall_frame)
+    {
+        DECLSPEC_ALIGN(64) XSTATE xs;
+        xcontext.c.ContextFlags = CONTEXT_FULL;
+        context_init_xstate( &xcontext.c, &xs );
+
+        NtGetContextThread( GetCurrentThread(), &xcontext.c );
+        wait_suspend( &xcontext.c );
+        NtSetContextThread( GetCurrentThread(), &xcontext.c );
+    }
+    else
+    {
+        save_context( &xcontext, sigcontext );
+        wait_suspend( &xcontext.c );
+        restore_context( &xcontext, sigcontext );
+    }
 }
 
 
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 2905f1a4100..073ad9b10cf 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1509,10 +1509,18 @@ static void output_syscall_dispatcher( int count, const char *variant )
             output( "\tfrstor (%%ebx)\n" );
             output( "\tfwait\n" );
         }
-        else
+        else if(!strcmp( variant, "_fxsave" ))
         {
             output( "\tfxrstor (%%ebx)\n" );
         }
+        else
+        {
+            output( "\tmovl %%eax,%%ecx\n" );
+            output( "\tmovl $7,%%eax\n" );
+            output( "\txorl %%edx,%%edx\n" );
+            output( "\txrstor (%%ebx)\n" );
+            output( "\tmovl %%ecx,%%eax\n" );
+        }
         output( "\tleal -0x30(%%ebp),%%ebx\n" );
         output_cfi( ".cfi_def_cfa_register %%ebx" );
         output_cfi( ".cfi_adjust_cfa_offset 0x30\n" );




More information about the wine-cvs mailing list