From af74bd31229e0f065448253b248ec0cb3b51af26 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 2 Mar 2021 18:52:44 +0100 Subject: [PATCH] ntdll: Use syscall dispatcher to restore context in NtSetContextThread. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- 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" );