ntdll: Call the Unix entry point from the Unix side.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-03-16 11:10:15 +01:00
parent 22da5bd757
commit e0fc8d7acb
5 changed files with 49 additions and 45 deletions

View File

@ -117,7 +117,6 @@ typedef struct _wine_modref
{ {
LDR_DATA_TABLE_ENTRY ldr; LDR_DATA_TABLE_ENTRY ldr;
struct file_id id; struct file_id id;
void *unix_entry;
int alloc_deps; int alloc_deps;
int nDeps; int nDeps;
struct _wine_modref **deps; 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 ) DWORD flags, WINE_MODREF** pwm, BOOL prefer_native )
{ {
NTSTATUS status; NTSTATUS status;
void *module, *unix_entry = NULL; void *module;
SECTION_IMAGE_INFORMATION image_info; SECTION_IMAGE_INFORMATION image_info;
TRACE("Trying built-in %s\n", debugstr_us(nt_name)); 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 (status) return status;
if ((*pwm = get_modref( module ))) /* already loaded */ 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) ); TRACE( "loading %s\n", debugstr_us(nt_name) );
status = build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm ); status = build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm );
if (!status) (*pwm)->unix_entry = unix_entry; if (status && module) NtUnmapViewOfSection( NtCurrentProcess(), module );
else if (module) NtUnmapViewOfSection( NtCurrentProcess(), module );
return status; return status;
} }
@ -2730,15 +2728,11 @@ done:
NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
{ {
WINE_MODREF *wm; WINE_MODREF *wm;
NTSTATUS ret = STATUS_DLL_NOT_FOUND; NTSTATUS ret;
RtlEnterCriticalSection( &loader_section ); RtlEnterCriticalSection( &loader_section );
if ((wm = get_modref( module ))) if ((wm = get_modref( module ))) ret = unix_funcs->init_unix_lib( module, reason, ptr_in, ptr_out );
{
NTSTATUS (CDECL *init_func)( HMODULE, DWORD, const void *, void * ) = wm->unix_entry;
if (init_func) ret = init_func( module, reason, ptr_in, ptr_out );
}
else ret = STATUS_INVALID_HANDLE; else ret = STATUS_INVALID_HANDLE;
RtlLeaveCriticalSection( &loader_section ); RtlLeaveCriticalSection( &loader_section );

View File

@ -1107,7 +1107,7 @@ already_loaded:
/*********************************************************************** /***********************************************************************
* dlopen_unix_dll * 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; void *unix_module, *handle, *entry;
const IMAGE_NT_HEADERS *nt; 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; if (!(entry = dlsym( handle, "__wine_init_unix_lib" ))) goto done;
unix_module = (HMODULE)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff); 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 ); map_so_dll( nt, unix_module );
fixup_ntdll_imports( name, unix_module ); fixup_ntdll_imports( name, unix_module );
*unix_entry = entry; return status;
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;
} }
done: done:
dlclose( handle ); dlclose( handle );
@ -1326,7 +1313,7 @@ static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, void **m
/*********************************************************************** /***********************************************************************
* load_builtin_dll * 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 ) SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native )
{ {
unsigned int i, pos, namepos, namelen, maxlen = 0; unsigned int i, pos, namepos, namelen, maxlen = 0;
@ -1400,7 +1387,7 @@ done:
if (!status && ext) if (!status && ext)
{ {
strcpy( ext, ".so" ); strcpy( ext, ".so" );
dlopen_unix_dll( *module, ptr, unix_entry ); dlopen_unix_dll( *module, ptr );
} }
free( file ); free( file );
return status; return status;
@ -1591,6 +1578,7 @@ static struct unix_funcs unix_funcs =
load_so_dll, load_so_dll,
load_builtin_dll, load_builtin_dll,
init_builtin_dll, init_builtin_dll,
init_unix_lib,
unwind_builtin_dll, unwind_builtin_dll,
get_load_order, get_load_order,
__wine_dbg_get_channel_flags, __wine_dbg_get_channel_flags,

View File

@ -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, extern void virtual_fill_image_information( const pe_image_info_t *pe_info,
SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN; SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN;
extern void *get_builtin_so_handle( void *module ) 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 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, extern BOOL get_thread_times( int unix_pid, int unix_tid, LARGE_INTEGER *kernel_time,

View File

@ -91,6 +91,7 @@ struct builtin_module
void *handle; void *handle;
void *module; void *module;
void *unix_handle; void *unix_handle;
void *unix_entry;
}; };
static struct list builtin_modules = LIST_INIT( builtin_modules ); 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->handle = handle;
builtin->module = module; builtin->module = module;
builtin->unix_handle = NULL; builtin->unix_handle = NULL;
builtin->unix_entry = NULL;
if (st) if (st)
{ {
builtin->dev = st->st_dev; builtin->dev = st->st_dev;
@ -641,7 +643,7 @@ void *get_builtin_so_handle( void *module )
/*********************************************************************** /***********************************************************************
* set_builtin_unix_handle * 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; sigset_t sigset;
NTSTATUS status = STATUS_DLL_NOT_FOUND; 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 ); server_enter_uninterrupted_section( &virtual_mutex, &sigset );
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry ) 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; builtin->unix_handle = handle;
else if (builtin->unix_handle) status = STATUS_OBJECT_NAME_COLLISION; builtin->unix_entry = entry;
else status = STATUS_SUCCESS; status = STATUS_SUCCESS;
break;
}
if (builtin->unix_handle == handle)
{
status = STATUS_DUPLICATE_NAME;
break;
} }
else status = STATUS_IMAGE_ALREADY_LOADED;
break;
} }
if (!status) builtin->unix_handle = handle;
server_leave_uninterrupted_section( &virtual_mutex, &sigset ); server_leave_uninterrupted_section( &virtual_mutex, &sigset );
return status; 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 * free_ranges_lower_bound
* *

View File

@ -37,7 +37,7 @@ enum loadorder
}; };
/* increment this when you change the function table */ /* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 117 #define NTDLL_UNIXLIB_VERSION 118
struct unix_funcs struct unix_funcs
{ {
@ -85,9 +85,10 @@ struct unix_funcs
/* loader functions */ /* loader functions */
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module ); 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 ); SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native );
void (CDECL *init_builtin_dll)( void *module ); 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, NTSTATUS (CDECL *unwind_builtin_dll)( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
CONTEXT *context ); CONTEXT *context );
enum loadorder (CDECL *get_load_order)( const WCHAR *app_name, const UNICODE_STRING *nt_name ); enum loadorder (CDECL *get_load_order)( const WCHAR *app_name, const UNICODE_STRING *nt_name );