From fec0157585e9d8bd03a8a71d1ed9b9d7ca59cb56 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 24 Mar 2020 01:54:07 +0100 Subject: [PATCH] dbghelp: Introduce loader_ops to abstract platform-specific loader and use it to synchronize module list. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/dbghelp/dbghelp.c | 4 ++-- dlls/dbghelp/dbghelp_private.h | 9 +++++++-- dlls/dbghelp/elf_module.c | 18 ++++++++++-------- dlls/dbghelp/macho_module.c | 18 ++++++++++-------- dlls/dbghelp/module.c | 23 ++++++++++++----------- 5 files changed, 41 insertions(+), 31 deletions(-) diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c index a8e04c73035..0372f901272 100644 --- a/dlls/dbghelp/dbghelp.c +++ b/dlls/dbghelp/dbghelp.c @@ -334,6 +334,7 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP pcs->handle = hProcess; pcs->is_64bit = (sizeof(void *) == 8 || wow64) && !child_wow64; + pcs->loader = &no_loader_ops; /* platform-specific initialization will override it if loader debug info can be found */ if (UserSearchPath) { @@ -379,8 +380,7 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP { if (fInvadeProcess) EnumerateLoadedModulesW64(hProcess, process_invade_cb, hProcess); - elf_synchronize_module_list(pcs); - macho_synchronize_module_list(pcs); + pcs->loader->synchronize_module_list(pcs); } else if (fInvadeProcess) { diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index ad6679a3d3e..ab1644265ff 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -387,10 +387,16 @@ struct module struct wine_rb_tree sources_offsets_tree; }; +struct loader_ops +{ + BOOL (*synchronize_module_list)(struct process* process); +}; + struct process { struct process* next; HANDLE handle; + const struct loader_ops* loader; WCHAR* search_path; PSYMBOL_REGISTERED_CALLBACK64 reg_cb; @@ -601,7 +607,6 @@ extern BOOL elf_load_debug_info(struct module* module) DECLSPEC_HIDDEN; extern struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned long) DECLSPEC_HIDDEN; extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs) DECLSPEC_HIDDEN; -extern BOOL elf_synchronize_module_list(struct process* pcs) DECLSPEC_HIDDEN; struct elf_thunk_area; extern int elf_is_in_thunk_area(unsigned long addr, const struct elf_thunk_area* thunks) DECLSPEC_HIDDEN; @@ -612,7 +617,6 @@ extern BOOL macho_load_debug_info(struct process *pcs, struct module* mo extern struct module* macho_load_module(struct process* pcs, const WCHAR* name, unsigned long) DECLSPEC_HIDDEN; extern BOOL macho_read_wine_loader_dbg_info(struct process* pcs) DECLSPEC_HIDDEN; -extern BOOL macho_synchronize_module_list(struct process* pcs) DECLSPEC_HIDDEN; /* minidump.c */ void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva) DECLSPEC_HIDDEN; @@ -621,6 +625,7 @@ void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size extern const WCHAR S_ElfW[] DECLSPEC_HIDDEN; extern const WCHAR S_WineLoaderW[] DECLSPEC_HIDDEN; extern const WCHAR S_SlashW[] DECLSPEC_HIDDEN; +extern const struct loader_ops no_loader_ops DECLSPEC_HIDDEN; extern struct module* module_find_by_addr(const struct process* pcs, DWORD64 addr, diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index 1c7a77650b1..2a4b349c49b 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -1623,7 +1623,7 @@ struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned * - if a module is in debuggee and not in pcs, it's loaded into pcs * - if a module is in pcs and not in debuggee, it's unloaded from pcs */ -BOOL elf_synchronize_module_list(struct process* pcs) +static BOOL elf_synchronize_module_list(struct process* pcs) { struct module* module; struct elf_load el; @@ -1704,6 +1704,11 @@ static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info) return ret; } +static const struct loader_ops elf_loader_ops = +{ + elf_synchronize_module_list, +}; + /****************************************************************** * elf_read_wine_loader_dbg_info * @@ -1714,10 +1719,12 @@ 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; + if (!elf_search_loader(pcs, &elf_info) || !elf_info.dbg_hdr_addr) 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; + pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr; + pcs->loader = &elf_loader_ops; + return TRUE; } #else /* !__ELF__ */ @@ -1727,11 +1734,6 @@ BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap) return FALSE; } -BOOL elf_synchronize_module_list(struct process* pcs) -{ - return FALSE; -} - BOOL elf_fetch_file_info(const WCHAR* name, DWORD_PTR* base, DWORD* size, DWORD* checksum) { diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index 93135c71e79..071d7bed5c5 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -1694,7 +1694,7 @@ static BOOL macho_enum_sync_cb(const WCHAR* name, unsigned long addr, void* user * - if a module is in debuggee and not in pcs, it's loaded into pcs * - if a module is in pcs and not in debuggee, it's unloaded from pcs */ -BOOL macho_synchronize_module_list(struct process* pcs) +static BOOL macho_synchronize_module_list(struct process* pcs) { struct module* module; struct macho_sync ms; @@ -1908,6 +1908,11 @@ static BOOL macho_search_loader(struct process* pcs, struct macho_info* macho_in return ret; } +static const struct loader_ops macho_loader_ops = +{ + macho_synchronize_module_list, +}; + /****************************************************************** * macho_read_wine_loader_dbg_info * @@ -1919,19 +1924,16 @@ BOOL macho_read_wine_loader_dbg_info(struct process* pcs) TRACE("(%p/%p)\n", pcs, pcs->handle); macho_info.flags = MACHO_INFO_DEBUG_HEADER | MACHO_INFO_MODULE; - if (!macho_search_loader(pcs, &macho_info)) return FALSE; + if (!macho_search_loader(pcs, &macho_info) || !macho_info.dbg_hdr_addr) return FALSE; macho_info.module->format_info[DFI_MACHO]->u.macho_info->is_loader = 1; module_set_module(macho_info.module, S_WineLoaderW); - return (pcs->dbg_hdr_addr = macho_info.dbg_hdr_addr) != 0; + pcs->dbg_hdr_addr = macho_info.dbg_hdr_addr; + pcs->loader = &macho_loader_ops; + return TRUE; } #else /* HAVE_MACH_O_LOADER_H */ -BOOL macho_synchronize_module_list(struct process* pcs) -{ - return FALSE; -} - BOOL macho_fetch_file_info(HANDLE process, const WCHAR* name, unsigned long load_addr, DWORD_PTR* base, DWORD* size, DWORD* checksum) { diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 74502a9d6b7..5ff7e029055 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -529,15 +529,6 @@ enum module_type module_get_type_by_name(const WCHAR* name) return DMT_PE; } -/****************************************************************** - * refresh_module_list - */ -static BOOL refresh_module_list(struct process* pcs) -{ - /* force transparent ELF and Mach-O loading / unloading */ - return elf_synchronize_module_list(pcs) || macho_synchronize_module_list(pcs); -} - static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fmap, DWORD link_crc) { DWORD read_bytes; @@ -875,7 +866,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam if (Flags & ~(SLMFLAG_VIRTUAL)) FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName)); - refresh_module_list(pcs); + pcs->loader->synchronize_module_list(pcs); /* this is a Wine extension to the API just to redo the synchronisation */ if (!wImageName && !hFile) return 0; @@ -1409,7 +1400,7 @@ BOOL WINAPI SymRefreshModuleList(HANDLE hProcess) if (!(pcs = process_find_by_handle(hProcess))) return FALSE; - return refresh_module_list(pcs); + return pcs->loader->synchronize_module_list(pcs); } /*********************************************************************** @@ -1434,3 +1425,13 @@ PVOID WINAPI SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) return dbghelp_current_cpu->find_runtime_function(module, AddrBase); } + +static BOOL native_synchronize_module_list(struct process* pcs) +{ + return FALSE; +} + +const struct loader_ops no_loader_ops = +{ + native_synchronize_module_list, +};