Commit 77f5e296 authored by Alexandre Julliard's avatar Alexandre Julliard

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

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