Jacek Caban : ntdll: Use syscall dispatcher for restoring context in x86_64 NtSetContextThread implementation.
Alexandre Julliard
julliard at winehq.org
Mon Feb 22 15:43:22 CST 2021
Module: wine
Branch: master
Commit: 437bef6ac15dea892904769b46a4cafb80ed9eb4
URL: https://source.winehq.org/git/wine.git/?a=commit;h=437bef6ac15dea892904769b46a4cafb80ed9eb4
Author: Jacek Caban <jacek at codeweavers.com>
Date: Mon Feb 22 18:04:16 2021 +0100
ntdll: Use syscall dispatcher for restoring context in x86_64 NtSetContextThread implementation.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/server.c | 5 ++++-
dlls/ntdll/unix/signal_arm.c | 10 ++++++++++
dlls/ntdll/unix/signal_arm64.c | 10 ++++++++++
dlls/ntdll/unix/signal_i386.c | 11 +++++++++++
dlls/ntdll/unix/signal_x86_64.c | 29 ++++++++++++++++++++++-------
dlls/ntdll/unix/unix_private.h | 1 +
tools/winebuild/import.c | 13 ++++++++++++-
7 files changed, 70 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 6af8effe9e1..4f149c0f644 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -726,7 +726,10 @@ NTSTATUS WINAPI NtContinue( CONTEXT *context, BOOLEAN alertable )
status = server_select( NULL, 0, SELECT_INTERRUPTIBLE | SELECT_ALERTABLE, 0, NULL, NULL, &apc );
if (status == STATUS_USER_APC) invoke_apc( context, &apc );
}
- return NtSetContextThread( GetCurrentThread(), context );
+ status = NtSetContextThread( GetCurrentThread(), context );
+ if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+ signal_restore_full_cpu_context();
+ return status;
}
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index 2de58925c84..cb4695939f5 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -332,6 +332,16 @@ __ASM_GLOBAL_FUNC( set_cpu_context,
"pop {pc}" )
+/***********************************************************************
+ * signal_restore_full_cpu_context
+ *
+ * Restore full context from syscall frame
+ */
+void signal_restore_full_cpu_context(void)
+{
+}
+
+
/***********************************************************************
* get_server_context_flags
*
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index 9a36746f5bc..80cc59d0743 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -406,6 +406,16 @@ static void restore_fpu( CONTEXT *context, ucontext_t *sigcontext )
}
+/***********************************************************************
+ * signal_restore_full_cpu_context
+ *
+ * Restore full context from syscall frame
+ */
+void signal_restore_full_cpu_context(void)
+{
+}
+
+
/***********************************************************************
* get_server_context_flags
*
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 09529a1ea96..4d03153bd1f 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -807,6 +807,17 @@ static inline void restore_xstate( const CONTEXT *context )
__asm__ volatile( "xrstor %0" : : "m"(*xrstor_base), "a" (4), "d" (0) );
}
+
+/***********************************************************************
+ * signal_restore_full_cpu_context
+ *
+ * Restore full context from syscall frame
+ */
+void signal_restore_full_cpu_context(void)
+{
+}
+
+
/***********************************************************************
* fpux_to_fpu
*
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index b5040852cbe..88e5eace003 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -1591,7 +1591,12 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
"leaq 0x70(%rsp),%rsp\n\t"
"iretq" )
-static void signal_restore_full_cpu_context(void)
+/***********************************************************************
+ * signal_restore_full_cpu_context
+ *
+ * Restore full context from syscall frame
+ */
+void signal_restore_full_cpu_context(void)
{
struct syscall_xsave *xsave = get_syscall_xsave( get_syscall_frame() );
SYSTEM_CPU_INFORMATION cpu_info;
@@ -1863,9 +1868,6 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
else if (xs->CompactionMask & XSTATE_MASK_GSSE)
xsave->xstate.Mask &= ~XSTATE_MASK_GSSE;
}
-
- if (!(flags & CONTEXT_INTEGER)) frame->rax = STATUS_SUCCESS;
- signal_restore_full_cpu_context();
return STATUS_SUCCESS;
}
@@ -2614,11 +2616,24 @@ static void quit_handler( int signal, siginfo_t *siginfo, void *ucontext )
*/
static void usr1_handler( int signal, siginfo_t *siginfo, void *ucontext )
{
+ struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
struct xcontext context;
+ if (frame)
+ {
+ DECLSPEC_ALIGN(64) XSTATE xs;
+ context.c.ContextFlags = CONTEXT_FULL;
+ context_init_xstate( &context.c, &xs );
- save_context( &context, ucontext );
- wait_suspend( &context.c );
- restore_context( &context, ucontext );
+ NtGetContextThread( GetCurrentThread(), &context.c );
+ wait_suspend( &context.c );
+ NtSetContextThread( GetCurrentThread(), &context.c );
+ }
+ else
+ {
+ save_context( &context, ucontext );
+ wait_suspend( &context.c );
+ restore_context( &context, ucontext );
+ }
}
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 65f526d0f7d..c98b11701e4 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -214,6 +214,7 @@ extern void DECLSPEC_NORETURN signal_start_thread( PRTL_THREAD_START_ROUTINE ent
extern void DECLSPEC_NORETURN signal_exit_thread( int status, void (*func)(int) ) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN exec_process( NTSTATUS status ) DECLSPEC_HIDDEN;
extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN;
+extern void signal_restore_full_cpu_context(void) DECLSPEC_HIDDEN;
extern void fill_vm_counters( VM_COUNTERS_EX *pvmi, int unix_pid ) DECLSPEC_HIDDEN;
extern NTSTATUS cdrom_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 0fddbaf6134..a01694ffb9c 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1559,7 +1559,18 @@ static void output_syscall_dispatcher( int count, const char *variant )
output( "\tcallq *(%%r10,%%r11,8)\n" );
output( "2:\tmovq %%gs:0x30,%%rcx\n" );
output( "\tmovq $0,0x328(%%rcx)\n" );
- output( "\tfxrstor64 (%%r12)\n" );
+ if (!*variant)
+ {
+ output( "\tfxrstor64 (%%r12)\n" );
+ }
+ else
+ {
+ output( "\tmovq %%rax,%%r11\n" );
+ output( "\tmovl $7,%%eax\n" );
+ output( "\txorq %%rdx,%%rdx\n" );
+ output( "\txrstor64 (%%r12)\n" );
+ output( "\tmovq %%r11,%%rax\n" );
+ }
output( "\tmovq -0x30(%%rbp),%%r15\n" );
output( "\tmovq -0x38(%%rbp),%%r14\n" );
output( "\tmovq -0x40(%%rbp),%%r13\n" );
More information about the wine-cvs
mailing list