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 *);
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, &params )))
{
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, &params.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,
......
......@@ -24,6 +24,7 @@
#include <sys/types.h>
#include "windef.h"
#include "winbase.h"
#include "winnt.h"
#include "winternl.h"
#include "unixlib.h"
......
......@@ -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 = &params->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,7 +2154,6 @@ static ULONG_PTR get_image_address(void)
*/
static struct unix_funcs unix_funcs =
{
load_so_dll,
init_builtin_dll,
unwind_builtin_dll,
RtlGetSystemTimePrecise,
......@@ -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
*/
static void start_main_thread(void)
......
......@@ -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));
......
......@@ -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;
......
......@@ -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 );
......
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