Module: wine Branch: master Commit: f7332ab4a6e199d03e4318d82c0b16a0396b935c URL: https://gitlab.winehq.org/wine/wine/-/commit/f7332ab4a6e199d03e4318d82c0b16a...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Nov 10 10:29:41 2022 +0100
ntdll: Use a proper Unix syscall for load_so_dll().
---
dlls/ntdll/loader.c | 20 +++++++++----------- dlls/ntdll/ntdll_misc.h | 1 + dlls/ntdll/unix/loader.c | 29 +++++++++++++++++++++++++---- dlls/ntdll/unix/unix_private.h | 5 +++++ dlls/ntdll/unix/virtual.c | 10 ++++++++-- dlls/ntdll/unixlib.h | 20 +++++++++++++++++--- 6 files changed, 65 insertions(+), 20 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 96001e14de5..a301659ae82 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -76,6 +76,8 @@ static DWORD (WINAPI *pCtrlRoutine)(void *);
SYSTEM_DLL_INIT_BLOCK LdrSystemDllInitBlock = { 0xf0 };
+unixlib_handle_t ntdll_unix_handle = 0; + /* windows directory */ const WCHAR windows_dir[] = L"C:\windows"; /* system directory with trailing backslash */ @@ -2201,6 +2203,8 @@ static void build_ntdll_module(void) wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS; node_ntdll = wm->ldr.DdagNode; if (TRACE_ON(relay)) RELAY_SetupDLL( meminfo.AllocationBase ); + NtQueryVirtualMemory( GetCurrentProcess(), meminfo.AllocationBase, MemoryWineUnixFuncs, + &ntdll_unix_handle, sizeof(ntdll_unix_handle), NULL ); }
@@ -2623,10 +2627,10 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name, void *module; NTSTATUS status; WINE_MODREF *wm; - UNICODE_STRING win_name = *nt_name; + struct load_so_dll_params params = { *nt_name, &module };
- TRACE( "trying %s as so lib\n", debugstr_us(&win_name) ); - if ((status = unix_funcs->load_so_dll( &win_name, &module ))) + TRACE( "trying %s as so lib\n", debugstr_us(nt_name) ); + if ((status = NTDLL_UNIX_CALL( load_so_dll, ¶ms ))) { WARN( "failed to load .so lib %s\n", debugstr_us(nt_name) ); if (status == STATUS_INVALID_IMAGE_FORMAT) status = STATUS_INVALID_IMAGE_NOT_MZ; @@ -2643,7 +2647,7 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name, { SECTION_IMAGE_INFORMATION image_info = { 0 };
- if ((status = build_module( load_path, &win_name, &module, &image_info, NULL, flags, FALSE, &wm ))) + if ((status = build_module( load_path, ¶ms.nt_name, &module, &image_info, NULL, flags, FALSE, &wm ))) { if (module) NtUnmapViewOfSection( NtCurrentProcess(), module ); return status; @@ -3152,7 +3156,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, DWORD fl switch (nts) { case STATUS_INVALID_IMAGE_NOT_MZ: /* not in PE format, maybe it's a .so file */ - nts = load_so_dll( load_path, &nt_name, flags, pwm ); + if (ntdll_unix_handle) nts = load_so_dll( load_path, &nt_name, flags, pwm ); break;
case STATUS_SUCCESS: /* valid PE file */ @@ -4598,11 +4602,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) }
-static NTSTATUS CDECL load_so_dll_fallback( UNICODE_STRING *nt_name, void **module ) -{ - return STATUS_INVALID_IMAGE_FORMAT; -} - static void CDECL init_builtin_dll_fallback( void *module ) { } @@ -4622,7 +4621,6 @@ static LONGLONG WINAPI RtlGetSystemTimePrecise_fallback(void)
static const struct unix_funcs unix_fallbacks = { - load_so_dll_fallback, init_builtin_dll_fallback, unwind_builtin_dll_fallback, RtlGetSystemTimePrecise_fallback, diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index 973e985ff42..1ce972e3b38 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -24,6 +24,7 @@ #include <sys/types.h>
#include "windef.h" +#include "winbase.h" #include "winnt.h" #include "winternl.h" #include "unixlib.h" diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index c25b373bc5e..7d4b9f0ee0a 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -396,7 +396,7 @@ const char **dll_paths = NULL; const char **system_dll_paths = NULL; const char *user_name = NULL; SECTION_IMAGE_INFORMATION main_image_info = { NULL }; -static HMODULE ntdll_module; +HMODULE ntdll_module = 0; static const IMAGE_EXPORT_DIRECTORY *ntdll_exports;
/* adjust an array of pointers to make them into RVAs */ @@ -1375,9 +1375,11 @@ NTSTATUS WINAPI __wine_unix_call( unixlib_handle_t handle, unsigned int code, vo /*********************************************************************** * load_so_dll */ -static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module ) +static NTSTATUS load_so_dll( void *args ) { static const WCHAR soW[] = {'.','s','o',0}; + struct load_so_dll_params *params = args; + UNICODE_STRING *nt_name = ¶ms->nt_name; OBJECT_ATTRIBUTES attr; UNICODE_STRING redir; pe_image_info_t info; @@ -1399,7 +1401,7 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module ) len = nt_name->Length / sizeof(WCHAR); if (len > 3 && !wcsicmp( nt_name->Buffer + len - 3, soW )) nt_name->Length -= 3 * sizeof(WCHAR);
- status = dlopen_dll( unix_name, nt_name, module, &info, FALSE ); + status = dlopen_dll( unix_name, nt_name, params->module, &info, FALSE ); free( unix_name ); free( redir.Buffer ); return status; @@ -2152,13 +2154,32 @@ static ULONG_PTR get_image_address(void) */ static struct unix_funcs unix_funcs = { - load_so_dll, init_builtin_dll, unwind_builtin_dll, RtlGetSystemTimePrecise, };
+/*********************************************************************** + * __wine_unix_call_funcs + */ +const unixlib_entry_t __wine_unix_call_funcs[] = +{ + load_so_dll, +}; + + +static NTSTATUS wow64_load_so_dll( void *args ) { return STATUS_INVALID_IMAGE_FORMAT; } + +/*********************************************************************** + * __wine_unix_call_wow64_funcs + */ +const unixlib_entry_t __wine_unix_call_wow64_funcs[] = +{ + wow64_load_so_dll, +}; + + /*********************************************************************** * start_main_thread */ diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index f45e8462700..17159cd6a44 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -27,6 +27,7 @@ #include "wine/unixlib.h" #include "wine/server.h" #include "wine/list.h" +#include "wine/debug.h"
struct msghdr;
@@ -40,6 +41,10 @@ static const WORD current_machine = IMAGE_FILE_MACHINE_ARMNT; static const WORD current_machine = IMAGE_FILE_MACHINE_ARM64; #endif extern WORD native_machine DECLSPEC_HIDDEN; +extern HMODULE ntdll_module DECLSPEC_HIDDEN; + +extern const unixlib_entry_t __wine_unix_call_funcs[]; +extern const unixlib_entry_t __wine_unix_call_wow64_funcs[];
static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 5f1005a129f..e1e45ba60f1 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -635,13 +635,19 @@ void *get_builtin_so_handle( void *module ) /*********************************************************************** * get_builtin_unix_funcs */ -static NTSTATUS get_builtin_unix_funcs( void *module, BOOL wow, void **funcs ) +static NTSTATUS get_builtin_unix_funcs( void *module, BOOL wow, const void **funcs ) { const char *ptr_name = wow ? "__wine_unix_call_wow64_funcs" : "__wine_unix_call_funcs"; sigset_t sigset; NTSTATUS status = STATUS_DLL_NOT_FOUND; struct builtin_module *builtin;
+ if (module == ntdll_module) + { + *funcs = wow ? __wine_unix_call_wow64_funcs : __wine_unix_call_funcs; + return STATUS_SUCCESS; + } + server_enter_uninterrupted_section( &virtual_mutex, &sigset ); LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry ) { @@ -4422,7 +4428,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr, if (process == GetCurrentProcess()) { void *module = (void *)addr; - void *funcs = NULL; + const void *funcs = NULL;
status = get_builtin_unix_funcs( module, info_class == MemoryWineUnixWow64Funcs, &funcs ); if (!status) *(unixlib_handle_t *)buffer = (UINT_PTR)funcs; diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h index fa5fad73980..e41f7290bc2 100644 --- a/dlls/ntdll/unixlib.h +++ b/dlls/ntdll/unixlib.h @@ -21,17 +21,31 @@ #ifndef __NTDLL_UNIXLIB_H #define __NTDLL_UNIXLIB_H
-#include "wine/debug.h" +#include "wine/unixlib.h"
struct _DISPATCHER_CONTEXT;
+struct load_so_dll_params +{ + UNICODE_STRING nt_name; + void **module; +}; + +enum ntdll_unix_funcs +{ + unix_load_so_dll, +}; + +extern unixlib_handle_t ntdll_unix_handle; + +#define NTDLL_UNIX_CALL( func, params ) __wine_unix_call( ntdll_unix_handle, unix_ ## func, params ) + /* increment this when you change the function table */ -#define NTDLL_UNIXLIB_VERSION 135 +#define NTDLL_UNIXLIB_VERSION 136
struct unix_funcs { /* loader functions */ - NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module ); void (CDECL *init_builtin_dll)( void *module ); NTSTATUS (CDECL *unwind_builtin_dll)( ULONG type, struct _DISPATCHER_CONTEXT *dispatch, CONTEXT *context );