From 7512c53b89308c16a512cb8f0c1d0fd6ff02b17b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 7 Apr 2021 10:46:34 +0200 Subject: [PATCH] ntdll: Cache the main image section information. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50937 Signed-off-by: Alexandre Julliard --- dlls/ntdll/unix/env.c | 14 ++++++-------- dlls/ntdll/unix/loader.c | 13 +++++++------ dlls/ntdll/unix/server.c | 4 ++-- dlls/ntdll/unix/unix_private.h | 11 +++-------- dlls/ntdll/unix/virtual.c | 8 ++------ 5 files changed, 20 insertions(+), 30 deletions(-) diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c index 5b4a2254659..10089a740c2 100644 --- a/dlls/ntdll/unix/env.c +++ b/dlls/ntdll/unix/env.c @@ -1891,7 +1891,6 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void) { static const WCHAR pathW[] = {'P','A','T','H'}; RTL_USER_PROCESS_PARAMETERS *params = NULL; - SECTION_IMAGE_INFORMATION image_info; SIZE_T size, env_pos, env_size; WCHAR *dst, *image, *cmdline, *p, *path = NULL; WCHAR *env = get_initial_environment( &env_pos, &env_size ); @@ -1916,11 +1915,11 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void) add_registry_environment( &env, &env_pos, &env_size ); env[env_pos++] = 0; - status = load_main_exe( NULL, main_argv[1], curdir, &image, &module, &image_info ); + status = load_main_exe( NULL, main_argv[1], curdir, &image, &module ); if (!status) { - if (image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT; - if (image_info.Machine != current_machine) status = STATUS_INVALID_IMAGE_FORMAT; + if (main_image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT; + if (main_image_info.Machine != current_machine) status = STATUS_INVALID_IMAGE_FORMAT; } if (status) /* try launching it through start.exe */ @@ -1928,7 +1927,7 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void) static const char *args[] = { "start.exe", "/exec" }; free( image ); if (module) NtUnmapViewOfSection( GetCurrentProcess(), module ); - load_start_exe( &image, &module, &image_info ); + load_start_exe( &image, &module ); prepend_argv( args, 2 ); } else rebuild_argv(); @@ -1989,7 +1988,6 @@ void init_startup_info(void) NTSTATUS status; SIZE_T size, info_size, env_size, env_pos; RTL_USER_PROCESS_PARAMETERS *params = NULL; - SECTION_IMAGE_INFORMATION image_info; startup_info_t *info; if (!startup_info_size) @@ -2082,8 +2080,8 @@ void init_startup_info(void) free( info ); NtCurrentTeb()->Peb->ProcessParameters = params; - status = load_main_exe( params->ImagePathName.Buffer, NULL, params->CommandLine.Buffer, - &image, &module, &image_info ); + status = load_main_exe( params->ImagePathName.Buffer, NULL, + params->CommandLine.Buffer, &image, &module ); if (status) { MESSAGE( "wine: failed to start %s\n", debugstr_us(¶ms->ImagePathName) ); diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 3d613425b68..e362f5eb4db 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -122,6 +122,7 @@ const char *build_dir = NULL; const char *config_dir = NULL; const char **dll_paths = NULL; const char *user_name = NULL; +SECTION_IMAGE_INFORMATION main_image_info = { NULL }; static HMODULE ntdll_module; static const IMAGE_EXPORT_DIRECTORY *ntdll_exports; @@ -1473,7 +1474,7 @@ static NTSTATUS open_main_image( WCHAR *image, void **module, SECTION_IMAGE_INFO * load_main_exe */ NTSTATUS load_main_exe( const WCHAR *dos_name, const char *unix_name, const WCHAR *curdir, - WCHAR **image, void **module, SECTION_IMAGE_INFORMATION *image_info ) + WCHAR **image, void **module ) { UNICODE_STRING nt_name; WCHAR *tmp = NULL; @@ -1487,7 +1488,7 @@ NTSTATUS load_main_exe( const WCHAR *dos_name, const char *unix_name, const WCHA if (unix_name && unix_name[0] == '/' && !stat( unix_name, &st )) { if ((status = unix_to_nt_file_name( unix_name, image ))) goto failed; - status = open_main_image( *image, module, image_info ); + status = open_main_image( *image, module, &main_image_info ); if (status != STATUS_DLL_NOT_FOUND) return status; free( *image ); } @@ -1504,14 +1505,14 @@ NTSTATUS load_main_exe( const WCHAR *dos_name, const char *unix_name, const WCHA if ((status = get_full_path( dos_name, curdir, image ))) goto failed; free( tmp ); - status = open_main_image( *image, module, image_info ); + status = open_main_image( *image, module, &main_image_info ); if (status != STATUS_DLL_NOT_FOUND) return status; /* if path is in system dir, we can load the builtin even if the file itself doesn't exist */ init_unicode_string( &nt_name, *image ); if (is_builtin_path( &nt_name, &machine )) { - status = find_builtin_dll( &nt_name, module, &size, image_info, machine, FALSE ); + status = find_builtin_dll( &nt_name, module, &size, &main_image_info, machine, FALSE ); if (status != STATUS_DLL_NOT_FOUND) return status; } if (!contains_path) return STATUS_DLL_NOT_FOUND; @@ -1529,7 +1530,7 @@ failed: * * Load start.exe as main image. */ -NTSTATUS load_start_exe( WCHAR **image, void **module, SECTION_IMAGE_INFORMATION *image_info ) +NTSTATUS load_start_exe( WCHAR **image, void **module ) { static const WCHAR startW[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\', 's','y','s','t','e','m','3','2','\\','s','t','a','r','t','.','e','x','e',0}; @@ -1538,7 +1539,7 @@ NTSTATUS load_start_exe( WCHAR **image, void **module, SECTION_IMAGE_INFORMATION SIZE_T size; init_unicode_string( &nt_name, startW ); - status = find_builtin_dll( &nt_name, module, &size, image_info, current_machine, FALSE ); + status = find_builtin_dll( &nt_name, module, &size, &main_image_info, current_machine, FALSE ); if (status) { MESSAGE( "wine: failed to load start.exe: %x\n", status ); diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index 65863f54c4b..a108ce00482 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -1605,7 +1605,6 @@ size_t server_init_process(void) void server_init_process_done(void) { PEB *peb = NtCurrentTeb()->Peb; - IMAGE_NT_HEADERS *nt = get_exe_nt_header(); void *entry; NTSTATUS status; int suspend, needs_close, unixdir; @@ -1622,7 +1621,8 @@ void server_init_process_done(void) #ifdef __APPLE__ send_server_task_port(); #endif - if (nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) virtual_set_large_address_space(); + if (main_image_info.ImageCharacteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) + virtual_set_large_address_space(); /* Install signal handlers; this cannot be done earlier, since we cannot * send exceptions to the debugger before the create process event that diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 257566ce976..d0fa7a54f49 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -120,6 +120,7 @@ extern const char **dll_paths DECLSPEC_HIDDEN; extern USHORT *uctable DECLSPEC_HIDDEN; extern USHORT *lctable DECLSPEC_HIDDEN; extern SIZE_T startup_info_size DECLSPEC_HIDDEN; +extern SECTION_IMAGE_INFORMATION main_image_info DECLSPEC_HIDDEN; extern int main_argc DECLSPEC_HIDDEN; extern char **main_argv DECLSPEC_HIDDEN; extern char **main_envp DECLSPEC_HIDDEN; @@ -147,8 +148,8 @@ extern NTSTATUS load_builtin( const pe_image_info_t *image_info, WCHAR *filename void **addr_ptr, SIZE_T *size_ptr ) 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, SECTION_IMAGE_INFORMATION *image_info ) DECLSPEC_HIDDEN; -extern NTSTATUS load_start_exe( WCHAR **image, void **module, SECTION_IMAGE_INFORMATION *image_info ) DECLSPEC_HIDDEN; + void **module ) DECLSPEC_HIDDEN; +extern NTSTATUS load_start_exe( WCHAR **image, void **module ) DECLSPEC_HIDDEN; extern void start_server( BOOL debug ) DECLSPEC_HIDDEN; extern ULONG_PTR get_image_address(void) DECLSPEC_HIDDEN; @@ -295,12 +296,6 @@ static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len ) while (len--) *dst++ = (unsigned char)*src++; } -static inline IMAGE_NT_HEADERS *get_exe_nt_header(void) -{ - IMAGE_DOS_HEADER *module = (IMAGE_DOS_HEADER *)NtCurrentTeb()->Peb->ImageBaseAddress; - return (IMAGE_NT_HEADERS *)((char *)module + module->e_lfanew); -} - static inline void *get_signal_stack(void) { return (char *)NtCurrentTeb() + teb_size - teb_offset; diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 149555f4fce..659ad2421d4 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -3006,12 +3006,8 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SI sigset_t sigset; SIZE_T size, extra_size = 0; - if (!reserve_size || !commit_size) - { - IMAGE_NT_HEADERS *nt = get_exe_nt_header(); - if (!reserve_size) reserve_size = nt->OptionalHeader.SizeOfStackReserve; - if (!commit_size) commit_size = nt->OptionalHeader.SizeOfStackCommit; - } + if (!reserve_size) reserve_size = main_image_info.MaximumStackSize; + if (!commit_size) commit_size = main_image_info.CommittedStackSize; size = max( reserve_size, commit_size ); if (size < 1024 * 1024) size = 1024 * 1024; /* Xlib needs a large stack */