Commit 847db3c1 authored by Alexandre Julliard's avatar Alexandre Julliard

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

parent 77f5e296
......@@ -115,6 +115,11 @@ SYSTEM_DLL_INIT_BLOCK *pLdrSystemDllInitBlock = NULL;
static NTSTATUS (CDECL *p__wine_set_unix_funcs)( int version, const struct unix_funcs *funcs );
extern SYSTEM_SERVICE_TABLE __wine_syscall_table DECLSPEC_HIDDEN;
SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[4];
#ifdef __GNUC__
static void fatal_error( const char *err, ... ) __attribute__((noreturn, format(printf,1,2)));
#endif
......@@ -1939,6 +1944,7 @@ static void start_main_thread(void)
NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 );
load_ntdll();
if (main_image_info.Machine != current_machine) load_wow64_ntdll( main_image_info.Machine );
KeServiceDescriptorTable[0] = __wine_syscall_table;
status = p__wine_set_unix_funcs( NTDLL_UNIXLIB_VERSION, &unix_funcs );
if (status == STATUS_REVISION_MISMATCH)
{
......
......@@ -192,10 +192,12 @@ struct syscall_frame
DWORD restore_flags; /* 044 */
DWORD fpscr; /* 048 */
struct syscall_frame *prev_frame; /* 04c */
ULONGLONG d[32]; /* 050 */
SYSTEM_SERVICE_TABLE *syscall_table; /* 050 */
DWORD align[3]; /* 054 */
ULONGLONG d[32]; /* 060 */
};
C_ASSERT( sizeof( struct syscall_frame ) == 0x150);
C_ASSERT( sizeof( struct syscall_frame ) == 0x160);
struct arm_thread_data
{
......@@ -607,6 +609,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void
callback_frame.frame.sp = (ULONG_PTR)args_data;
callback_frame.frame.pc = (ULONG_PTR)pKiUserCallbackDispatcher;
callback_frame.frame.restore_flags = CONTEXT_INTEGER;
callback_frame.frame.syscall_table = frame->syscall_table;
callback_frame.frame.prev_frame = frame;
arm_thread_data()->syscall_frame = &callback_frame.frame;
......@@ -993,6 +996,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
frame->r0 = (DWORD)ctx;
frame->prev_frame = NULL;
frame->restore_flags |= CONTEXT_INTEGER;
frame->syscall_table = KeServiceDescriptorTable;
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
__wine_syscall_dispatcher_return( frame, 0 );
......@@ -1009,7 +1013,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread,
/* set syscall frame */
"ldr r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
"cbnz r6, 1f\n\t"
"sub r6, sp, #0x150\n\t" /* sizeof(struct syscall_frame) */
"sub r6, sp, #0x160\n\t" /* sizeof(struct syscall_frame) */
"str r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
"1:\tmov sp, r6\n\t"
"bl " __ASM_NAME("call_init_thunk") )
......
......@@ -142,12 +142,14 @@ struct syscall_frame
ULONG cpsr; /* 108 */
ULONG restore_flags; /* 10c */
struct syscall_frame *prev_frame; /* 110 */
ULONG fpcr; /* 118 */
ULONG fpsr; /* 11c */
NEON128 v[32]; /* 120 */
SYSTEM_SERVICE_TABLE *syscall_table; /* 118 */
ULONG64 align; /* 120 */
ULONG fpcr; /* 128 */
ULONG fpsr; /* 12c */
NEON128 v[32]; /* 130 */
};
C_ASSERT( sizeof( struct syscall_frame ) == 0x320 );
C_ASSERT( sizeof( struct syscall_frame ) == 0x330 );
struct arm64_thread_data
{
......@@ -756,6 +758,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void
callback_frame.frame.sp = (ULONG_PTR)args_data;
callback_frame.frame.pc = (ULONG_PTR)pKiUserCallbackDispatcher;
callback_frame.frame.restore_flags = CONTEXT_INTEGER;
callback_frame.frame.syscall_table = frame->syscall_table;
callback_frame.frame.prev_frame = frame;
arm64_thread_data()->syscall_frame = &callback_frame.frame;
......@@ -1186,6 +1189,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
frame->x[18] = (ULONG64)teb;
frame->prev_frame = NULL;
frame->restore_flags |= CONTEXT_INTEGER;
frame->syscall_table = KeServiceDescriptorTable;
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
__wine_syscall_dispatcher_return( frame, 0 );
......@@ -1203,7 +1207,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread,
/* set syscall frame */
"ldr x8, [x3, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */
"cbnz x8, 1f\n\t"
"sub x8, sp, #0x320\n\t" /* sizeof(struct syscall_frame) */
"sub x8, sp, #0x330\n\t" /* sizeof(struct syscall_frame) */
"str x8, [x3, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */
"1:\tmov sp, x8\n\t"
"bl " __ASM_NAME("call_init_thunk") )
......
......@@ -463,26 +463,27 @@ enum i386_trap_code
struct syscall_frame
{
DWORD restore_flags; /* 000 */
DWORD eflags; /* 004 */
DWORD eip; /* 008 */
DWORD esp; /* 00c */
WORD cs; /* 010 */
WORD ss; /* 012 */
WORD ds; /* 014 */
WORD es; /* 016 */
WORD fs; /* 018 */
WORD gs; /* 01a */
DWORD eax; /* 01c */
DWORD ebx; /* 020 */
DWORD ecx; /* 024 */
DWORD edx; /* 028 */
DWORD edi; /* 02c */
DWORD esi; /* 030 */
DWORD ebp; /* 034 */
DWORD syscall_flags; /* 038 */
struct syscall_frame *prev_frame; /* 03c */
union /* 040 */
WORD syscall_flags; /* 000 */
WORD restore_flags; /* 002 */
DWORD eflags; /* 004 */
DWORD eip; /* 008 */
DWORD esp; /* 00c */
WORD cs; /* 010 */
WORD ss; /* 012 */
WORD ds; /* 014 */
WORD es; /* 016 */
WORD fs; /* 018 */
WORD gs; /* 01a */
DWORD eax; /* 01c */
DWORD ebx; /* 020 */
DWORD ecx; /* 024 */
DWORD edx; /* 028 */
DWORD edi; /* 02c */
DWORD esi; /* 030 */
DWORD ebp; /* 034 */
SYSTEM_SERVICE_TABLE *syscall_table; /* 038 */
struct syscall_frame *prev_frame; /* 03c */
union /* 040 */
{
XSAVE_FORMAT xsave;
FLOATING_SAVE_AREA fsave;
......@@ -490,7 +491,7 @@ struct syscall_frame
/* Leave space for the whole set of YMM registers. They're not used in
* 32-bit mode, but some processors fault if they're not in writable memory.
*/
DECLSPEC_ALIGN(64) XSTATE xstate; /* 240 */
DECLSPEC_ALIGN(64) XSTATE xstate; /* 240 */
};
C_ASSERT( sizeof(struct syscall_frame) == 0x380 );
......@@ -873,7 +874,7 @@ NTSTATUS signal_set_full_context( CONTEXT *context )
NTSTATUS status = NtSetContextThread( GetCurrentThread(), context );
if (!status && (context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
x86_thread_data()->syscall_frame->restore_flags |= CONTEXT_INTEGER;
x86_thread_data()->syscall_frame->restore_flags |= LOWORD(CONTEXT_INTEGER);
return status;
}
......@@ -1617,6 +1618,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void
callback_frame.frame.eip = (ULONG_PTR)pKiUserCallbackDispatcher;
callback_frame.frame.eflags = 0x202;
callback_frame.frame.syscall_flags = frame->syscall_flags;
callback_frame.frame.syscall_table = frame->syscall_table;
callback_frame.frame.prev_frame = frame;
x86_thread_data()->syscall_frame = &callback_frame.frame;
......@@ -1779,7 +1781,7 @@ static BOOL handle_syscall_trap( ucontext_t *sigcontext )
frame->eip = *(ULONG *)ESP_sig( sigcontext );
frame->eflags = EFL_sig(sigcontext);
frame->restore_flags = CONTEXT_CONTROL;
frame->restore_flags = LOWORD(CONTEXT_CONTROL);
EIP_sig( sigcontext ) = (ULONG)__wine_syscall_dispatcher_prolog_end;
ECX_sig( sigcontext ) = (ULONG)frame;
......@@ -2420,7 +2422,8 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
frame->eip = (DWORD)pLdrInitializeThunk;
frame->prev_frame = NULL;
frame->syscall_flags = syscall_flags;
frame->restore_flags |= CONTEXT_INTEGER;
frame->syscall_table = KeServiceDescriptorTable;
frame->restore_flags |= LOWORD(CONTEXT_INTEGER);
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
__wine_syscall_dispatcher_return( frame, 0 );
......
......@@ -327,8 +327,9 @@ struct syscall_frame
DWORD restore_flags; /* 0094 */
ULONG64 rbp; /* 0098 */
struct syscall_frame *prev_frame; /* 00a0 */
DWORD syscall_flags; /* 00a8 */
DWORD align[5]; /* 00ac */
SYSTEM_SERVICE_TABLE *syscall_table; /* 00a8 */
DWORD syscall_flags; /* 00b0 */
DWORD align[3]; /* 00b4 */
XMM_SAVE_AREA32 xsave; /* 00c0 */
DECLSPEC_ALIGN(64) XSTATE xstate; /* 02c0 */
};
......@@ -2318,6 +2319,7 @@ NTSTATUS WINAPI KeUserModeCallback( ULONG id, const void *args, ULONG len, void
callback_frame.frame.restore_flags = CONTEXT_CONTROL | CONTEXT_INTEGER;
callback_frame.frame.prev_frame = frame;
callback_frame.frame.syscall_flags = frame->syscall_flags;
callback_frame.frame.syscall_table = frame->syscall_table;
amd64_thread_data()->syscall_frame = &callback_frame.frame;
__wine_syscall_dispatcher_return( &callback_frame.frame, 0 );
......@@ -3043,6 +3045,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
frame->prev_frame = NULL;
frame->restore_flags |= CONTEXT_INTEGER;
frame->syscall_flags = syscall_flags;
frame->syscall_table = KeServiceDescriptorTable;
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
__wine_syscall_dispatcher_return( frame, 0 );
......
......@@ -26,6 +26,8 @@ typedef UINT64 unixlib_handle_t;
extern NTSTATUS WINAPI __wine_unix_call( unixlib_handle_t handle, unsigned int code, void *args );
extern SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[4];
/* some useful helpers from ntdll */
extern DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD dstlen );
extern int ntdll_wcstoumbs( const WCHAR *src, DWORD srclen, char *dst, DWORD dstlen, BOOL strict );
......
......@@ -3761,6 +3761,14 @@ typedef struct
} SYSTEM_DLL_INIT_BLOCK;
#endif
typedef struct
{
ULONG_PTR *ServiceTable;
ULONG_PTR *CounterTable;
ULONG_PTR ServiceLimit;
BYTE *ArgumentTable;
} SYSTEM_SERVICE_TABLE;
/***********************************************************************
* Function declarations
*/
......
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