Commit f7332ab4 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Use a proper Unix syscall for load_so_dll().

parent 2a5191a7
...@@ -76,6 +76,8 @@ static DWORD (WINAPI *pCtrlRoutine)(void *); ...@@ -76,6 +76,8 @@ static DWORD (WINAPI *pCtrlRoutine)(void *);
SYSTEM_DLL_INIT_BLOCK LdrSystemDllInitBlock = { 0xf0 }; SYSTEM_DLL_INIT_BLOCK LdrSystemDllInitBlock = { 0xf0 };
unixlib_handle_t ntdll_unix_handle = 0;
/* windows directory */ /* windows directory */
const WCHAR windows_dir[] = L"C:\\windows"; const WCHAR windows_dir[] = L"C:\\windows";
/* system directory with trailing backslash */ /* system directory with trailing backslash */
...@@ -2201,6 +2203,8 @@ static void build_ntdll_module(void) ...@@ -2201,6 +2203,8 @@ static void build_ntdll_module(void)
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS; wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
node_ntdll = wm->ldr.DdagNode; node_ntdll = wm->ldr.DdagNode;
if (TRACE_ON(relay)) RELAY_SetupDLL( meminfo.AllocationBase ); 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, ...@@ -2623,10 +2627,10 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
void *module; void *module;
NTSTATUS status; NTSTATUS status;
WINE_MODREF *wm; 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) ); TRACE( "trying %s as so lib\n", debugstr_us(nt_name) );
if ((status = unix_funcs->load_so_dll( &win_name, &module ))) if ((status = NTDLL_UNIX_CALL( load_so_dll, &params )))
{ {
WARN( "failed to load .so lib %s\n", debugstr_us(nt_name) ); WARN( "failed to load .so lib %s\n", debugstr_us(nt_name) );
if (status == STATUS_INVALID_IMAGE_FORMAT) status = STATUS_INVALID_IMAGE_NOT_MZ; 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, ...@@ -2643,7 +2647,7 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
{ {
SECTION_IMAGE_INFORMATION image_info = { 0 }; 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, &params.nt_name, &module, &image_info, NULL, flags, FALSE, &wm )))
{ {
if (module) NtUnmapViewOfSection( NtCurrentProcess(), module ); if (module) NtUnmapViewOfSection( NtCurrentProcess(), module );
return status; return status;
...@@ -3152,7 +3156,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, DWORD fl ...@@ -3152,7 +3156,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, DWORD fl
switch (nts) switch (nts)
{ {
case STATUS_INVALID_IMAGE_NOT_MZ: /* not in PE format, maybe it's a .so file */ 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; break;
case STATUS_SUCCESS: /* valid PE file */ case STATUS_SUCCESS: /* valid PE file */
...@@ -4598,11 +4602,6 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) ...@@ -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 ) static void CDECL init_builtin_dll_fallback( void *module )
{ {
} }
...@@ -4622,7 +4621,6 @@ static LONGLONG WINAPI RtlGetSystemTimePrecise_fallback(void) ...@@ -4622,7 +4621,6 @@ static LONGLONG WINAPI RtlGetSystemTimePrecise_fallback(void)
static const struct unix_funcs unix_fallbacks = static const struct unix_funcs unix_fallbacks =
{ {
load_so_dll_fallback,
init_builtin_dll_fallback, init_builtin_dll_fallback,
unwind_builtin_dll_fallback, unwind_builtin_dll_fallback,
RtlGetSystemTimePrecise_fallback, RtlGetSystemTimePrecise_fallback,
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "windef.h" #include "windef.h"
#include "winbase.h"
#include "winnt.h" #include "winnt.h"
#include "winternl.h" #include "winternl.h"
#include "unixlib.h" #include "unixlib.h"
......
...@@ -396,7 +396,7 @@ const char **dll_paths = NULL; ...@@ -396,7 +396,7 @@ const char **dll_paths = NULL;
const char **system_dll_paths = NULL; const char **system_dll_paths = NULL;
const char *user_name = NULL; const char *user_name = NULL;
SECTION_IMAGE_INFORMATION main_image_info = { NULL }; SECTION_IMAGE_INFORMATION main_image_info = { NULL };
static HMODULE ntdll_module; HMODULE ntdll_module = 0;
static const IMAGE_EXPORT_DIRECTORY *ntdll_exports; static const IMAGE_EXPORT_DIRECTORY *ntdll_exports;
/* adjust an array of pointers to make them into RVAs */ /* 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 ...@@ -1375,9 +1375,11 @@ NTSTATUS WINAPI __wine_unix_call( unixlib_handle_t handle, unsigned int code, vo
/*********************************************************************** /***********************************************************************
* load_so_dll * 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}; static const WCHAR soW[] = {'.','s','o',0};
struct load_so_dll_params *params = args;
UNICODE_STRING *nt_name = &params->nt_name;
OBJECT_ATTRIBUTES attr; OBJECT_ATTRIBUTES attr;
UNICODE_STRING redir; UNICODE_STRING redir;
pe_image_info_t info; pe_image_info_t info;
...@@ -1399,7 +1401,7 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module ) ...@@ -1399,7 +1401,7 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
len = nt_name->Length / sizeof(WCHAR); len = nt_name->Length / sizeof(WCHAR);
if (len > 3 && !wcsicmp( nt_name->Buffer + len - 3, soW )) nt_name->Length -= 3 * 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( unix_name );
free( redir.Buffer ); free( redir.Buffer );
return status; return status;
...@@ -2152,7 +2154,6 @@ static ULONG_PTR get_image_address(void) ...@@ -2152,7 +2154,6 @@ static ULONG_PTR get_image_address(void)
*/ */
static struct unix_funcs unix_funcs = static struct unix_funcs unix_funcs =
{ {
load_so_dll,
init_builtin_dll, init_builtin_dll,
unwind_builtin_dll, unwind_builtin_dll,
RtlGetSystemTimePrecise, RtlGetSystemTimePrecise,
...@@ -2160,6 +2161,26 @@ static struct unix_funcs unix_funcs = ...@@ -2160,6 +2161,26 @@ static struct unix_funcs unix_funcs =
/*********************************************************************** /***********************************************************************
* __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 * start_main_thread
*/ */
static void start_main_thread(void) static void start_main_thread(void)
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "wine/unixlib.h" #include "wine/unixlib.h"
#include "wine/server.h" #include "wine/server.h"
#include "wine/list.h" #include "wine/list.h"
#include "wine/debug.h"
struct msghdr; struct msghdr;
...@@ -40,6 +41,10 @@ static const WORD current_machine = IMAGE_FILE_MACHINE_ARMNT; ...@@ -40,6 +41,10 @@ static const WORD current_machine = IMAGE_FILE_MACHINE_ARMNT;
static const WORD current_machine = IMAGE_FILE_MACHINE_ARM64; static const WORD current_machine = IMAGE_FILE_MACHINE_ARM64;
#endif #endif
extern WORD native_machine DECLSPEC_HIDDEN; 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)); static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
......
...@@ -635,13 +635,19 @@ void *get_builtin_so_handle( void *module ) ...@@ -635,13 +635,19 @@ void *get_builtin_so_handle( void *module )
/*********************************************************************** /***********************************************************************
* get_builtin_unix_funcs * 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"; const char *ptr_name = wow ? "__wine_unix_call_wow64_funcs" : "__wine_unix_call_funcs";
sigset_t sigset; sigset_t sigset;
NTSTATUS status = STATUS_DLL_NOT_FOUND; NTSTATUS status = STATUS_DLL_NOT_FOUND;
struct builtin_module *builtin; 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 ); 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 )
{ {
...@@ -4422,7 +4428,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr, ...@@ -4422,7 +4428,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
if (process == GetCurrentProcess()) if (process == GetCurrentProcess())
{ {
void *module = (void *)addr; void *module = (void *)addr;
void *funcs = NULL; const void *funcs = NULL;
status = get_builtin_unix_funcs( module, info_class == MemoryWineUnixWow64Funcs, &funcs ); status = get_builtin_unix_funcs( module, info_class == MemoryWineUnixWow64Funcs, &funcs );
if (!status) *(unixlib_handle_t *)buffer = (UINT_PTR)funcs; if (!status) *(unixlib_handle_t *)buffer = (UINT_PTR)funcs;
......
...@@ -21,17 +21,31 @@ ...@@ -21,17 +21,31 @@
#ifndef __NTDLL_UNIXLIB_H #ifndef __NTDLL_UNIXLIB_H
#define __NTDLL_UNIXLIB_H #define __NTDLL_UNIXLIB_H
#include "wine/debug.h" #include "wine/unixlib.h"
struct _DISPATCHER_CONTEXT; 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 */ /* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 135 #define NTDLL_UNIXLIB_VERSION 136
struct unix_funcs struct unix_funcs
{ {
/* loader functions */ /* loader functions */
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module );
void (CDECL *init_builtin_dll)( void *module ); void (CDECL *init_builtin_dll)( void *module );
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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment