ntdll: Move the builtin dll list to virtual.c.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-03-16 10:58:14 +01:00
parent 100b81e8a8
commit 8824474e08
5 changed files with 214 additions and 188 deletions

View File

@ -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 );

View File

@ -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,

View File

@ -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,

View File

@ -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 );

View File

@ -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 );