Alexandre Julliard : ntdll: Store the syscall flags in the syscall frame on all platforms.

Alexandre Julliard julliard at winehq.org
Thu Aug 26 15:22:30 CDT 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Aug 25 13:31:49 2021 +0200

ntdll: Store the syscall flags in the syscall frame on all platforms.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/signal_i386.c   | 12 +++++++-----
 dlls/ntdll/unix/signal_x86_64.c | 15 ++++++++++-----
 dlls/ntdll/unix/unix_private.h  |  1 -
 tools/winebuild/import.c        |  7 ++-----
 4 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 1cd6ef7bb39..04645a9c4a6 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -519,6 +519,8 @@ C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct x86_thread_data, sysca
 #define SYSCALL_HAVE_XSAVEC   2
 #define SYSCALL_HAVE_FXSAVE   4
 
+static unsigned int syscall_flags;
+
 static inline struct x86_thread_data *x86_thread_data(void)
 {
     return (struct x86_thread_data *)ntdll_get_thread_data()->cpu_data;
@@ -1614,7 +1616,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void
         callback_frame.frame.esp           = (ULONG_PTR)stack;
         callback_frame.frame.eip           = (ULONG_PTR)pKiUserCallbackDispatcher;
         callback_frame.frame.eflags        = 0x202;
-        callback_frame.frame.syscall_flags = __wine_syscall_flags;
+        callback_frame.frame.syscall_flags = frame->syscall_flags;
         callback_frame.frame.prev_frame    = frame;
         x86_thread_data()->syscall_frame = &callback_frame.frame;
 
@@ -2340,9 +2342,9 @@ void signal_init_process(void)
 
     x86_thread_data()->syscall_frame = (struct syscall_frame *)kernel_stack - 1;
 
-    if (cpu_info.ProcessorFeatureBits & CPU_FEATURE_FXSR) __wine_syscall_flags |= SYSCALL_HAVE_FXSAVE;
-    if (cpu_info.ProcessorFeatureBits & CPU_FEATURE_XSAVE) __wine_syscall_flags |= SYSCALL_HAVE_XSAVE;
-    if (xstate_compaction_enabled) __wine_syscall_flags |= SYSCALL_HAVE_XSAVEC;
+    if (cpu_info.ProcessorFeatureBits & CPU_FEATURE_FXSR) syscall_flags |= SYSCALL_HAVE_FXSAVE;
+    if (cpu_info.ProcessorFeatureBits & CPU_FEATURE_XSAVE) syscall_flags |= SYSCALL_HAVE_XSAVE;
+    if (xstate_compaction_enabled) syscall_flags |= SYSCALL_HAVE_XSAVEC;
 
     sig_act.sa_mask = server_block_set;
     sig_act.sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK;
@@ -2417,7 +2419,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
     frame->esp = (DWORD)stack;
     frame->eip = (DWORD)pLdrInitializeThunk;
     frame->prev_frame    = NULL;
-    frame->syscall_flags = __wine_syscall_flags;
+    frame->syscall_flags = syscall_flags;
     frame->restore_flags |= CONTEXT_INTEGER;
 
     pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index e6971b4629a..cc2238f62c4 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -285,6 +285,8 @@ C_ASSERT( sizeof(struct stack_layout) == 0x590 ); /* Should match the size in ca
 #define SYSCALL_HAVE_PTHREAD_TEB 4
 #define SYSCALL_HAVE_WRFSGSBASE  8
 
+static unsigned int syscall_flags;
+
 /* stack layout when calling an user apc function.
  * FIXME: match Windows ABI. */
 struct apc_stack_layout
@@ -325,7 +327,8 @@ struct syscall_frame
     DWORD                 restore_flags; /* 0094 */
     ULONG64               rbp;           /* 0098 */
     struct syscall_frame *prev_frame;    /* 00a0 */
-    ULONG64               align[3];      /* 00a8 */
+    DWORD                 syscall_flags; /* 00a8 */
+    DWORD                 align[5];      /* 00ac */
     XMM_SAVE_AREA32       xsave;         /* 00c0 */
     DECLSPEC_ALIGN(64) XSTATE xstate;    /* 02c0 */
 };
@@ -2314,6 +2317,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void
         callback_frame.frame.eflags        = 0x200;
         callback_frame.frame.restore_flags = CONTEXT_CONTROL | CONTEXT_INTEGER;
         callback_frame.frame.prev_frame    = frame;
+        callback_frame.frame.syscall_flags = frame->syscall_flags;
         amd64_thread_data()->syscall_frame = &callback_frame.frame;
 
         __wine_syscall_dispatcher_return( &callback_frame.frame, 0 );
