ntdll: Move the loading of .so dlls to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
99649d7892
commit
31538a79a9
|
@ -24,12 +24,6 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_LINK_H
|
||||
# include <link.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
|
@ -42,7 +36,6 @@
|
|||
#include "delayloadhandler.h"
|
||||
|
||||
#include "wine/exception.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/server.h"
|
||||
|
@ -133,25 +126,11 @@ typedef struct _wine_modref
|
|||
{
|
||||
LDR_DATA_TABLE_ENTRY ldr;
|
||||
struct file_id id;
|
||||
void *so_handle;
|
||||
int alloc_deps;
|
||||
int nDeps;
|
||||
struct _wine_modref **deps;
|
||||
} WINE_MODREF;
|
||||
|
||||
/* info about the current builtin dll load */
|
||||
/* used to keep track of things across the register_dll constructor call */
|
||||
struct builtin_load_info
|
||||
{
|
||||
const WCHAR *load_path;
|
||||
const UNICODE_STRING *filename;
|
||||
NTSTATUS status;
|
||||
WINE_MODREF *wm;
|
||||
};
|
||||
|
||||
static struct builtin_load_info default_load_info;
|
||||
static struct builtin_load_info *builtin_load_info = &default_load_info;
|
||||
|
||||
static UINT tls_module_count; /* number of modules with TLS directory */
|
||||
static IMAGE_TLS_DIRECTORY *tls_dirs; /* array of TLS directories */
|
||||
LIST_ENTRY tls_links = { &tls_links, &tls_links };
|
||||
|
@ -581,28 +560,6 @@ static WINE_MODREF *find_fileid_module( const struct file_id *id )
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* find_so_module
|
||||
*
|
||||
* Find a module from its so file handle.
|
||||
* The loader_section must be locked while calling this function
|
||||
*/
|
||||
static WINE_MODREF *find_so_module( void *handle )
|
||||
{
|
||||
LIST_ENTRY *mark, *entry;
|
||||
|
||||
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||
{
|
||||
LDR_DATA_TABLE_ENTRY *mod = CONTAINING_RECORD( entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks );
|
||||
WINE_MODREF *wm = CONTAINING_RECORD( mod, WINE_MODREF, ldr );
|
||||
|
||||
if (wm->so_handle == handle) return wm;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* grow_module_deps
|
||||
*/
|
||||
|
@ -1323,85 +1280,6 @@ static void call_tls_callbacks( HMODULE module, UINT reason )
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/* The PT_LOAD segments are sorted in increasing order, and the first
|
||||
* starts at the beginning of the ELF file. By parsing the file, we can
|
||||
* find that first PT_LOAD segment, from which we can find the base
|
||||
* address it wanted, and knowing mapbase where the binary was actually
|
||||
* loaded, use them to work out the relocbase offset. */
|
||||
static BOOL get_relocbase(caddr_t mapbase, caddr_t *relocbase)
|
||||
{
|
||||
Elf_Half i;
|
||||
#ifdef _WIN64
|
||||
const Elf64_Ehdr *elf_header = (Elf64_Ehdr*) mapbase;
|
||||
#else
|
||||
const Elf32_Ehdr *elf_header = (Elf32_Ehdr*) mapbase;
|
||||
#endif
|
||||
const Elf_Phdr *prog_header = (const Elf_Phdr *)(mapbase + elf_header->e_phoff);
|
||||
|
||||
for (i = 0; i < elf_header->e_phnum; i++)
|
||||
{
|
||||
if (prog_header->p_type == PT_LOAD)
|
||||
{
|
||||
caddr_t desired_base = (caddr_t)((prog_header->p_vaddr / prog_header->p_align) * prog_header->p_align);
|
||||
*relocbase = (caddr_t) (mapbase - desired_base);
|
||||
return TRUE;
|
||||
}
|
||||
prog_header++;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
* call_constructors
|
||||
*/
|
||||
static void call_constructors( WINE_MODREF *wm )
|
||||
{
|
||||
#ifdef HAVE_DLINFO
|
||||
struct link_map *map;
|
||||
void (*init_func)(int, char **, char **) = NULL;
|
||||
void (**init_array)(int, char **, char **) = NULL;
|
||||
ULONG_PTR i, init_arraysz = 0;
|
||||
int argc;
|
||||
char **argv, **envp;
|
||||
#ifdef _WIN64
|
||||
const Elf64_Dyn *dyn;
|
||||
#else
|
||||
const Elf32_Dyn *dyn;
|
||||
#endif
|
||||
|
||||
if (dlinfo( wm->so_handle, RTLD_DI_LINKMAP, &map ) == -1) return;
|
||||
for (dyn = map->l_ld; dyn->d_tag; dyn++)
|
||||
{
|
||||
caddr_t relocbase = (caddr_t)map->l_addr;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/* On older FreeBSD versions, l_addr was the absolute load address, now it's the relocation offset. */
|
||||
if (!dlsym(RTLD_DEFAULT, "_rtld_version_laddr_offset"))
|
||||
if (!get_relocbase(map->l_addr, &relocbase)) return;
|
||||
#endif
|
||||
switch (dyn->d_tag)
|
||||
{
|
||||
case 0x60009990: init_array = (void *)(relocbase + dyn->d_un.d_val); break;
|
||||
case 0x60009991: init_arraysz = dyn->d_un.d_val; break;
|
||||
case 0x60009992: init_func = (void *)(relocbase + dyn->d_un.d_val); break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE( "%s: got init_func %p init_array %p %lu\n", debugstr_us( &wm->ldr.BaseDllName ),
|
||||
init_func, init_array, init_arraysz );
|
||||
|
||||
unix_funcs->get_main_args( &argc, &argv, &envp );
|
||||
|
||||
if (init_func) init_func( argc, argv, envp );
|
||||
|
||||
if (init_array)
|
||||
for (i = 0; i < init_arraysz / sizeof(*init_array); i++) init_array[i]( argc, argv, envp );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* MODULE_InitDLL
|
||||
*/
|
||||
|
@ -1417,7 +1295,8 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
|
|||
|
||||
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return STATUS_SUCCESS;
|
||||
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.DllBase, reason );
|
||||
if (wm->so_handle && reason == DLL_PROCESS_ATTACH) call_constructors( wm );
|
||||
if (wm->ldr.Flags & LDR_WINE_INTERNAL && reason == DLL_PROCESS_ATTACH)
|
||||
unix_funcs->init_builtin_dll( wm->ldr.DllBase );
|
||||
if (!entry) return STATUS_SUCCESS;
|
||||
|
||||
if (TRACE_ON(relay))
|
||||
|
@ -2070,30 +1949,13 @@ static NTSTATUS build_module( LPCWSTR load_path, const UNICODE_STRING *nt_name,
|
|||
static NTSTATUS build_so_dll_module( const WCHAR *load_path, const UNICODE_STRING *nt_name,
|
||||
void *module, DWORD flags, WINE_MODREF **pwm )
|
||||
{
|
||||
NTSTATUS status;
|
||||
pe_image_info_t image_info = { 0 };
|
||||
|
||||
image_info.image_flags = IMAGE_FLAGS_WineBuiltin;
|
||||
unix_funcs->virtual_create_builtin_view( module );
|
||||
return build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* load_builtin_callback
|
||||
*
|
||||
* Load a library in memory; callback function for wine_dll_register
|
||||
*/
|
||||
static void load_builtin_callback( void *module, const char *filename )
|
||||
{
|
||||
if (!module)
|
||||
{
|
||||
ERR("could not map image for %s\n", debugstr_us(builtin_load_info->filename) );
|
||||
builtin_load_info->status = STATUS_NO_MEMORY;
|
||||
return;
|
||||
}
|
||||
builtin_load_info->status = build_so_dll_module( builtin_load_info->load_path,
|
||||
builtin_load_info->filename, module,
|
||||
0, &builtin_load_info->wm );
|
||||
status = build_module( load_path, nt_name, &module, &image_info, NULL, flags, pwm );
|
||||
if (status && module) unix_funcs->unload_builtin_dll( module );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2481,7 +2343,7 @@ static inline char *prepend( char *buffer, const char *str, size_t len )
|
|||
* open_builtin_file
|
||||
*/
|
||||
static NTSTATUS open_builtin_file( char *name, WINE_MODREF **pwm, void **module,
|
||||
pe_image_info_t *image_info, struct file_id *id, char **so_name )
|
||||
pe_image_info_t *image_info, struct file_id *id )
|
||||
{
|
||||
ANSI_STRING strA;
|
||||
UNICODE_STRING nt_name;
|
||||
|
@ -2513,11 +2375,20 @@ static NTSTATUS open_builtin_file( char *name, WINE_MODREF **pwm, void **module,
|
|||
{
|
||||
if (check_library_arch( fd ))
|
||||
{
|
||||
if ((*so_name = RtlAllocateHeap( GetProcessHeap(), 0, strlen(name) + 1 )))
|
||||
strcpy( *so_name, name );
|
||||
NtUnmapViewOfSection( NtCurrentProcess(), *module );
|
||||
*module = NULL;
|
||||
status = STATUS_SUCCESS;
|
||||
if (!unix_funcs->load_builtin_dll( name, module ))
|
||||
{
|
||||
memset( id, 0, sizeof(*id) );
|
||||
memset( image_info, 0, sizeof(*image_info) );
|
||||
image_info->image_flags = IMAGE_FLAGS_WineBuiltin;
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR( "failed to load .so lib %s\n", debugstr_a(name) );
|
||||
status = STATUS_PROCEDURE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
else status = STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
|
||||
close( fd );
|
||||
|
@ -2530,7 +2401,7 @@ static NTSTATUS open_builtin_file( char *name, WINE_MODREF **pwm, void **module,
|
|||
* find_builtin_dll
|
||||
*/
|
||||
static NTSTATUS find_builtin_dll( const WCHAR *name, WINE_MODREF **pwm, void **module,
|
||||
pe_image_info_t *image_info, struct file_id *id, char **so_name )
|
||||
pe_image_info_t *image_info, struct file_id *id )
|
||||
{
|
||||
unsigned int i, pos, len, namelen, maxlen = 0;
|
||||
char *ptr, *file;
|
||||
|
@ -2567,7 +2438,7 @@ static NTSTATUS find_builtin_dll( const WCHAR *name, WINE_MODREF **pwm, void **m
|
|||
ptr = prepend( ptr, ptr, namelen );
|
||||
ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 );
|
||||
ptr = prepend( ptr, build_dir, strlen(build_dir) );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, id, so_name );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, id );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
|
||||
/* now as a program */
|
||||
|
@ -2578,7 +2449,7 @@ static NTSTATUS find_builtin_dll( const WCHAR *name, WINE_MODREF **pwm, void **m
|
|||
ptr = prepend( ptr, ptr, namelen );
|
||||
ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 );
|
||||
ptr = prepend( ptr, build_dir, strlen(build_dir) );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, id, so_name );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, id );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
||||
|
@ -2586,7 +2457,7 @@ static NTSTATUS find_builtin_dll( const WCHAR *name, WINE_MODREF **pwm, void **m
|
|||
{
|
||||
file[pos + len + 1] = 0;
|
||||
ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, id, so_name );
|
||||
status = open_builtin_file( ptr, pwm, module, image_info, id );
|
||||
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
|
||||
else if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
@ -2604,108 +2475,33 @@ done:
|
|||
* load_so_dll
|
||||
*/
|
||||
static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
|
||||
const char *so_name, DWORD flags, WINE_MODREF** pwm )
|
||||
DWORD flags, WINE_MODREF **pwm )
|
||||
{
|
||||
static const WCHAR soW[] = {'.','s','o',0};
|
||||
DWORD len;
|
||||
void *handle;
|
||||
const IMAGE_NT_HEADERS *nt;
|
||||
struct builtin_load_info info, *prev_info;
|
||||
ANSI_STRING unix_name;
|
||||
void *module;
|
||||
NTSTATUS status;
|
||||
WINE_MODREF *wm;
|
||||
UNICODE_STRING win_name = *nt_name;
|
||||
|
||||
unix_name.Buffer = NULL;
|
||||
info.load_path = load_path;
|
||||
info.filename = &win_name;
|
||||
info.status = STATUS_SUCCESS;
|
||||
info.wm = NULL;
|
||||
|
||||
if (!so_name)
|
||||
TRACE( "trying %s as so lib\n", debugstr_us(&win_name) );
|
||||
if (unix_funcs->load_so_dll( &win_name, &module ))
|
||||
{
|
||||
if (wine_nt_to_unix_file_name( nt_name, &unix_name, FILE_OPEN, FALSE ))
|
||||
return STATUS_DLL_NOT_FOUND;
|
||||
|
||||
/* remove .so extension from Windows name */
|
||||
len = nt_name->Length / sizeof(WCHAR);
|
||||
if (len > 3 && !wcsicmp( nt_name->Buffer + len - 3, soW )) win_name.Length -= 3 * sizeof(WCHAR);
|
||||
WARN( "failed to load .so lib %s\n", debugstr_us(nt_name) );
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
|
||||
TRACE( "loading %s from so lib %s\n", debugstr_us(&win_name),
|
||||
debugstr_a( so_name ? so_name : unix_name.Buffer ));
|
||||
|
||||
prev_info = builtin_load_info;
|
||||
builtin_load_info = &info;
|
||||
handle = dlopen( so_name ? so_name : unix_name.Buffer, RTLD_NOW );
|
||||
builtin_load_info = prev_info;
|
||||
RtlFreeHeap( GetProcessHeap(), 0, unix_name.Buffer );
|
||||
|
||||
if (!handle)
|
||||
if ((wm = get_modref( module ))) /* already loaded */
|
||||
{
|
||||
if (so_name)
|
||||
{
|
||||
ERR("failed to load .so lib %s: %s\n", debugstr_a(so_name), dlerror() );
|
||||
info.status = STATUS_PROCEDURE_NOT_FOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN( "failed to load .so lib %s: %s\n", debugstr_us(nt_name), dlerror() );
|
||||
info.status = STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
}
|
||||
|
||||
if (info.status != STATUS_SUCCESS) goto failed;
|
||||
|
||||
if (!info.wm && (nt = dlsym( handle, "__wine_spec_nt_header" )))
|
||||
{
|
||||
HMODULE module = (HMODULE)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff);
|
||||
if ((info.wm = get_modref( module ))) /* already loaded */
|
||||
{
|
||||
TRACE( "Found %s at %p for builtin %s\n",
|
||||
debugstr_w(info.wm->ldr.FullDllName.Buffer), info.wm->ldr.DllBase,
|
||||
debugstr_us(nt_name) );
|
||||
if (info.wm->ldr.LoadCount != -1) info.wm->ldr.LoadCount++;
|
||||
dlclose( handle );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((info.status = unix_funcs->map_so_dll( nt, module ))) goto failed;
|
||||
if ((info.status = build_so_dll_module( load_path, &win_name, module, flags, &info.wm )))
|
||||
goto failed;
|
||||
TRACE_(loaddll)( "Loaded %s at %p: builtin\n",
|
||||
debugstr_w(info.wm->ldr.FullDllName.Buffer), info.wm->ldr.DllBase );
|
||||
info.wm->ldr.LoadCount = 1;
|
||||
info.wm->so_handle = handle;
|
||||
}
|
||||
}
|
||||
else if (!info.wm)
|
||||
{
|
||||
/* The constructor wasn't called, this means the .so is already
|
||||
* loaded under a different name. Try to find the wm for it. */
|
||||
|
||||
if (!(info.wm = find_so_module( handle )))
|
||||
{
|
||||
info.status = STATUS_INVALID_IMAGE_FORMAT;
|
||||
goto failed;
|
||||
}
|
||||
TRACE( "Found %s at %p for builtin %s\n",
|
||||
debugstr_w(info.wm->ldr.FullDllName.Buffer), info.wm->ldr.DllBase,
|
||||
debugstr_us(nt_name) );
|
||||
if (info.wm->ldr.LoadCount != -1) info.wm->ldr.LoadCount++;
|
||||
dlclose( handle ); /* release the libdl refcount */
|
||||
debugstr_w(wm->ldr.FullDllName.Buffer), wm->ldr.DllBase, debugstr_us(nt_name) );
|
||||
if (wm->ldr.LoadCount != -1) wm->ldr.LoadCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_(loaddll)( "Loaded %s at %p: builtin\n", debugstr_w(info.wm->ldr.FullDllName.Buffer), info.wm->ldr.DllBase );
|
||||
info.wm->ldr.LoadCount = 1;
|
||||
info.wm->so_handle = handle;
|
||||
if ((status = build_so_dll_module( load_path, &win_name, module, flags, &wm ))) return status;
|
||||
TRACE_(loaddll)( "Loaded %s at %p: builtin\n", debugstr_us(nt_name), module );
|
||||
}
|
||||
|
||||
*pwm = info.wm;
|
||||
*pwm = wm;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
failed:
|
||||
if (handle) dlclose( handle );
|
||||
return info.status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2720,7 +2516,6 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, const UNICODE_STRING *nt_na
|
|||
void *module = NULL;
|
||||
pe_image_info_t image_info;
|
||||
struct file_id id;
|
||||
char *so_name;
|
||||
|
||||
/* Fix the name in case we have a full path and extension */
|
||||
name = nt_name->Buffer;
|
||||
|
@ -2731,7 +2526,7 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, const UNICODE_STRING *nt_na
|
|||
|
||||
if (!module_ptr) module_ptr = &module;
|
||||
|
||||
status = find_builtin_dll( name, pwm, module_ptr, &image_info, &id, &so_name );
|
||||
status = find_builtin_dll( name, pwm, module_ptr, &image_info, &id );
|
||||
if (status) return status;
|
||||
|
||||
if (*pwm)
|
||||
|
@ -2743,14 +2538,9 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, const UNICODE_STRING *nt_na
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (*module_ptr)
|
||||
{
|
||||
TRACE( "loading %s from PE builtin %s\n", debugstr_w(name), debugstr_us(nt_name) );
|
||||
return load_native_dll( load_path, nt_name, module_ptr, &image_info, &id, flags, pwm );
|
||||
}
|
||||
|
||||
status = load_so_dll( load_path, nt_name, so_name, flags, pwm );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, so_name );
|
||||
TRACE( "loading %s from %s\n", debugstr_w(name), debugstr_us(nt_name) );
|
||||
status = build_module( load_path, nt_name, module_ptr, &image_info, &id, flags, pwm );
|
||||
if (status && *module_ptr) unix_funcs->unload_builtin_dll( *module_ptr );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -3030,7 +2820,7 @@ static NTSTATUS load_dll( const WCHAR *load_path, const WCHAR *libname, const WC
|
|||
case LO_BUILTIN:
|
||||
case LO_BUILTIN_NATIVE:
|
||||
case LO_DEFAULT:
|
||||
if (!load_so_dll( load_path, &nt_name, NULL, flags, pwm )) nts = STATUS_SUCCESS;
|
||||
if (!load_so_dll( load_path, &nt_name, flags, pwm )) nts = STATUS_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
nts = STATUS_DLL_NOT_FOUND;
|
||||
|
@ -3628,7 +3418,7 @@ static void free_modref( WINE_MODREF *wm )
|
|||
|
||||
free_tls_slot( &wm->ldr );
|
||||
RtlReleaseActivationContext( wm->ldr.ActivationContext );
|
||||
if (wm->so_handle) dlclose( wm->so_handle );
|
||||
unix_funcs->unload_builtin_dll( wm->ldr.DllBase );
|
||||
NtUnmapViewOfSection( NtCurrentProcess(), wm->ldr.DllBase );
|
||||
if (cached_modref == wm) cached_modref = NULL;
|
||||
RtlFreeUnicodeString( &wm->ldr.FullDllName );
|
||||
|
@ -3845,7 +3635,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow
|
|||
attach_implicitly_loaded_dlls( context );
|
||||
unix_funcs->virtual_release_address_space();
|
||||
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.DllBase, DLL_PROCESS_ATTACH );
|
||||
if (wm->so_handle) call_constructors( wm );
|
||||
if (wm->ldr.Flags & LDR_WINE_INTERNAL) unix_funcs->init_builtin_dll( wm->ldr.DllBase );
|
||||
if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
|
||||
}
|
||||
else
|
||||
|
@ -4351,8 +4141,6 @@ void __wine_process_init(void)
|
|||
status = build_so_dll_module( params->DllPath.Buffer, &nt_name, ntdll_module, 0, &wm );
|
||||
assert( !status );
|
||||
|
||||
wine_dll_set_callback( load_builtin_callback );
|
||||
|
||||
RtlInitUnicodeString( &nt_name, kernel32W );
|
||||
if ((status = load_builtin_dll( params->DllPath.Buffer, &nt_name, NULL, 0, &wm )) != STATUS_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -74,10 +74,6 @@ extern void init_user_process_params( SIZE_T data_size ) DECLSPEC_HIDDEN;
|
|||
extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS status ) DECLSPEC_HIDDEN;
|
||||
|
||||
extern int __wine_main_argc;
|
||||
extern char **__wine_main_argv;
|
||||
extern WCHAR **__wine_main_wargv;
|
||||
|
||||
/* server support */
|
||||
extern const char *build_dir DECLSPEC_HIDDEN;
|
||||
extern const char *data_dir DECLSPEC_HIDDEN;
|
||||
|
@ -107,9 +103,6 @@ extern const struct unix_funcs *unix_funcs DECLSPEC_HIDDEN;
|
|||
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
|
||||
extern void init_directories(void) DECLSPEC_HIDDEN;
|
||||
|
||||
/* virtual memory */
|
||||
extern void virtual_fill_image_information( const pe_image_info_t *pe_info,
|
||||
SECTION_IMAGE_INFORMATION *info ) DECLSPEC_HIDDEN;
|
||||
extern struct _KUSER_SHARED_DATA *user_shared_data DECLSPEC_HIDDEN;
|
||||
|
||||
/* locale */
|
||||
|
|
|
@ -67,9 +67,9 @@ extern WCHAR **__wine_main_wargv;
|
|||
|
||||
USHORT *uctable = NULL, *lctable = NULL;
|
||||
|
||||
static int main_argc;
|
||||
static char **main_argv;
|
||||
static char **main_envp;
|
||||
int main_argc = 0;
|
||||
char **main_argv = NULL;
|
||||
char **main_envp = NULL;
|
||||
static WCHAR **main_wargv;
|
||||
|
||||
static CPTABLEINFO unix_table;
|
||||
|
@ -802,19 +802,6 @@ void init_environment( int argc, char *argv[], char *envp[] )
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_main_args
|
||||
*
|
||||
* Return the initial arguments.
|
||||
*/
|
||||
void CDECL get_main_args( int *argc, char **argv[], char **envp[] )
|
||||
{
|
||||
*argc = main_argc;
|
||||
*argv = main_argv;
|
||||
*envp = main_envp;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* get_initial_environment
|
||||
*
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#ifdef HAVE_LINK_H
|
||||
# include <link.h>
|
||||
#endif
|
||||
#ifdef HAVE_PWD_H
|
||||
# include <pwd.h>
|
||||
#endif
|
||||
|
@ -82,10 +85,11 @@
|
|||
#include "winnls.h"
|
||||
#include "winternl.h"
|
||||
#include "unix_private.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/library.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(module);
|
||||
|
||||
extern IMAGE_NT_HEADERS __wine_spec_nt_header;
|
||||
|
||||
|
@ -121,6 +125,26 @@ static SIZE_T dll_path_maxlen;
|
|||
const char *data_dir = NULL;
|
||||
const char *build_dir = NULL;
|
||||
const char *config_dir = NULL;
|
||||
HMODULE ntdll_module = NULL;
|
||||
|
||||
struct builtin_module
|
||||
{
|
||||
struct list entry;
|
||||
void *handle;
|
||||
void *module;
|
||||
};
|
||||
|
||||
static struct list builtin_modules = LIST_INIT( builtin_modules );
|
||||
|
||||
static NTSTATUS add_builtin_module( void *module, void *handle )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
if (!(builtin = malloc( sizeof(*builtin) ))) return STATUS_NO_MEMORY;
|
||||
builtin->handle = handle;
|
||||
builtin->module = module;
|
||||
list_add_tail( &builtin_modules, &builtin->entry );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void *get_rva( const IMAGE_NT_HEADERS *nt, ULONG_PTR addr )
|
||||
{
|
||||
|
@ -569,7 +593,7 @@ void start_server( BOOL debug )
|
|||
*
|
||||
* Map a builtin dll in memory and fixup RVAs.
|
||||
*/
|
||||
static NTSTATUS CDECL map_so_dll( const IMAGE_NT_HEADERS *nt_descr, HMODULE module )
|
||||
static NTSTATUS map_so_dll( const IMAGE_NT_HEADERS *nt_descr, HMODULE module )
|
||||
{
|
||||
static const char builtin_signature[32] = "Wine builtin DLL";
|
||||
IMAGE_DATA_DIRECTORY *dir;
|
||||
|
@ -762,7 +786,7 @@ static ULONG_PTR find_pe_export( HMODULE module, const IMAGE_EXPORT_DIRECTORY *e
|
|||
return find_named_export( module, exports, (char *)name->Name );
|
||||
}
|
||||
|
||||
static void fixup_ntdll_imports( const IMAGE_NT_HEADERS *nt, HMODULE ntdll_module )
|
||||
static void fixup_ntdll_imports( const IMAGE_NT_HEADERS *nt )
|
||||
{
|
||||
const IMAGE_EXPORT_DIRECTORY *ntdll_exports = get_export_dir( ntdll_module );
|
||||
const IMAGE_IMPORT_DESCRIPTOR *descr;
|
||||
|
@ -813,29 +837,224 @@ static void fixup_ntdll_imports( const IMAGE_NT_HEADERS *nt, HMODULE ntdll_modul
|
|||
#undef GET_FUNC
|
||||
}
|
||||
|
||||
|
||||
static void *callback_module;
|
||||
|
||||
/***********************************************************************
|
||||
* load_builtin_callback
|
||||
*
|
||||
* Load a library in memory; callback function for wine_dll_register
|
||||
*/
|
||||
static void load_builtin_callback( void *module, const char *filename )
|
||||
{
|
||||
callback_module = module;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* dlopen_dll
|
||||
*/
|
||||
static NTSTATUS dlopen_dll( const char *so_name, void **ret_module )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
void *module, *handle;
|
||||
const IMAGE_NT_HEADERS *nt;
|
||||
|
||||
callback_module = (void *)1;
|
||||
handle = dlopen( so_name, RTLD_NOW );
|
||||
if (!handle)
|
||||
{
|
||||
WARN( "failed to load .so lib %s: %s\n", debugstr_a(so_name), dlerror() );
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
if (callback_module != (void *)1) /* callback was called */
|
||||
{
|
||||
if (!callback_module) return STATUS_NO_MEMORY;
|
||||
WARN( "got old-style builtin library %s, constructors won't work\n", debugstr_a(so_name) );
|
||||
module = callback_module;
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
if (builtin->module == module) goto already_loaded;
|
||||
}
|
||||
else if ((nt = dlsym( handle, "__wine_spec_nt_header" )))
|
||||
{
|
||||
module = (HMODULE)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff);
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
if (builtin->module == module) goto already_loaded;
|
||||
if (map_so_dll( nt, module ))
|
||||
{
|
||||
dlclose( handle );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
else /* already loaded .so */
|
||||
{
|
||||
WARN( "%s already loaded?\n", debugstr_a(so_name));
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
if (builtin->handle == handle) goto already_loaded;
|
||||
return STATUS_INVALID_IMAGE_FORMAT;
|
||||
}
|
||||
|
||||
if (add_builtin_module( module, handle ))
|
||||
{
|
||||
dlclose( handle );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
virtual_create_builtin_view( module );
|
||||
*ret_module = module;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
already_loaded:
|
||||
*ret_module = builtin->module;
|
||||
dlclose( handle );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* load_so_dll
|
||||
*/
|
||||
static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
|
||||
{
|
||||
static const WCHAR soW[] = {'.','s','o',0};
|
||||
ANSI_STRING unix_name;
|
||||
NTSTATUS status;
|
||||
DWORD len;
|
||||
|
||||
if (nt_to_unix_file_name( nt_name, &unix_name, FILE_OPEN, FALSE )) return STATUS_DLL_NOT_FOUND;
|
||||
|
||||
/* remove .so extension from Windows name */
|
||||
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.Buffer, module );
|
||||
RtlFreeAnsiString( &unix_name );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* load_builtin_dll
|
||||
*/
|
||||
static NTSTATUS CDECL load_builtin_dll( const char *so_name, void **module )
|
||||
{
|
||||
return dlopen_dll( so_name, module );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* unload_builtin_dll
|
||||
*/
|
||||
static NTSTATUS CDECL unload_builtin_dll( void *module )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
{
|
||||
if (builtin->module != module) continue;
|
||||
list_remove( &builtin->entry );
|
||||
if (builtin->handle) dlclose( builtin->handle );
|
||||
free( builtin );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/* The PT_LOAD segments are sorted in increasing order, and the first
|
||||
* starts at the beginning of the ELF file. By parsing the file, we can
|
||||
* find that first PT_LOAD segment, from which we can find the base
|
||||
* address it wanted, and knowing mapbase where the binary was actually
|
||||
* loaded, use them to work out the relocbase offset. */
|
||||
static BOOL get_relocbase(caddr_t mapbase, caddr_t *relocbase)
|
||||
{
|
||||
Elf_Half i;
|
||||
#ifdef _WIN64
|
||||
const Elf64_Ehdr *elf_header = (Elf64_Ehdr*) mapbase;
|
||||
#else
|
||||
const Elf32_Ehdr *elf_header = (Elf32_Ehdr*) mapbase;
|
||||
#endif
|
||||
const Elf_Phdr *prog_header = (const Elf_Phdr *)(mapbase + elf_header->e_phoff);
|
||||
|
||||
for (i = 0; i < elf_header->e_phnum; i++)
|
||||
{
|
||||
if (prog_header->p_type == PT_LOAD)
|
||||
{
|
||||
caddr_t desired_base = (caddr_t)((prog_header->p_vaddr / prog_header->p_align) * prog_header->p_align);
|
||||
*relocbase = (caddr_t) (mapbase - desired_base);
|
||||
return TRUE;
|
||||
}
|
||||
prog_header++;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
* init_builtin_dll
|
||||
*/
|
||||
static void CDECL init_builtin_dll( void *module )
|
||||
{
|
||||
#ifdef HAVE_DLINFO
|
||||
struct builtin_module *builtin;
|
||||
struct link_map *map;
|
||||
void (*init_func)(int, char **, char **) = NULL;
|
||||
void (**init_array)(int, char **, char **) = NULL;
|
||||
ULONG_PTR i, init_arraysz = 0;
|
||||
#ifdef _WIN64
|
||||
const Elf64_Dyn *dyn;
|
||||
#else
|
||||
const Elf32_Dyn *dyn;
|
||||
#endif
|
||||
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
{
|
||||
if (builtin->module != module) continue;
|
||||
if (!builtin->handle) break;
|
||||
if (!dlinfo( builtin->handle, RTLD_DI_LINKMAP, &map )) goto found;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
found:
|
||||
for (dyn = map->l_ld; dyn->d_tag; dyn++)
|
||||
{
|
||||
caddr_t relocbase = (caddr_t)map->l_addr;
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/* On older FreeBSD versions, l_addr was the absolute load address, now it's the relocation offset. */
|
||||
if (!dlsym(RTLD_DEFAULT, "_rtld_version_laddr_offset"))
|
||||
if (!get_relocbase(map->l_addr, &relocbase)) return;
|
||||
#endif
|
||||
switch (dyn->d_tag)
|
||||
{
|
||||
case 0x60009990: init_array = (void *)(relocbase + dyn->d_un.d_val); break;
|
||||
case 0x60009991: init_arraysz = dyn->d_un.d_val; break;
|
||||
case 0x60009992: init_func = (void *)(relocbase + dyn->d_un.d_val); break;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE( "%p: got init_func %p init_array %p %lu\n", module, init_func, init_array, init_arraysz );
|
||||
|
||||
if (init_func) init_func( main_argc, main_argv, main_envp );
|
||||
|
||||
if (init_array)
|
||||
for (i = 0; i < init_arraysz / sizeof(*init_array); i++)
|
||||
init_array[i]( main_argc, main_argv, main_envp );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* load_ntdll
|
||||
*/
|
||||
static HMODULE load_ntdll(void)
|
||||
{
|
||||
const IMAGE_NT_HEADERS *nt;
|
||||
HMODULE module;
|
||||
Dl_info info;
|
||||
char *name;
|
||||
void *handle;
|
||||
void *module;
|
||||
char *name = build_path( dll_dir, "ntdll.dll.so" );
|
||||
NTSTATUS status = dlopen_dll( name, &module );
|
||||
|
||||
name = build_path( dll_dir, "ntdll.dll.so" );
|
||||
if (!dladdr( load_ntdll, &info )) fatal_error( "cannot get path to ntdll.so\n" );
|
||||
name = malloc( strlen(info.dli_fname) + 5 );
|
||||
strcpy( name, info.dli_fname );
|
||||
strcpy( name + strlen(info.dli_fname) - 3, ".dll.so" );
|
||||
if (!(handle = dlopen( name, RTLD_NOW ))) fatal_error( "failed to load %s: %s\n", name, dlerror() );
|
||||
if (!(nt = dlsym( handle, "__wine_spec_nt_header" )))
|
||||
fatal_error( "NT header not found in %s (too old?)\n", name );
|
||||
dll_dir = realpath_dirname( name );
|
||||
if (status) fatal_error( "failed to load %s error %x\n", name, status );
|
||||
free( name );
|
||||
module = (HMODULE)((nt->OptionalHeader.ImageBase + 0xffff) & ~0xffff);
|
||||
map_so_dll( nt, module );
|
||||
return module;
|
||||
}
|
||||
|
||||
|
@ -1000,7 +1219,6 @@ static struct unix_funcs unix_funcs =
|
|||
fast_RtlSleepConditionVariableSRW,
|
||||
fast_RtlSleepConditionVariableCS,
|
||||
fast_RtlWakeConditionVariable,
|
||||
get_main_args,
|
||||
get_initial_environment,
|
||||
get_initial_directory,
|
||||
get_paths,
|
||||
|
@ -1010,10 +1228,8 @@ static struct unix_funcs unix_funcs =
|
|||
get_version,
|
||||
get_build_id,
|
||||
get_host_version,
|
||||
map_so_dll,
|
||||
virtual_map_section,
|
||||
virtual_get_system_info,
|
||||
virtual_create_builtin_view,
|
||||
virtual_alloc_thread_stack,
|
||||
virtual_locked_recvmsg,
|
||||
virtual_release_address_space,
|
||||
|
@ -1031,6 +1247,10 @@ static struct unix_funcs unix_funcs =
|
|||
nt_to_unix_file_name,
|
||||
unix_to_nt_file_name,
|
||||
set_show_dot_files,
|
||||
load_so_dll,
|
||||
load_builtin_dll,
|
||||
unload_builtin_dll,
|
||||
init_builtin_dll,
|
||||
__wine_dbg_get_channel_flags,
|
||||
__wine_dbg_strdup,
|
||||
__wine_dbg_output,
|
||||
|
@ -1266,8 +1486,6 @@ static void check_command_line( int argc, char *argv[] )
|
|||
*/
|
||||
void __wine_main( int argc, char *argv[], char *envp[] )
|
||||
{
|
||||
HMODULE module;
|
||||
|
||||
init_paths( argc, argv, envp );
|
||||
|
||||
if (!getenv( "WINELOADERNOEXEC" )) /* first time around */
|
||||
|
@ -1294,10 +1512,11 @@ void __wine_main( int argc, char *argv[], char *envp[] )
|
|||
|
||||
virtual_init();
|
||||
|
||||
module = load_ntdll();
|
||||
fixup_ntdll_imports( &__wine_spec_nt_header, module );
|
||||
ntdll_module = load_ntdll();
|
||||
fixup_ntdll_imports( &__wine_spec_nt_header );
|
||||
|
||||
init_environment( argc, argv, envp );
|
||||
wine_dll_set_callback( load_builtin_callback );
|
||||
|
||||
#ifdef __APPLE__
|
||||
apple_main_thread();
|
||||
|
@ -1329,9 +1548,11 @@ NTSTATUS __cdecl __wine_init_unix_lib( HMODULE module, const void *ptr_in, void
|
|||
#endif
|
||||
init_paths( __wine_main_argc, __wine_main_argv, envp );
|
||||
|
||||
ntdll_module = module;
|
||||
map_so_dll( nt, module );
|
||||
fixup_ntdll_imports( &__wine_spec_nt_header, module );
|
||||
fixup_ntdll_imports( &__wine_spec_nt_header );
|
||||
init_environment( __wine_main_argc, __wine_main_argv, envp );
|
||||
wine_dll_set_callback( load_builtin_callback );
|
||||
*(struct unix_funcs **)ptr_out = &unix_funcs;
|
||||
wine_mmap_enum_reserved_areas( add_area, NULL, 0 );
|
||||
return STATUS_SUCCESS;
|
||||
|
|
|
@ -104,6 +104,7 @@ TEB * CDECL init_threading( int *nb_threads_ptr, struct ldt_copy **ldt_copy, SIZ
|
|||
server_init_process();
|
||||
info_size = server_init_thread( teb->Peb, suspend );
|
||||
virtual_map_user_shared_data();
|
||||
virtual_create_builtin_view( ntdll_module );
|
||||
init_files();
|
||||
NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 );
|
||||
|
||||
|
|
|
@ -95,7 +95,6 @@ void CDECL mmap_remove_reserved_area( void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
|
|||
int CDECL mmap_is_in_reserved_area( void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
|
||||
int CDECL mmap_enum_reserved_areas( int (CDECL *enum_func)(void *base, SIZE_T size, void *arg), void *arg,
|
||||
int top_down ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_main_args( int *argc, char **argv[], char **envp[] ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_initial_directory( UNICODE_STRING *dir ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL get_unix_codepage( CPTABLEINFO *table ) DECLSPEC_HIDDEN;
|
||||
|
@ -104,7 +103,6 @@ extern NTSTATUS CDECL virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsig
|
|||
const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, ULONG alloc_type,
|
||||
ULONG protect, pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL virtual_create_builtin_view( void *module ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SIZE_T commit_size, SIZE_T *pthread_size ) DECLSPEC_HIDDEN;
|
||||
extern ssize_t CDECL virtual_locked_recvmsg( int fd, struct msghdr *hdr, int flags ) DECLSPEC_HIDDEN;
|
||||
extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN;
|
||||
|
@ -132,8 +130,12 @@ extern void CDECL set_show_dot_files( BOOL enable ) DECLSPEC_HIDDEN;
|
|||
extern const char *data_dir DECLSPEC_HIDDEN;
|
||||
extern const char *build_dir DECLSPEC_HIDDEN;
|
||||
extern const char *config_dir DECLSPEC_HIDDEN;
|
||||
extern HMODULE ntdll_module DECLSPEC_HIDDEN;
|
||||
extern USHORT *uctable DECLSPEC_HIDDEN;
|
||||
extern USHORT *lctable DECLSPEC_HIDDEN;
|
||||
extern int main_argc DECLSPEC_HIDDEN;
|
||||
extern char **main_argv DECLSPEC_HIDDEN;
|
||||
extern char **main_envp DECLSPEC_HIDDEN;
|
||||
extern unsigned int server_cpus DECLSPEC_HIDDEN;
|
||||
extern BOOL is_wow64 DECLSPEC_HIDDEN;
|
||||
extern HANDLE keyed_event DECLSPEC_HIDDEN;
|
||||
|
@ -181,6 +183,7 @@ extern NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct o
|
|||
|
||||
extern void virtual_init(void) DECLSPEC_HIDDEN;
|
||||
extern ULONG_PTR get_system_affinity_mask(void) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_create_builtin_view( void *module ) DECLSPEC_HIDDEN;
|
||||
extern TEB *virtual_alloc_first_teb(void) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_alloc_teb( TEB **ret_teb ) DECLSPEC_HIDDEN;
|
||||
extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -2498,11 +2498,12 @@ void CDECL virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info )
|
|||
/***********************************************************************
|
||||
* virtual_create_builtin_view
|
||||
*/
|
||||
NTSTATUS CDECL virtual_create_builtin_view( void *module )
|
||||
NTSTATUS virtual_create_builtin_view( void *module )
|
||||
{
|
||||
NTSTATUS status;
|
||||
sigset_t sigset;
|
||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module );
|
||||
IMAGE_DOS_HEADER *dos = module;
|
||||
IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
|
||||
SIZE_T size = nt->OptionalHeader.SizeOfImage;
|
||||
IMAGE_SECTION_HEADER *sec;
|
||||
struct file_view *view;
|
||||
|
@ -2511,7 +2512,7 @@ NTSTATUS CDECL virtual_create_builtin_view( void *module )
|
|||
|
||||
size = ROUND_SIZE( module, size );
|
||||
base = ROUND_ADDR( module, page_mask );
|
||||
server_enter_uninterrupted_section( &csVirtual, &sigset );
|
||||
if (use_locks) server_enter_uninterrupted_section( &csVirtual, &sigset );
|
||||
status = create_view( &view, base, size, SEC_IMAGE | SEC_FILE | VPROT_SYSTEM |
|
||||
VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC );
|
||||
if (!status)
|
||||
|
@ -2533,7 +2534,7 @@ NTSTATUS CDECL virtual_create_builtin_view( void *module )
|
|||
}
|
||||
VIRTUAL_DEBUG_DUMP_VIEW( view );
|
||||
}
|
||||
server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||
if (use_locks) server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
|||
struct msghdr;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 57
|
||||
#define NTDLL_UNIXLIB_VERSION 58
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -277,7 +277,6 @@ struct unix_funcs
|
|||
NTSTATUS (CDECL *fast_RtlWakeConditionVariable)( RTL_CONDITION_VARIABLE *variable, int count );
|
||||
|
||||
/* environment functions */
|
||||
void (CDECL *get_main_args)( int *argc, char **argv[], char **envp[] );
|
||||
NTSTATUS (CDECL *get_initial_environment)( WCHAR **wargv[], WCHAR *env, SIZE_T *size );
|
||||
void (CDECL *get_initial_directory)( UNICODE_STRING *dir );
|
||||
void (CDECL *get_paths)( const char **builddir, const char **datadir, const char **configdir );
|
||||
|
@ -289,12 +288,10 @@ struct unix_funcs
|
|||
void (CDECL *get_host_version)( const char **sysname, const char **release );
|
||||
|
||||
/* virtual memory functions */
|
||||
NTSTATUS (CDECL *map_so_dll)( const IMAGE_NT_HEADERS *nt_descr, HMODULE module );
|
||||
NTSTATUS (CDECL *virtual_map_section)( HANDLE handle, PVOID *addr_ptr, unsigned short zero_bits_64, SIZE_T commit_size,
|
||||
const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, ULONG alloc_type,
|
||||
ULONG protect, pe_image_info_t *image_info );
|
||||
void (CDECL *virtual_get_system_info)( SYSTEM_BASIC_INFORMATION *info );
|
||||
NTSTATUS (CDECL *virtual_create_builtin_view)( void *module );
|
||||
NTSTATUS (CDECL *virtual_alloc_thread_stack)( INITIAL_TEB *stack, SIZE_T reserve_size, SIZE_T commit_size, SIZE_T *pthread_size );
|
||||
ssize_t (CDECL *virtual_locked_recvmsg)( int fd, struct msghdr *hdr, int flags );
|
||||
void (CDECL *virtual_release_address_space)(void);
|
||||
|
@ -323,6 +320,12 @@ struct unix_funcs
|
|||
NTSTATUS (CDECL *unix_to_nt_file_name)( const ANSI_STRING *name, UNICODE_STRING *nt );
|
||||
void (CDECL *set_show_dot_files)( BOOL enable );
|
||||
|
||||
/* loader functions */
|
||||
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module );
|
||||
NTSTATUS (CDECL *load_builtin_dll)( const char *so_name, void **module );
|
||||
NTSTATUS (CDECL *unload_builtin_dll)( void *module );
|
||||
void (CDECL *init_builtin_dll)( void *module );
|
||||
|
||||
/* debugging functions */
|
||||
unsigned char (CDECL *dbg_get_channel_flags)( struct __wine_debug_channel *channel );
|
||||
const char * (CDECL *dbg_strdup)( const char *str );
|
||||
|
|
|
@ -201,39 +201,6 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* virtual_fill_image_information
|
||||
*
|
||||
* Helper for NtQuerySection.
|
||||
*/
|
||||
void virtual_fill_image_information( const pe_image_info_t *pe_info, SECTION_IMAGE_INFORMATION *info )
|
||||
{
|
||||
info->TransferAddress = wine_server_get_ptr( pe_info->entry_point );
|
||||
info->ZeroBits = pe_info->zerobits;
|
||||
info->MaximumStackSize = pe_info->stack_size;
|
||||
info->CommittedStackSize = pe_info->stack_commit;
|
||||
info->SubSystemType = pe_info->subsystem;
|
||||
info->SubsystemVersionLow = pe_info->subsystem_low;
|
||||
info->SubsystemVersionHigh = pe_info->subsystem_high;
|
||||
info->GpValue = pe_info->gp;
|
||||
info->ImageCharacteristics = pe_info->image_charact;
|
||||
info->DllCharacteristics = pe_info->dll_charact;
|
||||
info->Machine = pe_info->machine;
|
||||
info->ImageContainsCode = pe_info->contains_code;
|
||||
info->u.ImageFlags = pe_info->image_flags & ~(IMAGE_FLAGS_WineBuiltin|IMAGE_FLAGS_WineFakeDll);
|
||||
info->LoaderFlags = pe_info->loader_flags;
|
||||
info->ImageFileSize = pe_info->file_size;
|
||||
info->CheckSum = pe_info->checksum;
|
||||
#ifndef _WIN64 /* don't return 64-bit values to 32-bit processes */
|
||||
if (pe_info->machine == IMAGE_FILE_MACHINE_AMD64 || pe_info->machine == IMAGE_FILE_MACHINE_ARM64)
|
||||
{
|
||||
info->TransferAddress = (void *)0x81231234; /* sic */
|
||||
info->MaximumStackSize = 0x100000;
|
||||
info->CommittedStackSize = 0x10000;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtQuerySection (NTDLL.@)
|
||||
* ZwQuerySection (NTDLL.@)
|
||||
|
|
Loading…
Reference in New Issue