diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c index a0424aa15cd..0bb591babe6 100644 --- a/dlls/dbghelp/dbghelp.c +++ b/dlls/dbghelp/dbghelp.c @@ -295,6 +295,7 @@ static BOOL check_live_target(struct process* pcs) BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess) { struct process* pcs; + BOOL wow64, child_wow64; TRACE("(%p %s %u)\n", hProcess, debugstr_w(UserSearchPath), fInvadeProcess); @@ -312,6 +313,12 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP pcs->handle = hProcess; + IsWow64Process(GetCurrentProcess(), &wow64); + + if (!IsWow64Process(hProcess, &child_wow64)) + return FALSE; + pcs->is_64bit = (sizeof(void *) == 8 || wow64) && !child_wow64; + if (UserSearchPath) { pcs->search_path = lstrcpyW(HeapAlloc(GetProcessHeap(), 0, diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index f37991dacd6..3c1b3dd8ca6 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -403,6 +403,8 @@ struct process unsigned buffer_size; void* buffer; + + BOOL is_64bit; }; struct line_info @@ -609,7 +611,7 @@ extern void module_reset_debug_info(struct module* module) DECLSPEC_HIDD extern BOOL module_remove(struct process* pcs, struct module* module) DECLSPEC_HIDDEN; extern void module_set_module(struct module* module, const WCHAR* name) DECLSPEC_HIDDEN; -extern const WCHAR *get_wine_loader_name(void) DECLSPEC_HIDDEN; +extern WCHAR * get_wine_loader_name(struct process *pcs) DECLSPEC_HIDDEN; /* msc.c */ extern BOOL pe_load_debug_directory(const struct process* pcs, diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index e841b1b707a..4d877b44214 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -50,6 +50,7 @@ #include "wine/library.h" #include "wine/debug.h" +#include "wine/heap.h" #ifdef __ELF__ @@ -1568,13 +1569,17 @@ static BOOL elf_enum_modules_internal(const struct process* pcs, */ static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info) { + WCHAR *loader = get_wine_loader_name(pcs); PROCESS_BASIC_INFORMATION pbi; ULONG_PTR base = 0; + BOOL ret; if (!NtQueryInformationProcess( pcs->handle, ProcessBasicInformation, &pbi, sizeof(pbi), NULL )) ReadProcessMemory( pcs->handle, &pbi.PebBaseAddress->Reserved[0], &base, sizeof(base), NULL ); - return elf_search_and_load_file(pcs, get_wine_loader_name(), base, 0, elf_info); + ret = elf_search_and_load_file(pcs, loader, base, 0, elf_info); + heap_free(loader); + return ret; } /****************************************************************** diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index 01fa300eff7..4018c9dbf2d 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -1703,6 +1703,7 @@ BOOL macho_synchronize_module_list(struct process* pcs) */ static BOOL macho_search_loader(struct process* pcs, struct macho_info* macho_info) { + WCHAR *loader = get_wine_loader_name(pcs); BOOL ret = FALSE; ULONG_PTR dyld_image_info_address; struct dyld_all_image_infos image_infos; @@ -1757,7 +1758,8 @@ static BOOL macho_search_loader(struct process* pcs, struct macho_info* macho_in } if (!ret) - ret = macho_search_and_load_file(pcs, get_wine_loader_name(), 0, macho_info); + ret = macho_search_and_load_file(pcs, loader, 0, macho_info); + heap_free(loader); return ret; } diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 7a238123c7a..36598737242 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -139,43 +139,38 @@ void module_set_module(struct module* module, const WCHAR* name) module_fill_module(name, module->modulename, sizeof(module->modulename) / sizeof(module->modulename[0])); } -const WCHAR *get_wine_loader_name(void) +/* Returned string must be freed by caller */ +WCHAR *get_wine_loader_name(struct process *pcs) { - static const BOOL is_win64 = sizeof(void *) > sizeof(int); /* FIXME: should depend on target process */ static const WCHAR wineW[] = {'w','i','n','e',0}; static const WCHAR suffixW[] = {'6','4',0}; - static const WCHAR *loader; + WCHAR *buffer, *p; + const char *env; - if (!loader) + /* All binaries are loaded with WINELOADER (if run from tree) or by the + * main executable + */ + if ((env = getenv("WINELOADER"))) { - WCHAR *p, *buffer; - const char *ptr; - - /* All binaries are loaded with WINELOADER (if run from tree) or by the - * main executable - */ - if ((ptr = getenv("WINELOADER"))) - { - DWORD len = 2 + MultiByteToWideChar( CP_UNIXCP, 0, ptr, -1, NULL, 0 ); - buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); - MultiByteToWideChar( CP_UNIXCP, 0, ptr, -1, buffer, len ); - } - else - { - buffer = HeapAlloc( GetProcessHeap(), 0, sizeof(wineW) + 2 * sizeof(WCHAR) ); - strcpyW( buffer, wineW ); - } - p = buffer + strlenW( buffer ) - strlenW( suffixW ); - if (p > buffer && !strcmpW( p, suffixW )) - { - if (!is_win64) *p = 0; - } - else if (is_win64) strcatW( buffer, suffixW ); - - TRACE( "returning %s\n", debugstr_w(buffer) ); - loader = buffer; + DWORD len = 2 + MultiByteToWideChar( CP_UNIXCP, 0, env, -1, NULL, 0 ); + buffer = heap_alloc( len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_UNIXCP, 0, env, -1, buffer, len ); } - return loader; + else + { + buffer = heap_alloc( sizeof(wineW) + 2 * sizeof(WCHAR) ); + strcpyW( buffer, wineW ); + } + + p = buffer + strlenW( buffer ) - strlenW( suffixW ); + if (p > buffer && !strcmpW( p, suffixW )) + *p = 0; + + if (pcs->is_64bit) + strcatW(buffer, suffixW); + + TRACE( "returning %s\n", debugstr_w(buffer) ); + return buffer; } static const char* get_module_type(enum module_type type, BOOL virtual)