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;
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 );

View File

@ -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,

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,
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,

View File

@ -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;
builtin->unix_handle = handle;
builtin->unix_entry = entry;
status = STATUS_SUCCESS;
}
else status = STATUS_IMAGE_ALREADY_LOADED;
break;
}
if (builtin->unix_handle == handle)
{
status = STATUS_DUPLICATE_NAME;
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
*

View File

@ -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 );