ntdll: Load the Unix library only when __wine_init_unix_lib() is called.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
81bbc4872e
commit
89340bb762
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,33 @@ 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;
|
||||
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;
|
||||
*name = builtin->unix_name;
|
||||
*handle = builtin->unix_handle;
|
||||
*entry = builtin->unix_entry;
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_builtin_unix_info
|
||||
*/
|
||||
NTSTATUS set_builtin_unix_info( void *module, const char *name, void *handle, void *entry )
|
||||
{
|
||||
sigset_t sigset;
|
||||
NTSTATUS status = STATUS_DLL_NOT_FOUND;
|
||||
|
@ -655,6 +681,8 @@ NTSTATUS set_builtin_unix_handle( void *module, void *handle, void *entry )
|
|||
if (builtin->module != module) continue;
|
||||
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;
|
||||
|
@ -667,28 +695,6 @@ NTSTATUS set_builtin_unix_handle( void *module, void *handle, void *entry )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue