From: Eric Pouech epouech@codeweavers.com
Under MacOS, lots of modules were incorrectly reported as 'ELF' modules. Use a generic model to advertize from dbghelp to winedbg if a module is a system module, and if so, what's its underlying file format.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/dbghelp_private.h | 1 - dlls/dbghelp/elf_module.c | 4 ++- dlls/dbghelp/macho_module.c | 2 ++ dlls/dbghelp/module.c | 11 ++----- include/dbghelp.h | 6 ++++ programs/winedbg/info.c | 53 ++++++++++++++++++++++++++-------- 6 files changed, 55 insertions(+), 22 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index edae3f9324a..05a1b53d41c 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -724,7 +724,6 @@ extern BOOL macho_read_wine_loader_dbg_info(struct process* pcs, ULONG_P void minidump_add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva) DECLSPEC_HIDDEN;
/* module.c */ -extern const WCHAR S_ElfW[] DECLSPEC_HIDDEN; extern const WCHAR S_WineLoaderW[] DECLSPEC_HIDDEN; extern const struct loader_ops no_loader_ops DECLSPEC_HIDDEN; extern const struct loader_ops empty_loader_ops DECLSPEC_HIDDEN; diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index a2a60752a68..248eee60734 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -1083,7 +1083,7 @@ static BOOL elf_load_debug_info_from_map(struct module* module, lret = dwarf2_parse(module, module->reloc_delta, thunks, fmap); ret = ret || lret; } - if (wcsstr(module->modulename, S_ElfW) || !wcscmp(module->modulename, S_WineLoaderW)) + if (module->format_info[DFI_ELF] || !wcscmp(module->modulename, S_WineLoaderW)) { /* add the thunks for native libraries */ if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY)) @@ -1249,6 +1249,7 @@ static BOOL elf_load_file_from_fmap(struct process* pcs, const WCHAR* filename, HeapFree(GetProcessHeap(), 0, modfmt); return FALSE; } + elf_info->module->module.SystemModule = WINE_SYSMODULE_ELF; elf_info->module->reloc_delta = elf_info->module->module.BaseOfImage - fmap->u.elf.elf_start; elf_module_info = (void*)(modfmt + 1); elf_info->module->format_info[DFI_ELF] = modfmt; @@ -1791,6 +1792,7 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs, ULONG_PTR addr) TRACE("Found ELF debug header %#I64x\n", elf_info.dbg_hdr_addr); elf_info.module->format_info[DFI_ELF]->u.elf_info->elf_loader = 1; module_set_module(elf_info.module, S_WineLoaderW); + elf_info.module->module.SystemModule = WINE_SYSMODULE_ELF; pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr; pcs->loader = &elf_loader_ops; return TRUE; diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index a36e737c618..b8783eac7e9 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -1517,6 +1517,7 @@ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename, HeapFree(GetProcessHeap(), 0, modfmt); goto leave; } + macho_info->module->module.SystemModule = WINE_SYSMODULE_MACHO; macho_info->module->reloc_delta = macho_info->module->module.BaseOfImage - fmap.u.macho.segs_start; macho_module_info = (void*)(modfmt + 1); macho_info->module->format_info[DFI_MACHO] = modfmt; @@ -1948,6 +1949,7 @@ BOOL macho_read_wine_loader_dbg_info(struct process* pcs, ULONG_PTR addr) if (!macho_search_loader(pcs, &macho_info)) return FALSE; macho_info.module->format_info[DFI_MACHO]->u.macho_info->is_loader = 1; module_set_module(macho_info.module, S_WineLoaderW); + macho_info.module->module.SystemModule = WINE_SYSMODULE_MACHO; pcs->loader = &macho_loader_ops; TRACE("Found macho debug header %#Ix\n", pcs->dbg_hdr_addr); return TRUE; diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index 6c69031ddfd..e52ee7e35a1 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -35,7 +35,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
#define NOTE_GNU_BUILD_ID 3
-const WCHAR S_ElfW[] = L"<elf>"; const WCHAR S_WineLoaderW[] = L"<wine-loader>"; static const WCHAR * const ext[] = {L".acm", L".dll", L".drv", L".exe", L".ocx", L".vxd", NULL};
@@ -103,7 +102,7 @@ static BOOL is_wine_loader(const WCHAR *module) static void module_fill_module(const WCHAR* in, WCHAR* out, size_t size) { const WCHAR *ptr, *endptr; - size_t len, l; + size_t len;
endptr = in + lstrlenW(in); endptr -= match_ext(in, endptr - in); @@ -113,12 +112,6 @@ static void module_fill_module(const WCHAR* in, WCHAR* out, size_t size) out[len] = '\0'; if (is_wine_loader(out)) lstrcpynW(out, S_WineLoaderW, size); - else - { - if (len > 3 && !wcsicmp(&out[len - 3], L".so") && - (l = match_ext(out, len - 3))) - lstrcpyW(&out[len - l - 3], L"<elf>"); - } while ((*out = towlower(*out))) out++; }
@@ -229,6 +222,8 @@ struct module* module_new(struct process* pcs, const WCHAR* name, module->module.Reserved = 0; module->module.Magic = WINE_IMAGEHLP_MODULE_MAGIC;
+ module->module.SystemModule = WINE_SYSMODULE_NONE; + module->reloc_delta = 0; module->type = type; module->is_virtual = virtual; diff --git a/include/dbghelp.h b/include/dbghelp.h index e864052ab32..030e328a9ec 100644 --- a/include/dbghelp.h +++ b/include/dbghelp.h @@ -295,6 +295,12 @@ typedef struct FORMAT_DWARF = 0x0000000F, FORMAT_STABS = 0x00010000, } DebugFormatMask; + enum wine_sysmodule + { + WINE_SYSMODULE_NONE, + WINE_SYSMODULE_ELF, + WINE_SYSMODULE_MACHO, + } SystemModule; } WINE_IMAGEHLP_MODULEW64; #define WINE_IMAGEHLP_MODULE_MAGIC 0xB0507E17 #endif /* __WINESRC__ */ diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c index a46ecec923a..1fde9641fa1 100644 --- a/programs/winedbg/info.c +++ b/programs/winedbg/info.c @@ -149,10 +149,20 @@ static const char* get_symtype_str(const WINE_IMAGEHLP_MODULEW64* mi) } }
+enum module_kind {MODKIND_SYSTEM = 0x00, MODKIND_ELF = 0x01, MODKIND_MACHO = 0x02, + MODKIND_PE = 0x10, MODKIND_PE_FAKEDLL = 0x11, + MODKIND_ERROR = 0x80}; + +static inline enum module_kind modkind_get_family(enum module_kind mk) +{ + return mk & 0xf0; +} + struct info_module { WINE_IMAGEHLP_MODULEW64 mi; char name[64]; + enum module_kind kind; };
struct info_modules @@ -210,6 +220,20 @@ static inline BOOL module_is_container(const struct info_module *wmod_cntnr, wmod_child->mi.BaseOfImage + wmod_child->mi.ImageSize; }
+static inline const char* module_get_type_name(const struct info_module* mod) +{ + switch (mod->kind) + { + case MODKIND_SYSTEM: return "System"; + case MODKIND_ELF: return "ELF"; + case MODKIND_MACHO: return "Mach-O"; + case MODKIND_PE_FAKEDLL: + case MODKIND_PE: return "PE"; + case MODKIND_ERROR: break; + } + return ""; +} + static BOOL CALLBACK info_mod_cb(PCSTR mod_name, DWORD64 base, PVOID ctx) { struct info_modules *im = ctx; @@ -225,9 +249,17 @@ static BOOL CALLBACK info_mod_cb(PCSTR mod_name, DWORD64 base, PVOID ctx) im->modules[im->num_used].mi.Magic = WINE_IMAGEHLP_MODULE_MAGIC; if (SymGetModuleInfoW64(dbg_curr_process->handle, base, (IMAGEHLP_MODULEW64*)&im->modules[im->num_used].mi)) { - const int dst_len = sizeof(im->modules[im->num_used].name); - lstrcpynA(im->modules[im->num_used].name, mod_name, dst_len - 1); - im->modules[im->num_used].name[dst_len - 1] = 0; + struct info_module* mod = &im->modules[im->num_used]; + static const size_t dst_len = sizeof(mod->name) - 1; + + switch (mod->mi.SystemModule) + { + case WINE_SYSMODULE_ELF: mod->kind = MODKIND_ELF; break; + case WINE_SYSMODULE_MACHO: mod->kind = MODKIND_MACHO; break; + case WINE_SYSMODULE_NONE: mod->kind = MODKIND_PE; break; + } + lstrcpynA(mod->name, mod_name, dst_len); + mod->name[dst_len] = 0; im->num_used++; } return TRUE; @@ -286,14 +318,14 @@ void info_win32_module(DWORD64 base, BOOL multi_machine) (base < im.modules[i].mi.BaseOfImage || base >= im.modules[i].mi.BaseOfImage + im.modules[i].mi.ImageSize)) continue; if (!multi_machine && machine != im.modules[i].mi.MachineType) continue; - if (strstr(im.modules[i].name, "<elf>")) + if (modkind_get_family(im.modules[i].kind) == MODKIND_SYSTEM) { - dbg_printf("ELF\t"); + dbg_printf("%s\t", module_get_type_name(&im.modules[i])); module_print_info(&im.modules[i], FALSE, multi_machine); /* print all modules embedded in this one */ for (j = 0; j < im.num_used; j++) { - if (!strstr(im.modules[j].name, "<elf>") && module_is_container(&im.modules[i], &im.modules[j])) + if (modkind_get_family(im.modules[j].kind) == MODKIND_PE && module_is_container(&im.modules[i], &im.modules[j])) { dbg_printf(" \-PE\t"); module_print_info(&im.modules[j], TRUE, multi_machine); @@ -303,16 +335,13 @@ void info_win32_module(DWORD64 base, BOOL multi_machine) else { /* check module is not embedded in another module */ - for (j = 0; j < im.num_used; j++) + for (j = 0; j < im.num_used; j++) { - if (strstr(im.modules[j].name, "<elf>") && module_is_container(&im.modules[j], &im.modules[i])) + if (modkind_get_family(im.modules[j].kind) == MODKIND_SYSTEM && module_is_container(&im.modules[j], &im.modules[i])) break; } if (j < im.num_used) continue; - if (strstr(im.modules[i].name, ".so") || strchr(im.modules[i].name, '<')) - dbg_printf("ELF\t"); - else - dbg_printf("PE\t"); + dbg_printf("%s\t", module_get_type_name(&im.modules[i])); module_print_info(&im.modules[i], FALSE, multi_machine); } num_printed++;