When running a 32-bit EXE in Wow64 mode with a fairly full address space, a builtin DLL may be loaded above the 4GB line. This is due to virtual_map_builtin_module calling virtual_map_image with zero_bits hardcoded to 0. virtual_map_section is called with the correct zero_bits, this patch propagates that parameter down through load_builtin, find_builtin_dll, open_builtin_pe_file, and virtual_map_builtin_module.
From: Brendan Shanks bshanks@codeweavers.com
Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- dlls/ntdll/unix/loader.c | 2 +- dlls/ntdll/unix/unix_private.h | 4 ++-- dlls/ntdll/unix/virtual.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 7f85582adf3..ef66d76e610 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1486,7 +1486,7 @@ static NTSTATUS open_builtin_pe_file( const char *name, OBJECT_ATTRIBUTES *attr, status = open_dll_file( name, attr, &mapping ); if (!status) { - status = virtual_map_builtin_module( mapping, module, size, image_info, machine, prefer_native ); + status = virtual_map_builtin_module( mapping, module, size, image_info, 0, machine, prefer_native ); NtClose( mapping ); } return status; diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 795fc148479..8a213bdc65f 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -195,8 +195,8 @@ 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, BOOL wow64 ) DECLSPEC_HIDDEN; -extern NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size, - SECTION_IMAGE_INFORMATION *info, WORD machine, BOOL prefer_native ) DECLSPEC_HIDDEN; +extern NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size, SECTION_IMAGE_INFORMATION *info, + ULONG_PTR zero_bits, WORD machine, BOOL prefer_native ) DECLSPEC_HIDDEN; extern NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_name, pe_image_info_t *info, void *so_handle ) DECLSPEC_HIDDEN; extern TEB *virtual_alloc_first_teb(void) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 6ecca9cb98a..0f65db69fbb 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -2756,8 +2756,8 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info, BOOL wow64 ) /*********************************************************************** * virtual_map_builtin_module */ -NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size, - SECTION_IMAGE_INFORMATION *info, WORD machine, BOOL prefer_native ) +NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size, SECTION_IMAGE_INFORMATION *info, + ULONG_PTR zero_bits, WORD machine, BOOL prefer_native ) { mem_size_t full_size; unsigned int sec_flags; @@ -2794,7 +2794,7 @@ NTSTATUS virtual_map_builtin_module( HANDLE mapping, void **module, SIZE_T *size else { status = virtual_map_image( mapping, SECTION_MAP_READ | SECTION_MAP_EXECUTE, - module, size, 0, shared_file, 0, image_info, filename, TRUE ); + module, size, zero_bits, shared_file, 0, image_info, filename, TRUE ); virtual_fill_image_information( image_info, info ); }
From: Brendan Shanks bshanks@codeweavers.com
Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- dlls/ntdll/unix/loader.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index ef66d76e610..cd8b79e2d52 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1477,7 +1477,7 @@ static NTSTATUS open_dll_file( const char *name, OBJECT_ATTRIBUTES *attr, HANDLE */ static NTSTATUS open_builtin_pe_file( const char *name, OBJECT_ATTRIBUTES *attr, void **module, SIZE_T *size, SECTION_IMAGE_INFORMATION *image_info, - WORD machine, BOOL prefer_native ) + ULONG_PTR zero_bits, WORD machine, BOOL prefer_native ) { NTSTATUS status; HANDLE mapping; @@ -1486,7 +1486,7 @@ static NTSTATUS open_builtin_pe_file( const char *name, OBJECT_ATTRIBUTES *attr, status = open_dll_file( name, attr, &mapping ); if (!status) { - status = virtual_map_builtin_module( mapping, module, size, image_info, 0, machine, prefer_native ); + status = virtual_map_builtin_module( mapping, module, size, image_info, zero_bits, machine, prefer_native ); NtClose( mapping ); } return status; @@ -1572,7 +1572,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T ptr = prepend( ptr, ptr, namelen ); ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 ); ptr = prepend( ptr, build_dir, strlen(build_dir) ); - status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, machine, prefer_native ); + status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, 0, machine, prefer_native ); if (status != STATUS_DLL_NOT_FOUND) goto done; strcpy( file + pos + len + 1, ".so" ); status = open_builtin_so_file( ptr, &attr, module, image_info, machine, prefer_native ); @@ -1586,7 +1586,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T ptr = prepend( ptr, ptr, namelen ); ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 ); ptr = prepend( ptr, build_dir, strlen(build_dir) ); - status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, machine, prefer_native ); + status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, 0, machine, prefer_native ); if (status != STATUS_DLL_NOT_FOUND) goto done; strcpy( file + pos + len + 1, ".so" ); status = open_builtin_so_file( ptr, &attr, module, image_info, machine, prefer_native ); @@ -1599,7 +1599,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T file[pos + len + 1] = 0; ptr = prepend( ptr, pe_dir, strlen(pe_dir) ); ptr = prepend( ptr, dll_paths[i], strlen(dll_paths[i]) ); - status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, machine, prefer_native ); + status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, 0, machine, prefer_native ); /* use so dir for unix lib */ ptr = file + pos; ptr = prepend( ptr, so_dir, strlen(so_dir) ); @@ -1610,7 +1610,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T if (status != STATUS_DLL_NOT_FOUND) goto done; file[pos + len + 1] = 0; ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) ); - status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, machine, prefer_native ); + status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, 0, machine, prefer_native ); if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { found_image = TRUE; @@ -1981,7 +1981,7 @@ static void load_ntdll(void) name = malloc( strlen( ntdll_dir ) + strlen( pe_dir ) + sizeof("/ntdll.dll.so") ); if (build_dir) sprintf( name, "%s/ntdll.dll", ntdll_dir ); else sprintf( name, "%s%s/ntdll.dll", dll_dir, pe_dir ); - status = open_builtin_pe_file( name, &attr, &module, &size, &info, current_machine, FALSE ); + status = open_builtin_pe_file( name, &attr, &module, &size, &info, 0, current_machine, FALSE ); if (status == STATUS_DLL_NOT_FOUND) { sprintf( name, "%s/ntdll.dll.so", ntdll_dir );
From: Brendan Shanks bshanks@codeweavers.com
Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- dlls/ntdll/unix/loader.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index cd8b79e2d52..a69bf49b705 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1530,7 +1530,8 @@ static NTSTATUS open_builtin_so_file( const char *name, OBJECT_ATTRIBUTES *attr, * find_builtin_dll */ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T *size_ptr, - SECTION_IMAGE_INFORMATION *image_info, WORD machine, BOOL prefer_native ) + SECTION_IMAGE_INFORMATION *image_info, + ULONG_PTR zero_bits, WORD machine, BOOL prefer_native ) { unsigned int i, pos, namepos, namelen, maxlen = 0; unsigned int len = nt_name->Length / sizeof(WCHAR); @@ -1572,7 +1573,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T ptr = prepend( ptr, ptr, namelen ); ptr = prepend( ptr, "/dlls", sizeof("/dlls") - 1 ); ptr = prepend( ptr, build_dir, strlen(build_dir) ); - status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, 0, machine, prefer_native ); + status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, zero_bits, machine, prefer_native ); if (status != STATUS_DLL_NOT_FOUND) goto done; strcpy( file + pos + len + 1, ".so" ); status = open_builtin_so_file( ptr, &attr, module, image_info, machine, prefer_native ); @@ -1586,7 +1587,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T ptr = prepend( ptr, ptr, namelen ); ptr = prepend( ptr, "/programs", sizeof("/programs") - 1 ); ptr = prepend( ptr, build_dir, strlen(build_dir) ); - status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, 0, machine, prefer_native ); + status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, zero_bits, machine, prefer_native ); if (status != STATUS_DLL_NOT_FOUND) goto done; strcpy( file + pos + len + 1, ".so" ); status = open_builtin_so_file( ptr, &attr, module, image_info, machine, prefer_native ); @@ -1599,7 +1600,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T file[pos + len + 1] = 0; ptr = prepend( ptr, pe_dir, strlen(pe_dir) ); ptr = prepend( ptr, dll_paths[i], strlen(dll_paths[i]) ); - status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, 0, machine, prefer_native ); + status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, zero_bits, machine, prefer_native ); /* use so dir for unix lib */ ptr = file + pos; ptr = prepend( ptr, so_dir, strlen(so_dir) ); @@ -1610,7 +1611,7 @@ static NTSTATUS find_builtin_dll( UNICODE_STRING *nt_name, void **module, SIZE_T if (status != STATUS_DLL_NOT_FOUND) goto done; file[pos + len + 1] = 0; ptr = prepend( file + pos, dll_paths[i], strlen(dll_paths[i]) ); - status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, 0, machine, prefer_native ); + status = open_builtin_pe_file( ptr, &attr, module, size_ptr, image_info, zero_bits, machine, prefer_native ); if (status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) { found_image = TRUE; @@ -1674,9 +1675,9 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename, case LO_NATIVE_BUILTIN: return STATUS_IMAGE_ALREADY_LOADED; case LO_BUILTIN: - return find_builtin_dll( &nt_name, module, size, &info, machine, FALSE ); + return find_builtin_dll( &nt_name, module, size, &info, 0, machine, FALSE ); default: - status = find_builtin_dll( &nt_name, module, size, &info, machine, (loadorder == LO_DEFAULT) ); + status = find_builtin_dll( &nt_name, module, size, &info, 0, machine, (loadorder == LO_DEFAULT) ); if (status == STATUS_DLL_NOT_FOUND || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) return STATUS_IMAGE_ALREADY_LOADED; return status; @@ -1839,7 +1840,7 @@ NTSTATUS load_main_exe( const WCHAR *dos_name, const char *unix_name, const WCHA /* if path is in system dir, we can load the builtin even if the file itself doesn't exist */ if (loadorder != LO_NATIVE && is_builtin_path( &nt_name, &machine )) { - status = find_builtin_dll( &nt_name, module, &size, &main_image_info, machine, FALSE ); + status = find_builtin_dll( &nt_name, module, &size, &main_image_info, 0, machine, FALSE ); if (status != STATUS_DLL_NOT_FOUND) return status; } if (!contains_path) return STATUS_DLL_NOT_FOUND; @@ -1868,7 +1869,7 @@ NTSTATUS load_start_exe( WCHAR **image, void **module ) wcscpy( *image, get_machine_wow64_dir( current_machine )); wcscat( *image, startW ); init_unicode_string( &nt_name, *image ); - status = find_builtin_dll( &nt_name, module, &size, &main_image_info, current_machine, FALSE ); + status = find_builtin_dll( &nt_name, module, &size, &main_image_info, 0, current_machine, FALSE ); if (status) { MESSAGE( "wine: failed to load start.exe: %x\n", status ); @@ -2082,7 +2083,7 @@ static void load_wow64_ntdll( USHORT machine ) wcscpy( path, get_machine_wow64_dir( machine )); wcscat( path, ntdllW ); init_unicode_string( &nt_name, path ); - status = find_builtin_dll( &nt_name, &module, &size, &info, machine, FALSE ); + status = find_builtin_dll( &nt_name, &module, &size, &info, 0, machine, FALSE ); switch (status) { case STATUS_IMAGE_NOT_AT_BASE:
From: Brendan Shanks bshanks@codeweavers.com
Signed-off-by: Brendan Shanks bshanks@codeweavers.com --- dlls/ntdll/unix/loader.c | 6 +++--- dlls/ntdll/unix/unix_private.h | 2 +- dlls/ntdll/unix/virtual.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index a69bf49b705..2fd4acc06b9 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1644,7 +1644,7 @@ done: * Return STATUS_IMAGE_ALREADY_LOADED if we should keep the native one that we have found. */ NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename, - void **module, SIZE_T *size ) + void **module, SIZE_T *size, ULONG_PTR zero_bits ) { WORD machine = image_info->machine; /* request same machine as the native one */ NTSTATUS status; @@ -1675,9 +1675,9 @@ NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename, case LO_NATIVE_BUILTIN: return STATUS_IMAGE_ALREADY_LOADED; case LO_BUILTIN: - return find_builtin_dll( &nt_name, module, size, &info, 0, machine, FALSE ); + return find_builtin_dll( &nt_name, module, size, &info, zero_bits, machine, FALSE ); default: - status = find_builtin_dll( &nt_name, module, size, &info, 0, machine, (loadorder == LO_DEFAULT) ); + status = find_builtin_dll( &nt_name, module, size, &info, zero_bits, machine, (loadorder == LO_DEFAULT) ); if (status == STATUS_DLL_NOT_FOUND || status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH) return STATUS_IMAGE_ALREADY_LOADED; return status; diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 8a213bdc65f..39b667ddd4a 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -150,7 +150,7 @@ extern void *create_startup_info( const UNICODE_STRING *nt_image, const RTL_USER extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN; extern NTSTATUS exec_wineloader( char **argv, int socketfd, const pe_image_info_t *pe_info ) DECLSPEC_HIDDEN; extern NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename, - void **addr_ptr, SIZE_T *size_ptr ) DECLSPEC_HIDDEN; + void **addr_ptr, SIZE_T *size_ptr, ULONG_PTR zero_bits ) DECLSPEC_HIDDEN; extern BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine ) DECLSPEC_HIDDEN; extern NTSTATUS load_main_exe( const WCHAR *name, const char *unix_name, const WCHAR *curdir, WCHAR **image, void **module ) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 0f65db69fbb..a93d5b4174a 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -2539,7 +2539,7 @@ static NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, ULONG_PTR z { filename = (WCHAR *)(image_info + 1); /* check if we can replace that mapping with the builtin */ - res = load_builtin( image_info, filename, addr_ptr, size_ptr ); + res = load_builtin( image_info, filename, addr_ptr, size_ptr, zero_bits ); if (res == STATUS_IMAGE_ALREADY_LOADED) res = virtual_map_image( handle, access, addr_ptr, size_ptr, zero_bits, shared_file, alloc_type, image_info, filename, FALSE );