Alexandre Julliard : ntdll: Load the Unix library only when __wine_init_unix_lib() is called.
Alexandre Julliard
julliard at winehq.org
Mon Mar 22 17:15:52 CDT 2021
Module: wine
Branch: master
Commit: 89340bb762300c76a40cb4b62ba0f0d779306125
URL: https://source.winehq.org/git/wine.git/?a=commit;h=89340bb762300c76a40cb4b62ba0f0d779306125
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Mar 22 16:03:22 2021 +0100
ntdll: Load the Unix library only when __wine_init_unix_lib() is called.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/loader.c | 40 ++++++++++++++++++++++++----------------
dlls/ntdll/unix/unix_private.h | 4 ++--
dlls/ntdll/unix/virtual.c | 36 +++++++++++++++++++++---------------
3 files changed, 47 insertions(+), 33 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 9e43358a26d..1c95b84e965 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -1111,30 +1111,38 @@ already_loaded:
/***********************************************************************
- * dlopen_unix_dll
+ * init_unix_lib
*/
-static NTSTATUS dlopen_unix_dll( void *module, const char *name )
+static NTSTATUS CDECL init_unix_lib( void *module, DWORD reason, const void *ptr_in, void *ptr_out )
{
- void *unix_module, *handle, *entry;
+ NTSTATUS (CDECL *init_func)( HMODULE, DWORD, const void *, void * );
const IMAGE_NT_HEADERS *nt;
- NTSTATUS status = STATUS_INVALID_IMAGE_FORMAT;
+ const char *name;
+ void *handle, *entry, *unix_module;
+ NTSTATUS status;
- handle = dlopen( name, RTLD_NOW );
- if (!handle) return STATUS_DLL_NOT_FOUND;
- if (!(nt = dlsym( handle, "__wine_spec_nt_header" ))) goto done;
- if (!(entry = dlsym( handle, "__wine_init_unix_lib" ))) goto done;
+ if ((status = get_builtin_unix_info( module, &name, &handle, &entry ))) return status;
- unix_module = (HMODULE)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff);
- status = set_builtin_unix_handle( module, handle, entry );
- if (!status)
+ if (!entry)
{
+ if (!name) return STATUS_DLL_NOT_FOUND;
+ if (!(handle = dlopen( name, RTLD_NOW ))) return STATUS_DLL_NOT_FOUND;
+
+ if (!(nt = dlsym( handle, "__wine_spec_nt_header" )) ||
+ !(entry = dlsym( handle, "__wine_init_unix_lib" )))
+ {
+ dlclose( handle );
+ set_builtin_unix_info( module, NULL, NULL, NULL );
+ return STATUS_INVALID_IMAGE_FORMAT;
+ }
+ TRACE( "loaded %s for %p\n", debugstr_a(name), module );
+ unix_module = (void *)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff);
map_so_dll( nt, unix_module );
fixup_ntdll_imports( name, unix_module );
- return status;
+ set_builtin_unix_info( module, NULL, handle, entry );
}
-done:
- dlclose( handle );
- return status;
+ init_func = entry;
+ return init_func( module, reason, ptr_in, ptr_out );
}
@@ -1393,7 +1401,7 @@ done:
if (!status && ext)
{
strcpy( ext, ".so" );
- dlopen_unix_dll( *module, ptr );
+ set_builtin_unix_info( *module, ptr, NULL, NULL );
}
free( file );
return status;
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index c00a6ee6aa8..5877a00bac8 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -203,8 +203,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 *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_builtin_unix_info( void *module, const char **name, void **handle, void **entry ) DECLSPEC_HIDDEN;
+extern NTSTATUS set_builtin_unix_info( void *module, const char *name, void *handle, void *entry ) 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 bff4569b615..4edc7d0261e 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -90,6 +90,7 @@ struct builtin_module
ino_t ino;
void *handle;
void *module;
+ char *unix_name;
void *unix_handle;
void *unix_entry;
};
@@ -570,6 +571,7 @@ static void add_builtin_module( void *module, void *handle, const struct stat *s
if (!(builtin = malloc( sizeof(*builtin) ))) return;
builtin->handle = handle;
builtin->module = module;
+ builtin->unix_name = NULL;
builtin->unix_handle = NULL;
builtin->unix_entry = NULL;
if (st)
@@ -641,9 +643,9 @@ void *get_builtin_so_handle( void *module )
/***********************************************************************
- * set_builtin_unix_handle
+ * get_builtin_unix_info
*/
-NTSTATUS set_builtin_unix_handle( void *module, void *handle, void *entry )
+NTSTATUS get_builtin_unix_info( void *module, const char **name, void **handle, void **entry )
{
sigset_t sigset;
NTSTATUS status = STATUS_DLL_NOT_FOUND;
@@ -653,13 +655,10 @@ NTSTATUS set_builtin_unix_handle( void *module, void *handle, void *entry )
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
{
if (builtin->module != module) continue;
- if (!builtin->unix_handle)
- {
- builtin->unix_handle = handle;
- builtin->unix_entry = entry;
- status = STATUS_SUCCESS;
- }
- else status = STATUS_IMAGE_ALREADY_LOADED;
+ *name = builtin->unix_name;
+ *handle = builtin->unix_handle;
+ *entry = builtin->unix_entry;
+ status = STATUS_SUCCESS;
break;
}
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
@@ -668,24 +667,31 @@ NTSTATUS set_builtin_unix_handle( void *module, void *handle, void *entry )
/***********************************************************************
- * init_unix_lib
+ * set_builtin_unix_info
*/
-NTSTATUS CDECL init_unix_lib( void *module, DWORD reason, const void *ptr_in, void *ptr_out )
+NTSTATUS set_builtin_unix_info( void *module, const char *name, void *handle, void *entry )
{
sigset_t sigset;
- NTSTATUS (CDECL *init_func)( HMODULE, DWORD, const void *, void * ) = NULL;
+ NTSTATUS status = STATUS_DLL_NOT_FOUND;
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;
+ if (!builtin->unix_handle)
+ {
+ free( builtin->unix_name );
+ builtin->unix_name = name ? strdup( name ) : NULL;
+ builtin->unix_handle = handle;
+ builtin->unix_entry = entry;
+ status = STATUS_SUCCESS;
+ }
+ else status = STATUS_IMAGE_ALREADY_LOADED;
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 );
+ return status;
}
More information about the wine-cvs
mailing list