Module: wine Branch: master Commit: af74bd31229e0f065448253b248ec0cb3b51af26 URL: https://source.winehq.org/git/wine.git/?a=commit;h=af74bd31229e0f065448253b2...
Author: Jacek Caban jacek@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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" );