From: Eric Pouech epouech@codeweavers.com
In following patches, we'll add a bunch of new interfaces here. Also, hide partially module_format walking with some helpers.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/dbghelp_private.h | 41 +++++++++++++++++++++++++++++----- dlls/dbghelp/dwarf.c | 21 ++++++++++------- dlls/dbghelp/elf_module.c | 11 ++++++--- dlls/dbghelp/macho_module.c | 11 ++++++--- dlls/dbghelp/module.c | 11 ++++----- dlls/dbghelp/msc.c | 16 ++++++++----- dlls/dbghelp/pe_module.c | 11 ++++++--- dlls/dbghelp/symbol.c | 14 +++++------- dlls/dbghelp/type.c | 16 +++++-------- 9 files changed, 98 insertions(+), 54 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index c669109a7f9..fb55e4c89f7 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -414,14 +414,22 @@ enum format_info DFI_LAST };
-struct module_format +struct module_format; +struct module_format_vtable { - struct module* module; - void (*remove)(struct process* pcs, struct module_format* modfmt); - void (*loc_compute)(struct process* pcs, - const struct module_format* modfmt, + /* module handling */ + void (*remove)(struct module_format* modfmt); + /* stack walk */ + void (*loc_compute)(const struct module_format* modfmt, const struct symt_function* func, struct location* loc); +}; + +struct module_format +{ + struct module* module; + const struct module_format_vtable* vtable; + union { struct elf_module_info* elf_info; @@ -478,6 +486,29 @@ struct module struct wine_rb_tree sources_offsets_tree; };
+struct module_format_vtable_iterator +{ + int dfi; + struct module_format *modfmt; +}; + +#define MODULE_FORMAT_VTABLE_INDEX(f) (offsetof(struct module_format_vtable, f) / sizeof(void*)) + +static inline BOOL module_format_vtable_iterator_next(struct module *module, struct module_format_vtable_iterator *iter, size_t method_index) +{ + for ( ; iter->dfi < DFI_LAST; iter->dfi++) + { + iter->modfmt = module->format_info[iter->dfi]; + if (iter->modfmt && ((const void**)iter->modfmt->vtable)[method_index]) + { + iter->dfi++; + return TRUE; + } + } + iter->modfmt = NULL; + return FALSE; +} + typedef BOOL (*enum_modules_cb)(const WCHAR*, ULONG_PTR addr, void* user);
struct loader_ops diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 3971ff64988..86d41cd1970 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -3129,12 +3129,12 @@ static const dwarf2_cuhead_t* get_cuhead_from_func(const struct symt_function* f
static enum location_error compute_call_frame_cfa(struct module* module, ULONG_PTR ip, struct location* frame);
-static enum location_error loc_compute_frame(struct process* pcs, - const struct module_format* modfmt, +static enum location_error loc_compute_frame(const struct module_format* modfmt, const struct symt_function* func, DWORD_PTR ip, const dwarf2_cuhead_t* head, struct location* frame) { + struct process *pcs = modfmt->module->process; struct symt** psym = NULL; struct location* pframe; dwarf2_traverse_context_t lctx; @@ -4007,8 +4007,7 @@ static enum location_error compute_call_frame_cfa(struct module* module, ULONG_P return 0; }
-static void dwarf2_location_compute(struct process* pcs, - const struct module_format* modfmt, +static void dwarf2_location_compute(const struct module_format* modfmt, const struct symt_function* func, struct location* loc) { @@ -4026,10 +4025,11 @@ static void dwarf2_location_compute(struct process* pcs, } else { + struct process *pcs = modfmt->module->process; /* instruction pointer relative to compiland's start */ ip = pcs->localscope_pc - ((struct symt_compiland*)func->container)->address;
- if ((err = loc_compute_frame(pcs, modfmt, func, ip, head, &frame)) == 0) + if ((err = loc_compute_frame(modfmt, func, ip, head, &frame)) == 0) { switch (loc->kind) { @@ -4187,7 +4187,7 @@ static inline void dwarf2_fini_section(dwarf2_section_t* section) HeapFree(GetProcessHeap(), 0, (void*)section->address); }
-static void dwarf2_module_remove(struct process* pcs, struct module_format* modfmt) +static void dwarf2_module_remove(struct module_format* modfmt) { dwarf2_fini_section(&modfmt->u.dwarf2_info->debug_loc); dwarf2_fini_section(&modfmt->u.dwarf2_info->debug_frame); @@ -4293,6 +4293,12 @@ static BOOL dwarf2_unload_CU_module(dwarf2_parse_module_context_t* module_ctx) return TRUE; }
+static const struct module_format_vtable dwarf2_module_format_vtable = +{ + dwarf2_module_remove, + dwarf2_location_compute, +}; + BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, const struct elf_thunk_area* thunks, struct image_file_map* fmap) @@ -4340,8 +4346,7 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, goto leave; } dwarf2_modfmt->module = module; - dwarf2_modfmt->remove = dwarf2_module_remove; - dwarf2_modfmt->loc_compute = dwarf2_location_compute; + dwarf2_modfmt->vtable = &dwarf2_module_format_vtable; dwarf2_modfmt->u.dwarf2_info = (struct dwarf2_module_info_s*)(dwarf2_modfmt + 1); dwarf2_modfmt->u.dwarf2_info->word_size = fmap->addr_size / 8; /* set the word_size for eh_frame parsing */ dwarf2_modfmt->module->format_info[DFI_DWARF] = dwarf2_modfmt; diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index 8596d60483a..83c4ea898e8 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -602,7 +602,7 @@ BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap) return elf_map_file(&emfd, fmap); }
-static void elf_module_remove(struct process* pcs, struct module_format* modfmt) +static void elf_module_remove(struct module_format* modfmt) { image_unmap_file(&modfmt->u.elf_info->file_map); HeapFree(GetProcessHeap(), 0, modfmt); @@ -1142,6 +1142,12 @@ static BOOL elf_fetch_file_info(struct process* process, const WCHAR* name, ULON return TRUE; }
+static const struct module_format_vtable elf_module_format_vtable = +{ + elf_module_remove, + NULL, +}; + static BOOL elf_load_file_from_fmap(struct process* pcs, const WCHAR* filename, struct image_file_map* fmap, ULONG_PTR load_offset, ULONG_PTR dyn_addr, struct elf_info* elf_info) @@ -1253,8 +1259,7 @@ static BOOL elf_load_file_from_fmap(struct process* pcs, const WCHAR* filename, elf_module_info = (void*)(modfmt + 1); elf_info->module->format_info[DFI_ELF] = modfmt; modfmt->module = elf_info->module; - modfmt->remove = elf_module_remove; - modfmt->loc_compute = NULL; + modfmt->vtable = &elf_module_format_vtable; modfmt->u.elf_info = elf_module_info;
elf_module_info->elf_addr = load_offset; diff --git a/dlls/dbghelp/macho_module.c b/dlls/dbghelp/macho_module.c index 491e7188009..234136fa92d 100644 --- a/dlls/dbghelp/macho_module.c +++ b/dlls/dbghelp/macho_module.c @@ -1479,12 +1479,18 @@ static BOOL macho_fetch_file_info(struct process* process, const WCHAR* name, UL /****************************************************************** * macho_module_remove */ -static void macho_module_remove(struct process* pcs, struct module_format* modfmt) +static void macho_module_remove(struct module_format* modfmt) { macho_unmap_file(&modfmt->u.macho_info->file_map); HeapFree(GetProcessHeap(), 0, modfmt); }
+static const struct module_format_vtable macho_module_format_vtable = +{ + macho_module_remove, + NULL, +}; + /****************************************************************** * macho_load_file * @@ -1538,8 +1544,7 @@ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename, macho_info->module->format_info[DFI_MACHO] = modfmt;
modfmt->module = macho_info->module; - modfmt->remove = macho_module_remove; - modfmt->loc_compute = NULL; + modfmt->vtable = &macho_module_format_vtable; modfmt->u.macho_info = macho_module_info;
macho_module_info->load_addr = load_addr; diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index ce49ef2744a..3d0c5ba7549 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -1023,9 +1023,8 @@ DWORD64 WINAPI SymLoadModule64(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, */ BOOL module_remove(struct process* pcs, struct module* module) { - struct module_format*modfmt; + struct module_format_vtable_iterator iter = {}; struct module** p; - unsigned i;
TRACE("%s (%p)\n", debugstr_w(module->modulename), module);
@@ -1046,11 +1045,9 @@ BOOL module_remove(struct process* pcs, struct module* module) } } } - for (i = 0; i < DFI_LAST; i++) - { - if ((modfmt = module->format_info[i]) && modfmt->remove) - modfmt->remove(pcs, module->format_info[i]); - } + while (module_format_vtable_iterator_next(module, &iter, MODULE_FORMAT_VTABLE_INDEX(remove))) + iter.modfmt->vtable->remove(iter.modfmt); + hash_table_destroy(&module->ht_symbols); hash_table_destroy(&module->ht_types); HeapFree(GetProcessHeap(), 0, module->sources); diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index b3e15e2eda3..db06b186edb 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -2866,8 +2866,7 @@ static BOOL codeview_is_inside(const struct cv_local_info* locinfo, const struct return TRUE; }
-static void pdb_location_compute(struct process* pcs, - const struct module_format* modfmt, +static void pdb_location_compute(const struct module_format* modfmt, const struct symt_function* func, struct location* loc) { @@ -2880,7 +2879,7 @@ static void pdb_location_compute(struct process* pcs, locinfo->kind != 0; locinfo = (const struct cv_local_info*)((const char*)(locinfo + 1) + locinfo->ngaps * sizeof(locinfo->gaps[0]))) { - if (!codeview_is_inside(locinfo, func, pcs->localscope_pc)) continue; + if (!codeview_is_inside(locinfo, func, modfmt->module->process->localscope_pc)) continue; switch (locinfo->kind) { case S_DEFRANGE: @@ -3266,7 +3265,7 @@ static const char* pdb_get_string_table_entry(const PDB_STRING_TABLE* table, uns return (!table || offset >= table->length) ? NULL : (const char*)(table + 1) + offset; }
-static void pdb_module_remove(struct process* pcsn, struct module_format* modfmt) +static void pdb_module_remove(struct module_format* modfmt) { unsigned i;
@@ -3972,6 +3971,12 @@ static BOOL pdb_process_internal(const struct process *pcs, return TRUE; }
+static const struct module_format_vtable pdb_module_format_vtable = +{ + pdb_module_remove, + pdb_location_compute, +}; + static BOOL pdb_process_file(const struct process *pcs, const struct msc_debug_info *msc_dbg, const char *filename, const GUID *guid, DWORD timestamp, DWORD age) @@ -3991,8 +3996,7 @@ static BOOL pdb_process_file(const struct process *pcs, pdb_module_info = (void*)(modfmt + 1); msc_dbg->module->format_info[DFI_PDB] = modfmt; modfmt->module = msc_dbg->module; - modfmt->remove = pdb_module_remove; - modfmt->loc_compute = pdb_location_compute; + modfmt->vtable = &pdb_module_format_vtable; modfmt->u.pdb_info = pdb_module_info;
memset(cv_zmodules, 0, sizeof(cv_zmodules)); diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c index bd3d6000535..1f2022fc1af 100644 --- a/dlls/dbghelp/pe_module.c +++ b/dlls/dbghelp/pe_module.c @@ -387,7 +387,7 @@ BOOL pe_unlock_region(struct module *module, const BYTE* region) return TRUE; }
-static void pe_module_remove(struct process* pcs, struct module_format* modfmt) +static void pe_module_remove(struct module_format* modfmt) { image_unmap_file(&modfmt->u.pe_info->fmap); HeapFree(GetProcessHeap(), 0, modfmt); @@ -802,6 +802,12 @@ static BOOL search_builtin_pe(void *param, HANDLE handle, const WCHAR *path) return TRUE; }
+static const struct module_format_vtable pe_module_format_vtable = +{ + pe_module_remove, + NULL, +}; + /****************************************************************** * pe_load_native_module * @@ -877,8 +883,7 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name, { module->real_path = real_path ? pool_wcsdup(&module->pool, real_path) : NULL; modfmt->module = module; - modfmt->remove = pe_module_remove; - modfmt->loc_compute = NULL; + modfmt->vtable = &pe_module_format_vtable; module->format_info[DFI_PE] = modfmt; module->reloc_delta = base - PE_FROM_OPTHDR(&modfmt->u.pe_info->fmap, ImageBase); } diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 4fdd0a141be..7edf11a19b9 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -733,17 +733,13 @@ static void symt_fill_sym_info(struct module_pair* pair,
if (loc.kind >= loc_user) { - unsigned i; - struct module_format* modfmt; + struct module_format_vtable_iterator iter = {};
- for (i = 0; i < DFI_LAST; i++) + while ((module_format_vtable_iterator_next(pair->effective, &iter, + MODULE_FORMAT_VTABLE_INDEX(loc_compute)))) { - modfmt = pair->effective->format_info[i]; - if (modfmt && modfmt->loc_compute) - { - modfmt->loc_compute(pair->pcs, modfmt, func, &loc); - break; - } + iter.modfmt->vtable->loc_compute(iter.modfmt, func, &loc); + break; } } switch (loc.kind) diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c index a3ad80aacbb..b8bfd7ff369 100644 --- a/dlls/dbghelp/type.c +++ b/dlls/dbghelp/type.c @@ -1039,19 +1039,15 @@ BOOL symt_get_info(struct module* module, const struct symt* type, case DataIsParam: { struct location loc = ((const struct symt_data*)type)->u.var; - unsigned i; - struct module_format* modfmt; + struct module_format_vtable_iterator iter = {};
if (loc.kind < loc_user) return FALSE; - for (i = 0; i < DFI_LAST; i++) + while ((module_format_vtable_iterator_next(module, &iter, + MODULE_FORMAT_VTABLE_INDEX(loc_compute)))) { - modfmt = module->format_info[i]; - if (modfmt && modfmt->loc_compute) - { - modfmt->loc_compute(module->process, modfmt, - (const struct symt_function*)((const struct symt_data*)type)->container, &loc); - break; - } + iter.modfmt->vtable->loc_compute(iter.modfmt, + (const struct symt_function*)((const struct symt_data*)type)->container, &loc); + break; } if (loc.kind != loc_absolute) return FALSE; V_VT(&X(VARIANT)) = VT_UI4; /* FIXME */