@@ -2935,8 +2939,8 @@ void signal_init_process(void)
     anon_mmap_fixed( ptr, page_size, PROT_READ | PROT_WRITE, 0 );
     *(void **)ptr = __wine_syscall_dispatcher;
 
-    if (cpu_info.ProcessorFeatureBits & CPU_FEATURE_XSAVE) __wine_syscall_flags |= SYSCALL_HAVE_XSAVE;
-    if (xstate_compaction_enabled) __wine_syscall_flags |= SYSCALL_HAVE_XSAVEC;
+    if (cpu_info.ProcessorFeatureBits & CPU_FEATURE_XSAVE) syscall_flags |= SYSCALL_HAVE_XSAVE;
+    if (xstate_compaction_enabled) syscall_flags |= SYSCALL_HAVE_XSAVEC;
 
 #ifdef __linux__
     if (NtCurrentTeb()->WowTebOffset)
@@ -2948,8 +2952,8 @@ void signal_init_process(void)
         if ((sel = alloc_fs_sel( -1, teb32 )) != -1)
         {
             fs32_sel = (sel << 3) | 3;
-            __wine_syscall_flags |= SYSCALL_HAVE_PTHREAD_TEB;
-            if (getauxval( AT_HWCAP2 ) & 2) __wine_syscall_flags |= SYSCALL_HAVE_WRFSGSBASE;
+            syscall_flags |= SYSCALL_HAVE_PTHREAD_TEB;
+            if (getauxval( AT_HWCAP2 ) & 2) syscall_flags |= SYSCALL_HAVE_WRFSGSBASE;
         }
         else ERR_(seh)( "failed to allocate %%fs selector\n" );
     }
@@ -3038,6 +3042,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
     frame->rcx = (ULONG64)ctx;
     frame->prev_frame = NULL;
     frame->restore_flags |= CONTEXT_INTEGER;
+    frame->syscall_flags = syscall_flags;
 
     pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
     __wine_syscall_dispatcher_return( frame, 0 );
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 961ba42b232..731b12d332c 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -252,7 +252,6 @@ extern void DECLSPEC_NORETURN signal_start_thread( PRTL_THREAD_START_ROUTINE ent
 extern void DECLSPEC_NORETURN signal_exit_thread( int status, void (*func)(int), TEB *teb ) DECLSPEC_HIDDEN;
 extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN;
 extern void WINAPI DECLSPEC_NORETURN __wine_syscall_dispatcher_return( void *frame, ULONG_PTR retval ) DECLSPEC_HIDDEN;
-extern unsigned int __wine_syscall_flags DECLSPEC_HIDDEN;
 extern NTSTATUS signal_set_full_context( CONTEXT *context ) DECLSPEC_HIDDEN;
 extern NTSTATUS get_thread_wow64_context( HANDLE handle, void *ctx, ULONG size ) DECLSPEC_HIDDEN;
 extern NTSTATUS set_thread_wow64_context( HANDLE handle, const void *ctx, ULONG size ) DECLSPEC_HIDDEN;
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 5f1946e0c4f..4b1e0b18b46 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1576,7 +1576,7 @@ static void output_syscall_dispatcher(void)
         /* Legends of Runeterra hooks the first system call return instruction, and
          * depends on us returning to it. Adjust the return address accordingly. */
         output( "\tsubq $0xb,0x70(%%rcx)\n" );
-        output( "\tmovl %s(%%rip),%%r14d\n", asm_name("__wine_syscall_flags") );
+        output( "\tmovl 0xa8(%%rcx),%%r14d\n" );  /* frame->syscall_flags */
         output( "\ttestl $3,%%r14d\n" );  /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
         output( "\tjz 2f\n" );
         output( "\tmovl $7,%%eax\n" );
@@ -1685,7 +1685,7 @@ static void output_syscall_dispatcher(void)
         output( "5:\tmovl $0x%x,%%edx\n", invalid_param );
         output( "\tmovq %%rsp,%%rcx\n" );
         output( "%s\n", asm_globl("__wine_syscall_dispatcher_return") );
-        output( "\tmovl %s(%%rip),%%r14d\n", asm_name("__wine_syscall_flags") );
+        output( "\tmovl 0xa8(%%rcx),%%r14d\n" );  /* frame->syscall_flags */
         output( "\tmovq %%rdx,%%rax\n" );
         output( "\tjmp 2b\n" );
         break;
@@ -1932,9 +1932,6 @@ void output_syscalls( DLLSPEC *spec )
         output( ".Lsyscall_args:\n" );
         for (i = 0; i < count; i++)
             output( "\t.byte %u\n", get_args_size( syscalls[i] ));
-        output( "\t.align %d\n", get_alignment(4) );
-        output( "%s\n", asm_globl("__wine_syscall_flags") );
-        output( "\t.long 0\n" );
         return;
     }
 




More information about the wine-cvs mailing list