From e0fc8d7acbed511a495de8a566b59f8ab00310f1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 16 Mar 2021 11:10:15 +0100 Subject: [PATCH] ntdll: Call the Unix entry point from the Unix side. Signed-off-by: Alexandre Julliard --- dlls/ntdll/loader.c | 16 ++++--------- dlls/ntdll/unix/loader.c | 26 ++++++-------------- dlls/ntdll/unix/unix_private.h | 3 ++- dlls/ntdll/unix/virtual.c | 44 ++++++++++++++++++++++++---------- dlls/ntdll/unixlib.h | 5 ++-- 5 files changed, 49 insertions(+), 45 deletions(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index fa8f234ce42..83ae707ba3f 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -117,7 +117,6 @@ typedef struct _wine_modref { LDR_DATA_TABLE_ENTRY ldr; struct file_id id; - void *unix_entry; int alloc_deps; int nDeps; struct _wine_modref **deps; @@ -2340,12 +2339,12 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, UNICODE_STRING *nt_name, DWORD flags, WINE_MODREF** pwm, BOOL prefer_native ) { NTSTATUS status; - void *module, *unix_entry = NULL; + void *module; SECTION_IMAGE_INFORMATION image_info; TRACE("Trying built-in %s\n", debugstr_us(nt_name)); - status = unix_funcs->load_builtin_dll( nt_name, &module, &unix_entry, &image_info, prefer_native ); + status = unix_funcs->load_builtin_dll( nt_name, &module, &image_info, prefer_native ); if (status) return status; if ((*pwm = get_modref( module ))) /* already loaded */ @@ -2359,8 +2358,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, UNICODE_STRING *nt_name, TRACE( "loading %s\n", debugstr_us(nt_name) ); status = build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm ); - if (!status) (*pwm)->unix_entry = unix_entry; - else if (module) NtUnmapViewOfSection( NtCurrentProcess(), module ); + if (status && module) NtUnmapViewOfSection( NtCurrentProcess(), module ); return status; } @@ -2730,15 +2728,11 @@ done: NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) { WINE_MODREF *wm; - NTSTATUS ret = STATUS_DLL_NOT_FOUND; + NTSTATUS ret; RtlEnterCriticalSection( &loader_section ); - if ((wm = get_modref( module ))) - { - NTSTATUS (CDECL *init_func)( HMODULE, DWORD, const void *, void * ) = wm->unix_entry; - if (init_func) ret = init_func( module, reason, ptr_in, ptr_out ); - } + if ((wm = get_modref( module ))) ret = unix_funcs->init_unix_lib( module, reason, ptr_in, ptr_out ); else ret = STATUS_INVALID_HANDLE; RtlLeaveCriticalSection( &loader_section ); diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 69f76039e55..b9df449fa5a 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1107,7 +1107,7 @@ already_loaded: /*********************************************************************** * dlopen_unix_dll */ -static NTSTATUS dlopen_unix_dll( void *module, const char *name, void **unix_entry ) +static NTSTATUS dlopen_unix_dll( void *module, const char *name ) { void *unix_module, *handle, *entry; const IMAGE_NT_HEADERS *nt; @@ -1119,25 +1119,12 @@ static NTSTATUS dlopen_unix_dll( void *module, const char *name, void **unix_ent if (!(entry = dlsym( handle, "__wine_init_unix_lib" ))) goto done; unix_module = (HMODULE)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff); - switch (set_builtin_unix_handle( module, handle )) + status = set_builtin_unix_handle( module, handle, entry ); + if (!status) { - case STATUS_IMAGE_ALREADY_LOADED: - *unix_entry = entry; - return STATUS_SUCCESS; - case STATUS_SUCCESS: map_so_dll( nt, unix_module ); fixup_ntdll_imports( name, unix_module ); - *unix_entry = entry; - return STATUS_SUCCESS; - case STATUS_OBJECT_NAME_COLLISION: - ERR( "module %p already has a Unix module that's not %s\n", module, debugstr_a(name) ); - break; - case STATUS_DUPLICATE_NAME: - ERR( "%s already loaded for module %p\n", debugstr_a(name), module ); - break; - case STATUS_DLL_NOT_FOUND: - ERR( "builtin module not found for %s\n", debugstr_a(name) ); - break; + return status; } done: dlclose( handle ); @@ -1326,7 +1313,7 @@ static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, void **m /*********************************************************************** * load_builtin_dll */ -static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module, void **unix_entry, +static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module, SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native ) { unsigned int i, pos, namepos, namelen, maxlen = 0; @@ -1400,7 +1387,7 @@ done: if (!status && ext) { strcpy( ext, ".so" ); - dlopen_unix_dll( *module, ptr, unix_entry ); + dlopen_unix_dll( *module, ptr ); } free( file ); return status; @@ -1591,6 +1578,7 @@ static struct unix_funcs unix_funcs = load_so_dll, load_builtin_dll, init_builtin_dll, + init_unix_lib, unwind_builtin_dll, get_load_order, __wine_dbg_get_channel_flags, diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 8899d02911e..3c961ce2ca5 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -198,7 +198,8 @@ extern void virtual_set_large_address_space(void) DECLSPEC_HIDDEN; extern void virtual_fill_image_information( const pe_image_info_t *pe_info, SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN; extern void *get_builtin_so_handle( void *module ) DECLSPEC_HIDDEN; -extern NTSTATUS set_builtin_unix_handle( void *module, void *unix_handle ) DECLSPEC_HIDDEN; +extern NTSTATUS set_builtin_unix_handle( void *module, void *handle, void *entry ) DECLSPEC_HIDDEN; +extern NTSTATUS CDECL init_unix_lib( void *module, DWORD reason, const void *ptr_in, void *ptr_out ) DECLSPEC_HIDDEN; extern NTSTATUS get_thread_ldt_entry( HANDLE handle, void *data, ULONG len, ULONG *ret_len ) DECLSPEC_HIDDEN; extern BOOL get_thread_times( int unix_pid, int unix_tid, LARGE_INTEGER *kernel_time, diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 1461cdf3c6c..bff4569b615 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -91,6 +91,7 @@ struct builtin_module void *handle; void *module; void *unix_handle; + void *unix_entry; }; static struct list builtin_modules = LIST_INIT( builtin_modules ); @@ -570,6 +571,7 @@ static void add_builtin_module( void *module, void *handle, const struct stat *s builtin->handle = handle; builtin->module = module; builtin->unix_handle = NULL; + builtin->unix_entry = NULL; if (st) { builtin->dev = st->st_dev; @@ -641,7 +643,7 @@ void *get_builtin_so_handle( void *module ) /*********************************************************************** * set_builtin_unix_handle */ -NTSTATUS set_builtin_unix_handle( void *module, void *handle ) +NTSTATUS set_builtin_unix_handle( void *module, void *handle, void *entry ) { sigset_t sigset; NTSTATUS status = STATUS_DLL_NOT_FOUND; @@ -650,25 +652,43 @@ NTSTATUS set_builtin_unix_handle( void *module, void *handle ) server_enter_uninterrupted_section( &virtual_mutex, &sigset ); LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry ) { - if (builtin->module == module) + if (builtin->module != module) continue; + if (!builtin->unix_handle) { - if (builtin->unix_handle == handle) status = STATUS_IMAGE_ALREADY_LOADED; - else if (builtin->unix_handle) status = STATUS_OBJECT_NAME_COLLISION; - else status = STATUS_SUCCESS; - break; - } - if (builtin->unix_handle == handle) - { - status = STATUS_DUPLICATE_NAME; - break; + builtin->unix_handle = handle; + builtin->unix_entry = entry; + status = STATUS_SUCCESS; } + else status = STATUS_IMAGE_ALREADY_LOADED; + break; } - if (!status) builtin->unix_handle = handle; server_leave_uninterrupted_section( &virtual_mutex, &sigset ); return status; } +/*********************************************************************** + * init_unix_lib + */ +NTSTATUS CDECL init_unix_lib( void *module, DWORD reason, const void *ptr_in, void *ptr_out ) +{ + sigset_t sigset; + NTSTATUS (CDECL *init_func)( HMODULE, DWORD, const void *, void * ) = NULL; + struct builtin_module *builtin; + + server_enter_uninterrupted_section( &virtual_mutex, &sigset ); + LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry ) + { + if (builtin->module != module) continue; + init_func = builtin->unix_entry; + break; + } + server_leave_uninterrupted_section( &virtual_mutex, &sigset ); + if (!init_func) return STATUS_DLL_NOT_FOUND; + return init_func( module, reason, ptr_in, ptr_out ); +} + + /*********************************************************************** * free_ranges_lower_bound * diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h index 62ea02a7a12..71cc4177c06 100644 --- a/dlls/ntdll/unixlib.h +++ b/dlls/ntdll/unixlib.h @@ -37,7 +37,7 @@ enum loadorder }; /* increment this when you change the function table */ -#define NTDLL_UNIXLIB_VERSION 117 +#define NTDLL_UNIXLIB_VERSION 118 struct unix_funcs { @@ -85,9 +85,10 @@ struct unix_funcs /* loader functions */ NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module ); - NTSTATUS (CDECL *load_builtin_dll)( UNICODE_STRING *name, void **module, void **unix_entry, + NTSTATUS (CDECL *load_builtin_dll)( UNICODE_STRING *name, void **module, SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native ); void (CDECL *init_builtin_dll)( void *module ); + NTSTATUS (CDECL *init_unix_lib)( void *module, DWORD reason, const void *ptr_in, void *ptr_out ); NTSTATUS (CDECL *unwind_builtin_dll)( ULONG type, struct _DISPATCHER_CONTEXT *dispatch, CONTEXT *context ); enum loadorder (CDECL *get_load_order)( const WCHAR *app_name, const UNICODE_STRING *nt_name );