From 7ae1c396acd3649b2482f20992cc2c65159fbd05 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 30 Aug 2021 12:27:08 +0200 Subject: [PATCH] ntdll: Store the syscall argument table on the PE side. Signed-off-by: Alexandre Julliard --- dlls/ntdll/unix/loader.c | 21 +++++++++++++++++++-- tools/winebuild/import.c | 7 +++---- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 53df7c87878..266d53f0eca 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -118,6 +118,8 @@ static void *p__wine_syscall_dispatcher; extern SYSTEM_SERVICE_TABLE __wine_syscall_table DECLSPEC_HIDDEN; +static BYTE syscall_args[4096]; + SYSTEM_SERVICE_TABLE KeServiceDescriptorTable[4]; @@ -1148,8 +1150,21 @@ static NTSTATUS CDECL init_unix_lib( void *module, DWORD reason, const void *ptr */ NTSTATUS ntdll_init_syscalls( ULONG id, SYSTEM_SERVICE_TABLE *table, void **dispatcher ) { + struct syscall_info + { + void *dispatcher; + USHORT limit; + BYTE args[1]; + } *info = (struct syscall_info *)dispatcher; + if (id > 3) return STATUS_INVALID_PARAMETER; - *dispatcher = __wine_syscall_dispatcher; + if (info->limit != table->ServiceLimit) + { + ERR( "syscall count mismatch %u / %lu\n", info->limit, table->ServiceLimit ); + NtTerminateProcess( GetCurrentProcess(), STATUS_INVALID_PARAMETER ); + } + info->dispatcher = __wine_syscall_dispatcher; + memcpy( table->ArgumentTable, info->args, table->ServiceLimit ); KeServiceDescriptorTable[id] = *table; return STATUS_SUCCESS; } @@ -1932,6 +1947,7 @@ static struct unix_funcs unix_funcs = */ static void start_main_thread(void) { + SYSTEM_SERVICE_TABLE syscall_table = __wine_syscall_table; NTSTATUS status; TEB *teb = virtual_alloc_first_teb(); @@ -1954,7 +1970,8 @@ 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 ); - ntdll_init_syscalls( 0, &__wine_syscall_table, p__wine_syscall_dispatcher ); + syscall_table.ArgumentTable = syscall_args; + ntdll_init_syscalls( 0, &syscall_table, p__wine_syscall_dispatcher ); status = p__wine_set_unix_funcs( NTDLL_UNIXLIB_VERSION, &unix_funcs ); if (status == STATUS_REVISION_MISMATCH) { diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 84738fc9135..d9d6fcae0c6 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1444,13 +1444,10 @@ void output_syscalls( DLLSPEC *spec ) output( "\t.data\n" ); output( "\t.align %d\n", get_alignment( get_ptr_size() ) ); output( "%s\n", asm_globl("__wine_syscall_table") ); - output( "\t%s .Lsyscall_table, 0, %u, .Lsyscall_args\n", get_asm_ptr_keyword(), count ); + output( "\t%s .Lsyscall_table, 0, %u, 0\n", get_asm_ptr_keyword(), count ); output( ".Lsyscall_table:\n" ); for (i = 0; i < count; i++) output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name( get_link_name( syscalls[i] ))); - output( ".Lsyscall_args:\n" ); - for (i = 0; i < count; i++) - output( "\t.byte %u\n", get_args_size( syscalls[i] )); return; } @@ -1574,6 +1571,8 @@ void output_syscalls( DLLSPEC *spec ) output( "\t.align %d\n", get_alignment( get_ptr_size() ) ); output( "%s\n", asm_globl("__wine_syscall_dispatcher") ); output( "\t%s 0\n", get_asm_ptr_keyword() ); + output( "\t.short %u\n", count ); + for (i = 0; i < count; i++) output( "\t.byte %u\n", get_args_size( syscalls[i] )); }