ntdll: Move the builtin dll list to virtual.c.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
100b81e8a8
commit
8824474e08
|
@ -2323,7 +2323,7 @@ static NTSTATUS load_so_dll( LPCWSTR load_path, const UNICODE_STRING *nt_name,
|
|||
image_info.u.s.WineBuiltin = 1;
|
||||
if ((status = build_module( load_path, &win_name, &module, &image_info, NULL, flags, &wm )))
|
||||
{
|
||||
if (module) unix_funcs->unload_builtin_dll( module );
|
||||
if (module) NtUnmapViewOfSection( NtCurrentProcess(), module );
|
||||
return status;
|
||||
}
|
||||
TRACE_(loaddll)( "Loaded %s at %p: builtin\n", debugstr_us(nt_name), module );
|
||||
|
@ -2360,7 +2360,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) unix_funcs->unload_builtin_dll( module );
|
||||
else if (module) NtUnmapViewOfSection( NtCurrentProcess(), module );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -3245,7 +3245,6 @@ static void free_modref( WINE_MODREF *wm )
|
|||
|
||||
free_tls_slot( &wm->ldr );
|
||||
RtlReleaseActivationContext( wm->ldr.ActivationContext );
|
||||
unix_funcs->unload_builtin_dll( wm->ldr.DllBase );
|
||||
NtUnmapViewOfSection( NtCurrentProcess(), wm->ldr.DllBase );
|
||||
if (cached_modref == wm) cached_modref = NULL;
|
||||
RtlFreeUnicodeString( &wm->ldr.FullDllName );
|
||||
|
|
|
@ -132,40 +132,6 @@ const char *user_name = NULL;
|
|||
static HMODULE ntdll_module;
|
||||
static const IMAGE_EXPORT_DIRECTORY *ntdll_exports;
|
||||
|
||||
struct file_id
|
||||
{
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
};
|
||||
|
||||
struct builtin_module
|
||||
{
|
||||
struct list entry;
|
||||
struct file_id id;
|
||||
void *handle;
|
||||
void *module;
|
||||
void *unix_handle;
|
||||
};
|
||||
|
||||
static struct list builtin_modules = LIST_INIT( builtin_modules );
|
||||
|
||||
static NTSTATUS add_builtin_module( void *module, void *handle, const struct stat *st )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
if (!(builtin = malloc( sizeof(*builtin) ))) return STATUS_NO_MEMORY;
|
||||
builtin->handle = handle;
|
||||
builtin->module = module;
|
||||
builtin->unix_handle = NULL;
|
||||
if (st)
|
||||
{
|
||||
builtin->id.dev = st->st_dev;
|
||||
builtin->id.ino = st->st_ino;
|
||||
}
|
||||
else memset( &builtin->id, 0, sizeof(builtin->id) );
|
||||
list_add_tail( &builtin_modules, &builtin->entry );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* adjust an array of pointers to make them into RVAs */
|
||||
static inline void fixup_rva_ptrs( void *array, BYTE *base, unsigned int count )
|
||||
{
|
||||
|
@ -1081,7 +1047,6 @@ static void fill_builtin_image_info( void *module, pe_image_info_t *info )
|
|||
static NTSTATUS dlopen_dll( const char *so_name, UNICODE_STRING *nt_name, void **ret_module,
|
||||
pe_image_info_t *image_info, BOOL prefer_native )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
void *module, *handle;
|
||||
const IMAGE_NT_HEADERS *nt;
|
||||
|
||||
|
@ -1097,14 +1062,12 @@ static NTSTATUS dlopen_dll( const char *so_name, UNICODE_STRING *nt_name, void *
|
|||
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;
|
||||
if (get_builtin_so_handle( 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 (get_builtin_so_handle( module )) goto already_loaded;
|
||||
if (map_so_dll( nt, module ))
|
||||
{
|
||||
dlclose( handle );
|
||||
|
@ -1114,8 +1077,6 @@ static NTSTATUS dlopen_dll( const char *so_name, UNICODE_STRING *nt_name, void *
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -1127,18 +1088,17 @@ static NTSTATUS dlopen_dll( const char *so_name, UNICODE_STRING *nt_name, void *
|
|||
return STATUS_IMAGE_ALREADY_LOADED;
|
||||
}
|
||||
|
||||
if (add_builtin_module( module, handle, NULL ))
|
||||
if (virtual_create_builtin_view( module, nt_name, image_info, handle ))
|
||||
{
|
||||
dlclose( handle );
|
||||
return STATUS_NO_MEMORY;
|
||||
}
|
||||
virtual_create_builtin_view( module, nt_name, image_info );
|
||||
*ret_module = module;
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
already_loaded:
|
||||
fill_builtin_image_info( builtin->module, image_info );
|
||||
*ret_module = builtin->module;
|
||||
fill_builtin_image_info( module, image_info );
|
||||
*ret_module = module;
|
||||
dlclose( handle );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1149,7 +1109,6 @@ already_loaded:
|
|||
*/
|
||||
static NTSTATUS dlopen_unix_dll( void *module, const char *name, void **unix_entry )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
void *unix_module, *handle, *entry;
|
||||
const IMAGE_NT_HEADERS *nt;
|
||||
NTSTATUS status = STATUS_INVALID_IMAGE_FORMAT;
|
||||
|
@ -1160,34 +1119,26 @@ 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);
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
switch (set_builtin_unix_handle( module, handle ))
|
||||
{
|
||||
if (builtin->module == module)
|
||||
{
|
||||
if (builtin->unix_handle == handle) /* already loaded */
|
||||
{
|
||||
*unix_entry = entry;
|
||||
status = STATUS_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
if (builtin->unix_handle)
|
||||
{
|
||||
ERR( "module %p already has a Unix module that's not %s\n", module, debugstr_a(name) );
|
||||
goto done;
|
||||
}
|
||||
if ((status = map_so_dll( nt, unix_module ))) goto done;
|
||||
if ((status = fixup_ntdll_imports( name, unix_module ))) goto done;
|
||||
builtin->unix_handle = handle;
|
||||
*unix_entry = entry;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (builtin->unix_handle == handle)
|
||||
{
|
||||
ERR( "%s already loaded for module %p\n", debugstr_a(name), module );
|
||||
goto done;
|
||||
}
|
||||
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;
|
||||
}
|
||||
ERR( "builtin module not found for %s\n", debugstr_a(name) );
|
||||
done:
|
||||
dlclose( handle );
|
||||
return status;
|
||||
|
@ -1281,13 +1232,12 @@ static inline char *prepend( char *buffer, const char *str, size_t len )
|
|||
*
|
||||
* Open a file for a new dll. Helper for open_builtin_file.
|
||||
*/
|
||||
static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, HANDLE *mapping, void **module,
|
||||
SECTION_IMAGE_INFORMATION *image_info, struct stat *st, BOOL prefer_native )
|
||||
static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, void **module,
|
||||
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
LARGE_INTEGER size;
|
||||
NTSTATUS status;
|
||||
HANDLE handle;
|
||||
HANDLE handle, mapping;
|
||||
|
||||
if ((status = open_unix_file( &handle, name, GENERIC_READ | SYNCHRONIZE, attr, 0,
|
||||
FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_OPEN,
|
||||
|
@ -1296,56 +1246,42 @@ static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, HANDLE
|
|||
if (status != STATUS_OBJECT_PATH_NOT_FOUND && status != STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
{
|
||||
/* if the file exists but failed to open, report the error */
|
||||
if (!stat( name, st )) return status;
|
||||
struct stat st;
|
||||
if (!stat( name, &st )) return status;
|
||||
}
|
||||
/* otherwise continue searching */
|
||||
return STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!stat( name, st ))
|
||||
{
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
{
|
||||
if (builtin->id.dev == st->st_dev && builtin->id.ino == st->st_ino)
|
||||
{
|
||||
TRACE( "%s is the same file as existing module %p\n", debugstr_a(name),
|
||||
builtin->module );
|
||||
NtClose( handle );
|
||||
*module = builtin->module;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else memset( st, 0, sizeof(*st) );
|
||||
|
||||
*module = NULL;
|
||||
size.QuadPart = 0;
|
||||
status = NtCreateSection( mapping, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY |
|
||||
status = NtCreateSection( &mapping, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY |
|
||||
SECTION_MAP_READ | SECTION_MAP_EXECUTE,
|
||||
NULL, &size, PAGE_EXECUTE_READ, SEC_IMAGE, handle );
|
||||
NtClose( handle );
|
||||
if (status) return status;
|
||||
|
||||
NtQuerySection( *mapping, SectionImageInformation, image_info, sizeof(*image_info), NULL );
|
||||
NtQuerySection( mapping, SectionImageInformation, image_info, sizeof(*image_info), NULL );
|
||||
/* ignore non-builtins */
|
||||
if (!(image_info->u.s.WineBuiltin))
|
||||
{
|
||||
WARN( "%s found in WINEDLLPATH but not a builtin, ignoring\n", debugstr_a(name) );
|
||||
NtClose( *mapping );
|
||||
NtClose( mapping );
|
||||
return STATUS_DLL_NOT_FOUND;
|
||||
}
|
||||
if (!is_valid_binary( image_info ))
|
||||
{
|
||||
TRACE( "%s is for arch %x, continuing search\n", debugstr_a(name), image_info->Machine );
|
||||
NtClose( *mapping );
|
||||
NtClose( mapping );
|
||||
return STATUS_IMAGE_MACHINE_TYPE_MISMATCH;
|
||||
}
|
||||
if (prefer_native && (image_info->DllCharacteristics & IMAGE_DLLCHARACTERISTICS_PREFER_NATIVE))
|
||||
{
|
||||
TRACE( "%s has prefer-native flag, ignoring builtin\n", debugstr_a(name) );
|
||||
NtClose( *mapping );
|
||||
NtClose( mapping );
|
||||
return STATUS_IMAGE_ALREADY_LOADED;
|
||||
}
|
||||
status = virtual_map_builtin_module( mapping, module );
|
||||
NtClose( mapping );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1353,14 +1289,14 @@ static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, HANDLE
|
|||
/***********************************************************************
|
||||
* open_builtin_file
|
||||
*/
|
||||
static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, HANDLE *mapping, void **module,
|
||||
SECTION_IMAGE_INFORMATION *image_info, struct stat *st,
|
||||
BOOL prefer_native )
|
||||
static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, void **module,
|
||||
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native )
|
||||
{
|
||||
NTSTATUS status;
|
||||
int fd;
|
||||
|
||||
status = open_dll_file( name, attr, mapping, module, image_info, st, prefer_native );
|
||||
*module = NULL;
|
||||
status = open_dll_file( name, attr, module, image_info, prefer_native );
|
||||
if (status != STATUS_DLL_NOT_FOUND) return status;
|
||||
|
||||
/* try .so file */
|
||||
|
@ -1387,28 +1323,6 @@ static NTSTATUS open_builtin_file( char *name, OBJECT_ATTRIBUTES *attr, HANDLE *
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* map_builtin_module
|
||||
*/
|
||||
static NTSTATUS map_builtin_module( HANDLE mapping, void **module, struct stat *st )
|
||||
{
|
||||
NTSTATUS status;
|
||||
SIZE_T len = 0;
|
||||
|
||||
*module = NULL;
|
||||
status = NtMapViewOfSection( mapping, NtCurrentProcess(), module, 0, 0, NULL, &len,
|
||||
ViewShare, 0, PAGE_EXECUTE_READ );
|
||||
if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS;
|
||||
|
||||
if (!status)
|
||||
{
|
||||
status = add_builtin_module( *module, NULL, st );
|
||||
if (status) NtUnmapViewOfSection( NtCurrentProcess(), *module );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* load_builtin_dll
|
||||
*/
|
||||
|
@ -1421,8 +1335,6 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
|
|||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status = STATUS_DLL_NOT_FOUND;
|
||||
BOOL found_image = FALSE;
|
||||
HANDLE mapping;
|
||||
struct stat st;
|
||||
|
||||
for (i = namepos = 0; i < len; i++)
|
||||
if (nt_name->Buffer[i] == '/' || nt_name->Buffer[i] == '\\') namepos = i + 1;
|
||||
|
@ -1456,7 +1368,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
|
|||
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, &attr, &mapping, module, image_info, &st, prefer_native );
|
||||
status = open_builtin_file( ptr, &attr, module, image_info, prefer_native );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
|
||||
/* now as a program */
|
||||
|
@ -1467,7 +1379,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
|
|||
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, &attr, &mapping, module, image_info, &st, prefer_native );
|
||||
status = open_builtin_file( ptr, &attr, module, image_info, prefer_native );
|
||||
if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
||||
|
@ -1475,7 +1387,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
|
|||
{
|
||||
file[pos + len + 1] = 0;
|
||||
ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) );
|
||||
status = open_builtin_file( ptr, &attr, &mapping, module, image_info, &st, prefer_native );
|
||||
status = open_builtin_file( ptr, &attr, module, image_info, prefer_native );
|
||||
if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) found_image = TRUE;
|
||||
else if (status != STATUS_DLL_NOT_FOUND) goto done;
|
||||
}
|
||||
|
@ -1484,11 +1396,7 @@ static NTSTATUS CDECL load_builtin_dll( UNICODE_STRING *nt_name, void **module,
|
|||
WARN( "cannot find builtin library for %s\n", debugstr_us(nt_name) );
|
||||
|
||||
done:
|
||||
if (!status && !*module)
|
||||
{
|
||||
status = map_builtin_module( mapping, module, &st );
|
||||
NtClose( mapping );
|
||||
}
|
||||
if (status == STATUS_IMAGE_NOT_AT_BASE) status = STATUS_SUCCESS;
|
||||
if (!status && ext)
|
||||
{
|
||||
strcpy( ext, ".so" );
|
||||
|
@ -1499,26 +1407,6 @@ done:
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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 );
|
||||
if (builtin->unix_handle) dlclose( builtin->unix_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
|
||||
|
@ -1555,7 +1443,7 @@ static BOOL get_relocbase(caddr_t mapbase, caddr_t *relocbase)
|
|||
static void CDECL init_builtin_dll( void *module )
|
||||
{
|
||||
#ifdef HAVE_DLINFO
|
||||
struct builtin_module *builtin;
|
||||
void *handle = NULL;
|
||||
struct link_map *map;
|
||||
void (*init_func)(int, char **, char **) = NULL;
|
||||
void (**init_array)(int, char **, char **) = NULL;
|
||||
|
@ -1566,16 +1454,9 @@ static void CDECL init_builtin_dll( void *module )
|
|||
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;
|
||||
if (!(handle = get_builtin_so_handle( module ))) return;
|
||||
if (dlinfo( handle, RTLD_DI_LINKMAP, &map )) return;
|
||||
|
||||
found:
|
||||
for (dyn = map->l_ld; dyn->d_tag; dyn++)
|
||||
{
|
||||
caddr_t relocbase = (caddr_t)map->l_addr;
|
||||
|
@ -1615,24 +1496,15 @@ static void load_ntdll(void)
|
|||
SECTION_IMAGE_INFORMATION info;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING str;
|
||||
HANDLE mapping;
|
||||
struct stat st;
|
||||
void *module;
|
||||
char *name = build_path( dll_dir, "ntdll.dll.so" );
|
||||
|
||||
init_unicode_string( &str, path );
|
||||
InitializeObjectAttributes( &attr, &str, 0, 0, NULL );
|
||||
name[strlen(name) - 3] = 0; /* remove .so */
|
||||
status = open_builtin_file( name, &attr, &mapping, &module, &info, &st, FALSE );
|
||||
if (!status && !module)
|
||||
{
|
||||
SIZE_T len = 0;
|
||||
status = NtMapViewOfSection( mapping, NtCurrentProcess(), &module, 0, 0, NULL, &len,
|
||||
ViewShare, 0, PAGE_EXECUTE_READ );
|
||||
if (status == STATUS_IMAGE_NOT_AT_BASE) relocate_ntdll( module );
|
||||
status = add_builtin_module( module, NULL, &st );
|
||||
}
|
||||
if (status) fatal_error( "failed to load %s error %x\n", name, status );
|
||||
status = open_builtin_file( name, &attr, &module, &info, FALSE );
|
||||
if (status == STATUS_IMAGE_NOT_AT_BASE) relocate_ntdll( module );
|
||||
else if (status) fatal_error( "failed to load %s error %x\n", name, status );
|
||||
free( name );
|
||||
load_ntdll_functions( module );
|
||||
ntdll_module = module;
|
||||
|
@ -1718,7 +1590,6 @@ static struct unix_funcs unix_funcs =
|
|||
virtual_release_address_space,
|
||||
load_so_dll,
|
||||
load_builtin_dll,
|
||||
unload_builtin_dll,
|
||||
init_builtin_dll,
|
||||
unwind_builtin_dll,
|
||||
__wine_dbg_get_channel_flags,
|
||||
|
|
|
@ -173,8 +173,9 @@ extern void *anon_mmap_alloc( size_t size, int prot ) DECLSPEC_HIDDEN;
|
|||
extern void virtual_init(void) DECLSPEC_HIDDEN;
|
||||
extern ULONG_PTR get_system_affinity_mask(void) DECLSPEC_HIDDEN;
|
||||
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_name,
|
||||
pe_image_info_t *info ) DECLSPEC_HIDDEN;
|
||||
pe_image_info_t *info, void *so_handle ) 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;
|
||||
|
@ -196,6 +197,8 @@ extern void virtual_set_force_exec( BOOL enable ) DECLSPEC_HIDDEN;
|
|||
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 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,
|
||||
|
|
|
@ -83,6 +83,18 @@ struct reserved_area
|
|||
|
||||
static struct list reserved_areas = LIST_INIT(reserved_areas);
|
||||
|
||||
struct builtin_module
|
||||
{
|
||||
struct list entry;
|
||||
dev_t dev;
|
||||
ino_t ino;
|
||||
void *handle;
|
||||
void *module;
|
||||
void *unix_handle;
|
||||
};
|
||||
|
||||
static struct list builtin_modules = LIST_INIT( builtin_modules );
|
||||
|
||||
struct file_view
|
||||
{
|
||||
struct wine_rb_entry entry; /* entry in global view tree */
|
||||
|
@ -547,6 +559,116 @@ static void mmap_init( const struct preload_info *preload_info )
|
|||
#endif
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* add_builtin_module
|
||||
*/
|
||||
static void add_builtin_module( void *module, void *handle, const struct stat *st )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
|
||||
if (!(builtin = malloc( sizeof(*builtin) ))) return;
|
||||
builtin->handle = handle;
|
||||
builtin->module = module;
|
||||
builtin->unix_handle = NULL;
|
||||
if (st)
|
||||
{
|
||||
builtin->dev = st->st_dev;
|
||||
builtin->ino = st->st_ino;
|
||||
}
|
||||
else
|
||||
{
|
||||
builtin->dev = 0;
|
||||
builtin->ino = 0;
|
||||
}
|
||||
list_add_tail( &builtin_modules, &builtin->entry );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* remove_builtin_module
|
||||
*/
|
||||
static NTSTATUS remove_builtin_module( 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 );
|
||||
if (builtin->unix_handle) dlclose( builtin->unix_handle );
|
||||
free( builtin );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* find_builtin_module
|
||||
*/
|
||||
static void *find_builtin_module( const struct stat *st )
|
||||
{
|
||||
struct builtin_module *builtin;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( builtin, &builtin_modules, struct builtin_module, entry )
|
||||
if (builtin->dev == st->st_dev && builtin->ino == st->st_ino) return builtin->module;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* get_builtin_so_handle
|
||||
*/
|
||||
void *get_builtin_so_handle( void *module )
|
||||
{
|
||||
sigset_t sigset;
|
||||
void *ret = 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;
|
||||
ret = builtin->handle;
|
||||
break;
|
||||
}
|
||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* set_builtin_unix_handle
|
||||
*/
|
||||
NTSTATUS set_builtin_unix_handle( void *module, void *handle )
|
||||
{
|
||||
sigset_t sigset;
|
||||
NTSTATUS status = STATUS_DLL_NOT_FOUND;
|
||||
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)
|
||||
{
|
||||
if (builtin->unix_handle == handle) status = STATUS_IMAGE_ALREADY_LOADED;
|
||||
else if (builtin->unix_handle) status = STATUS_OBJECT_NAME_COLLISION;
|
||||
else status = STATUS_SUCCESS;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* free_ranges_lower_bound
|
||||
*
|
||||
|
@ -2248,12 +2370,13 @@ static NTSTATUS get_mapping_info( HANDLE handle, ACCESS_MASK access, unsigned in
|
|||
*/
|
||||
static NTSTATUS 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 )
|
||||
ULONG alloc_type, ULONG protect, BOOL is_builtin )
|
||||
{
|
||||
NTSTATUS res;
|
||||
mem_size_t full_size;
|
||||
ACCESS_MASK access;
|
||||
SIZE_T size;
|
||||
struct stat st;
|
||||
pe_image_info_t *image_info = NULL;
|
||||
WCHAR *filename;
|
||||
void *base;
|
||||
|
@ -2312,6 +2435,18 @@ static NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned sh
|
|||
res = STATUS_INVALID_PARAMETER;
|
||||
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
|
||||
if (is_builtin) /* check for already loaded builtin */
|
||||
{
|
||||
fstat( unix_handle, &st );
|
||||
if ((base = find_builtin_module( &st )))
|
||||
{
|
||||
*addr_ptr = base;
|
||||
*size_ptr = image_info->map_size;
|
||||
res = STATUS_SUCCESS;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (sec_flags & SEC_IMAGE)
|
||||
{
|
||||
base = wine_server_get_ptr( image_info->base );
|
||||
|
@ -2381,6 +2516,7 @@ static NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned sh
|
|||
|
||||
if (res >= 0)
|
||||
{
|
||||
if (is_builtin) add_builtin_module( view->base, NULL, &st );
|
||||
*addr_ptr = view->base;
|
||||
*size_ptr = size;
|
||||
VIRTUAL_DEBUG_DUMP_VIEW( view );
|
||||
|
@ -2525,10 +2661,23 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* virtual_map_builtin_module
|
||||
*/
|
||||
NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module )
|
||||
{
|
||||
SIZE_T size = 0;
|
||||
|
||||
*module = NULL;
|
||||
return virtual_map_section( mapping, module, 0, 0, NULL, &size, 0, PAGE_EXECUTE_READ, TRUE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* virtual_create_builtin_view
|
||||
*/
|
||||
NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_name, pe_image_info_t *info )
|
||||
NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_name,
|
||||
pe_image_info_t *info, void *so_handle )
|
||||
{
|
||||
NTSTATUS status;
|
||||
sigset_t sigset;
|
||||
|
@ -2573,6 +2722,7 @@ NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_nam
|
|||
|
||||
if (status >= 0)
|
||||
{
|
||||
add_builtin_module( view->base, so_handle, NULL );
|
||||
VIRTUAL_DEBUG_DUMP_VIEW( view );
|
||||
if (is_beyond_limit( base, size, working_set_limit )) working_set_limit = address_space_limit;
|
||||
}
|
||||
|
@ -4115,7 +4265,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
|
|||
}
|
||||
|
||||
return virtual_map_section( handle, addr_ptr, zero_bits_64, commit_size,
|
||||
offset_ptr, size_ptr, alloc_type, protect );
|
||||
offset_ptr, size_ptr, alloc_type, protect, FALSE );
|
||||
}
|
||||
|
||||
|
||||
|
@ -4152,7 +4302,11 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr )
|
|||
status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (!status) delete_view( view );
|
||||
if (!status)
|
||||
{
|
||||
if (view->protect & SEC_IMAGE) remove_builtin_module( view->base );
|
||||
delete_view( view );
|
||||
}
|
||||
else FIXME( "failed to unmap %p %x\n", view->base, status );
|
||||
}
|
||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
struct _DISPATCHER_CONTEXT;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
#define NTDLL_UNIXLIB_VERSION 115
|
||||
#define NTDLL_UNIXLIB_VERSION 116
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
|
@ -76,7 +76,6 @@ struct unix_funcs
|
|||
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module );
|
||||
NTSTATUS (CDECL *load_builtin_dll)( UNICODE_STRING *name, void **module, void **unix_entry,
|
||||
SECTION_IMAGE_INFORMATION *image_info, BOOL prefer_native );
|
||||
NTSTATUS (CDECL *unload_builtin_dll)( void *module );
|
||||
void (CDECL *init_builtin_dll)( void *module );
|
||||
NTSTATUS (CDECL *unwind_builtin_dll)( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
|
||||
CONTEXT *context );
|
||||
|
|
Loading…
Reference in New Issue