From f30fdd1822462326d3339a21b838d28b623e6486 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 24 Mar 2020 01:53:37 +0100 Subject: [PATCH] dbghelp: Move loader search functions to the end of module files. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/dbghelp/elf_module.c | 116 +++++++++++------------ dlls/dbghelp/macho_module.c | 181 ++++++++++++++++++------------------ 2 files changed, 148 insertions(+), 149 deletions(-) diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index 728025fa405..1c7a77650b1 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -1483,64 +1483,6 @@ static BOOL elf_enum_modules_internal(const struct process* pcs, return TRUE; } -/****************************************************************** - * elf_search_loader - * - * Lookup in a running ELF process the loader, and sets its ELF link - * address (for accessing the list of loaded .so libs) in pcs. - * If flags is ELF_INFO_MODULE, the module for the loader is also - * added as a module into 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 )) - return FALSE; - - if (!pcs->is_64bit) - { - PEB32 *peb32 = (PEB32 *)pbi.PebBaseAddress; - DWORD base32; - - if (!ReadProcessMemory( pcs->handle, &peb32->Reserved[0], &base32, - sizeof(base32), NULL )) - return FALSE; - - base = base32; - } - else - { - if (!ReadProcessMemory( pcs->handle, &pbi.PebBaseAddress->Reserved[0], - &base, sizeof(base), NULL )) - return FALSE; - } - - ret = elf_search_and_load_file(pcs, loader, base, 0, elf_info); - heap_free(loader); - return ret; -} - -/****************************************************************** - * elf_read_wine_loader_dbg_info - * - * Try to find a decent wine executable which could have loaded the debuggee - */ -BOOL elf_read_wine_loader_dbg_info(struct process* pcs) -{ - struct elf_info elf_info; - - elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE; - if (!elf_search_loader(pcs, &elf_info)) return FALSE; - elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1; - module_set_module(elf_info.module, S_WineLoaderW); - return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0; -} - struct elf_enum_user { enum_modules_cb cb; @@ -1720,6 +1662,64 @@ BOOL elf_synchronize_module_list(struct process* pcs) return TRUE; } +/****************************************************************** + * elf_search_loader + * + * Lookup in a running ELF process the loader, and sets its ELF link + * address (for accessing the list of loaded .so libs) in pcs. + * If flags is ELF_INFO_MODULE, the module for the loader is also + * added as a module into 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 )) + return FALSE; + + if (!pcs->is_64bit) + { + PEB32 *peb32 = (PEB32 *)pbi.PebBaseAddress; + DWORD base32; + + if (!ReadProcessMemory( pcs->handle, &peb32->Reserved[0], &base32, + sizeof(base32), NULL )) + return FALSE; + + base = base32; + } + else + { + if (!ReadProcessMemory( pcs->handle, &pbi.PebBaseAddress->Reserved[0], + &base, sizeof(base), NULL )) + return FALSE; + } + + ret = elf_search_and_load_file(pcs, loader, base, 0, elf_info); + heap_free(loader); + return ret; +} + +/****************************************************************** + * elf_read_wine_loader_dbg_info + * + * Try to find a decent wine executable which could have loaded the debuggee + */ +BOOL elf_read_wine_loader_dbg_info(struct process* pcs) +{ + struct elf_info elf_info; + + elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE; + if (!elf_search_loader(pcs, &elf_info)) return FALSE; + elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1; + module_set_module(elf_info.module, S_WineLoaderW); + return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0; +} + #else /* !__ELF__ */ BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap) diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index a35ed5db732..93135c71e79 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -1373,7 +1373,6 @@ static void macho_module_remove(struct process* pcs, struct module_format* modfm HeapFree(GetProcessHeap(), 0, modfmt); } - /****************************************************************** * get_dyld_image_info_address */ @@ -1729,6 +1728,96 @@ BOOL macho_synchronize_module_list(struct process* pcs) return TRUE; } +/****************************************************************** + * macho_enum_modules + * + * Enumerates the Mach-O loaded modules from a running target (hProc) + * This function doesn't require that someone has called SymInitialize + * on this very process. + */ +BOOL macho_enum_modules(struct process* process, enum_modules_cb cb, void* user) +{ + struct macho_info macho_info; + BOOL ret; + + TRACE("(%p, %p, %p)\n", process->handle, cb, user); + macho_info.flags = MACHO_INFO_DEBUG_HEADER | MACHO_INFO_NAME; + ret = macho_enum_modules_internal(process, macho_info.module_name, cb, user); + HeapFree(GetProcessHeap(), 0, (char*)macho_info.module_name); + return ret; +} + +struct macho_load +{ + struct process* pcs; + struct macho_info macho_info; + const WCHAR* name; + BOOL ret; +}; + +/****************************************************************** + * macho_load_cb + * + * Callback for macho_load_module, used to walk the list of loaded + * modules. + */ +static BOOL macho_load_cb(const WCHAR* name, unsigned long addr, void* user) +{ + struct macho_load* ml = user; + const WCHAR* p; + + TRACE("(%s, 0x%08lx, %p)\n", debugstr_w(name), addr, user); + + /* memcmp is needed for matches when bufstr contains also version information + * ml->name: libc.so, name: libc.so.6.0 + */ + p = file_name(name); + if (!memcmp(p, ml->name, lstrlenW(ml->name) * sizeof(WCHAR))) + { + ml->ret = macho_search_and_load_file(ml->pcs, name, addr, &ml->macho_info); + return FALSE; + } + return TRUE; +} + +/****************************************************************** + * macho_load_module + * + * Loads a Mach-O module and stores it in process' module list. + * Also, find module real name and load address from + * the real loaded modules list in pcs address space. + */ +struct module* macho_load_module(struct process* pcs, const WCHAR* name, unsigned long addr) +{ + struct macho_load ml; + + TRACE("(%p/%p, %s, 0x%08lx)\n", pcs, pcs->handle, debugstr_w(name), addr); + + ml.macho_info.flags = MACHO_INFO_MODULE; + ml.ret = FALSE; + + if (pcs->dbg_hdr_addr) /* we're debugging a live target */ + { + ml.pcs = pcs; + /* do only the lookup from the filename, not the path (as we lookup module + * name in the process' loaded module list) + */ + ml.name = file_name(name); + ml.ret = FALSE; + + if (!macho_enum_modules_internal(pcs, NULL, macho_load_cb, &ml)) + return NULL; + } + else if (addr) + { + ml.name = name; + ml.ret = macho_search_and_load_file(pcs, ml.name, addr, &ml.macho_info); + } + if (!ml.ret) return NULL; + assert(ml.macho_info.module); + return ml.macho_info.module; +} + /****************************************************************** * macho_search_loader * @@ -1836,96 +1925,6 @@ BOOL macho_read_wine_loader_dbg_info(struct process* pcs) return (pcs->dbg_hdr_addr = macho_info.dbg_hdr_addr) != 0; } -/****************************************************************** - * macho_enum_modules - * - * Enumerates the Mach-O loaded modules from a running target (hProc) - * This function doesn't require that someone has called SymInitialize - * on this very process. - */ -BOOL macho_enum_modules(struct process* process, enum_modules_cb cb, void* user) -{ - struct macho_info macho_info; - BOOL ret; - - TRACE("(%p, %p, %p)\n", process->handle, cb, user); - macho_info.flags = MACHO_INFO_DEBUG_HEADER | MACHO_INFO_NAME; - ret = macho_enum_modules_internal(process, macho_info.module_name, cb, user); - HeapFree(GetProcessHeap(), 0, (char*)macho_info.module_name); - return ret; -} - -struct macho_load -{ - struct process* pcs; - struct macho_info macho_info; - const WCHAR* name; - BOOL ret; -}; - -/****************************************************************** - * macho_load_cb - * - * Callback for macho_load_module, used to walk the list of loaded - * modules. - */ -static BOOL macho_load_cb(const WCHAR* name, unsigned long addr, void* user) -{ - struct macho_load* ml = user; - const WCHAR* p; - - TRACE("(%s, 0x%08lx, %p)\n", debugstr_w(name), addr, user); - - /* memcmp is needed for matches when bufstr contains also version information - * ml->name: libc.so, name: libc.so.6.0 - */ - p = file_name(name); - if (!memcmp(p, ml->name, lstrlenW(ml->name) * sizeof(WCHAR))) - { - ml->ret = macho_search_and_load_file(ml->pcs, name, addr, &ml->macho_info); - return FALSE; - } - return TRUE; -} - -/****************************************************************** - * macho_load_module - * - * Loads a Mach-O module and stores it in process' module list. - * Also, find module real name and load address from - * the real loaded modules list in pcs address space. - */ -struct module* macho_load_module(struct process* pcs, const WCHAR* name, unsigned long addr) -{ - struct macho_load ml; - - TRACE("(%p/%p, %s, 0x%08lx)\n", pcs, pcs->handle, debugstr_w(name), addr); - - ml.macho_info.flags = MACHO_INFO_MODULE; - ml.ret = FALSE; - - if (pcs->dbg_hdr_addr) /* we're debugging a live target */ - { - ml.pcs = pcs; - /* do only the lookup from the filename, not the path (as we lookup module - * name in the process' loaded module list) - */ - ml.name = file_name(name); - ml.ret = FALSE; - - if (!macho_enum_modules_internal(pcs, NULL, macho_load_cb, &ml)) - return NULL; - } - else if (addr) - { - ml.name = name; - ml.ret = macho_search_and_load_file(pcs, ml.name, addr, &ml.macho_info); - } - if (!ml.ret) return NULL; - assert(ml.macho_info.module); - return ml.macho_info.module; -} - #else /* HAVE_MACH_O_LOADER_H */ BOOL macho_synchronize_module_list(struct process* pcs)