The following series implements: - finish of refactoring for proper di / cu relationship wrt. image location (regular vs dwz file) - support of alternate .dwz file - references to DIE into an alternate .dwz file
A+
---
Eric Pouech (12): dbghelp: separate alternate debug file lookup dbghelp: Added support for locating a .dwz file (GNU extension) attached to a debug file dbghelp/dwarf: store in dwarf2 module's information a potential link to an external DWZ file dbghelp/dwarf: Now properly handling DW_FORM_GNU_strp_alt dbghelp/dwarf: Now loading the alternate dwarf file content as we do for a regular dwarf module dbghelp/dwarf: No longer passing a parse context to dwarf2_find_attribute dbghelp/dwarf: No longer passing a unit context to dwarf2_get_cpp_name dbghelp/dwarf: Folded printing info about unit context when printing debug_info's dbghelp/dwarf: No longer passing a unit context when parsing debug_info content dbghelp/dwarf! Added a new helper to jump into another debug_info dbghelp/dwarf: added proper support for DW_FORM_GNU_ref_alt dbghelp/dwarf: When loading a DWZ alternate file, don't force loading of all debug_infos
dlls/dbghelp/dwarf.c | 610 +++++++++++++++++++++-------------- dlls/dbghelp/image_private.h | 1 + dlls/dbghelp/module.c | 100 ++++++ 3 files changed, 463 insertions(+), 248 deletions(-)
Splitted in two different (and disjoint) the functions for checking that an alternate debug file matches the expected one - the first based on crc - the second based on GNU build-id
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/module.c | 99 +++++++++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 40 deletions(-)
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index cda12f4c350..c71e016b824 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -467,12 +467,13 @@ static BOOL module_is_container_loaded(const struct process* pcs, return FALSE; }
-static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fmap, DWORD link_crc) +static BOOL image_check_debug_link_crc(const WCHAR* file, struct image_file_map* fmap, DWORD link_crc) { DWORD read_bytes; HANDLE handle; WCHAR *path; WORD magic; + DWORD crc; BOOL ret;
path = get_dos_file_name(file); @@ -480,15 +481,12 @@ static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fma heap_free(path); if (handle == INVALID_HANDLE_VALUE) return FALSE;
- if (link_crc) + crc = calc_crc32(handle); + if (crc != link_crc) { - DWORD crc = calc_crc32(handle); - if (crc != link_crc) - { - WARN("Bad CRC for file %s (got %08x while expecting %08x)\n", debugstr_w(file), crc, link_crc); - CloseHandle(handle); - return FALSE; - } + WARN("Bad CRC for file %s (got %08x while expecting %08x)\n", debugstr_w(file), crc, link_crc); + CloseHandle(handle); + return FALSE; }
SetFilePointer(handle, 0, 0, FILE_BEGIN); @@ -500,6 +498,49 @@ static BOOL image_check_debug_link(const WCHAR* file, struct image_file_map* fma return ret; }
+static BOOL image_check_debug_link_gnu_id(const WCHAR* file, struct image_file_map* fmap, const BYTE* id, unsigned idlen) +{ + struct image_section_map buildid_sect; + DWORD read_bytes; + HANDLE handle; + WCHAR *path; + WORD magic; + BOOL ret; + + path = get_dos_file_name(file); + handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + heap_free(path); + if (handle == INVALID_HANDLE_VALUE) return FALSE; + + TRACE("Located debug information file at %s\n", debugstr_w(file)); + + if (ReadFile(handle, &magic, sizeof(magic), &read_bytes, NULL) && magic == IMAGE_DOS_SIGNATURE) + ret = pe_map_file(handle, fmap, DMT_PE); + else + ret = elf_map_handle(handle, fmap); + CloseHandle(handle); + + if (ret && image_find_section(fmap, ".note.gnu.build-id", &buildid_sect)) + { + const UINT32* note; + + note = (const UINT32*)image_map_section(&buildid_sect); + if (note != IMAGE_NO_MAP) + { + /* the usual ELF note structure: name-size desc-size type <name> <desc> */ + if (note[2] == NOTE_GNU_BUILD_ID) + { + if (note[1] == idlen && !memcmp(note + 3 + ((note[0] + 3) >> 2), id, idlen)) + return TRUE; + WARN("mismatch in buildid information for %s\n", wine_dbgstr_w(file)); + } + } + image_unmap_section(&buildid_sect); + image_unmap_file(fmap); + } + return FALSE; +} + /****************************************************************** * image_locate_debug_link * @@ -548,12 +589,12 @@ static BOOL image_locate_debug_link(const struct module* module, struct image_fi
/* testing execdir/filename */ MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len); - if (image_check_debug_link(p, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(p, fmap_link, crc)) goto found;
/* testing execdir/.debug/filename */ memcpy(slash, dotDebugW, sizeof(dotDebugW)); MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash + ARRAY_SIZE(dotDebugW), filename_len); - if (image_check_debug_link(p, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(p, fmap_link, crc)) goto found;
if (module->real_path) { @@ -562,7 +603,7 @@ static BOOL image_locate_debug_link(const struct module* module, struct image_fi if ((slash2 = wcsrchr(slash, '/'))) slash = slash2 + 1; if ((slash2 = wcsrchr(slash, '\'))) slash = slash2 + 1; MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len); - if (image_check_debug_link(p, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(p, fmap_link, crc)) goto found; }
/* testing globaldebugdir/execdir/filename */ @@ -570,10 +611,10 @@ static BOOL image_locate_debug_link(const struct module* module, struct image_fi memcpy(p, globalDebugDirW, globalDebugDirLen * sizeof(WCHAR)); slash += globalDebugDirLen; MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, slash, filename_len); - if (image_check_debug_link(p, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(p, fmap_link, crc)) goto found;
/* finally testing filename */ - if (image_check_debug_link(slash, fmap_link, crc)) goto found; + if (image_check_debug_link_crc(slash, fmap_link, crc)) goto found;
WARN("Couldn't locate or map %s\n", filename); @@ -632,33 +673,11 @@ static BOOL image_locate_build_id_target(struct image_file_map* fmap, const BYTE memcpy(z, dotDebug0W, sizeof(dotDebug0W)); TRACE("checking %s\n", wine_dbgstr_w(p));
- if (image_check_debug_link(p, fmap_link, 0)) + if (image_check_debug_link_gnu_id(p, fmap_link, idend - idlen, idlen)) { - struct image_section_map buildid_sect; - if (image_find_section(fmap_link, ".note.gnu.build-id", &buildid_sect)) - { - const UINT32* note; - - note = (const UINT32*)image_map_section(&buildid_sect); - if (note != IMAGE_NO_MAP) - { - /* the usual ELF note structure: name-size desc-size type <name> <desc> */ - if (note[2] == NOTE_GNU_BUILD_ID) - { - if (note[1] == idlen && - !memcmp(note + 3 + ((note[0] + 3) >> 2), idend - idlen, idlen)) - { - TRACE("Located debug information file at %s\n", debugstr_w(p)); - HeapFree(GetProcessHeap(), 0, p); - fmap->alternate = fmap_link; - return TRUE; - } - WARN("mismatch in buildid information for %s\n", wine_dbgstr_w(p)); - } - } - image_unmap_section(&buildid_sect); - } - image_unmap_file(fmap_link); + HeapFree(GetProcessHeap(), 0, p); + fmap->alternate = fmap_link; + return TRUE; }
TRACE("not found\n");
A DWZ file contains additional Dwarf debug information, and can be shared across several debug info files.
(see GNU dwz tool for more informations)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/image_private.h | 1 dlls/dbghelp/module.c | 100 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+)
diff --git a/dlls/dbghelp/image_private.h b/dlls/dbghelp/image_private.h index 83442ffb9e1..964e974e49d 100644 --- a/dlls/dbghelp/image_private.h +++ b/dlls/dbghelp/image_private.h @@ -194,6 +194,7 @@ struct macho64_nlist };
BOOL image_check_alternate(struct image_file_map* fmap, const struct module* module) DECLSPEC_HIDDEN; +struct image_file_map* image_load_debugaltlink(struct image_file_map* fmap, struct module* module) DECLSPEC_HIDDEN;
BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap) DECLSPEC_HIDDEN; BOOL pe_map_file(HANDLE file, struct image_file_map* fmap, enum module_type mt) DECLSPEC_HIDDEN; diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index c71e016b824..826306cfb38 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -629,6 +629,106 @@ found: return TRUE; }
+/****************************************************************** + * image_load_debugaltlink + * + * Handle a (potential) .gnu_debugaltlink section and the link to + * (another) alternate debug file. + * Return an heap-allocated image_file_map when the section .gnu_debugaltlink is present, + * and a matching debug file has been located. + */ +struct image_file_map* image_load_debugaltlink(struct image_file_map* fmap, struct module* module) +{ + struct image_section_map debugaltlink_sect; + const char* data; + struct image_file_map* fmap_link = NULL; + BOOL ret = FALSE; + + for (; fmap; fmap = fmap->alternate) + { + if (image_find_section(fmap, ".gnu_debugaltlink", &debugaltlink_sect)) break; + } + if (!fmap) + { + TRACE("No .gnu_debugaltlink section found for %s\n", debugstr_w(module->modulename)); + return NULL; + } + + data = image_map_section(&debugaltlink_sect); + if (data != IMAGE_NO_MAP) + { + unsigned sect_len; + const BYTE* id; + /* The content of the section is: + * + a \0 terminated string + * + followed by the build-id + * We try loading the dwz_alternate, either as absolute path, or relative to the embedded build-id + */ + sect_len = image_get_map_size(&debugaltlink_sect); + id = memchr(data, '\0', sect_len); + if (id) + { + id++; + fmap_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*fmap_link)); + if (fmap_link) + { + unsigned filename_len = MultiByteToWideChar(CP_UNIXCP, 0, data, -1, NULL, 0); + /* Trying absolute path */ + WCHAR* dst = HeapAlloc(GetProcessHeap(), 0, filename_len * sizeof(WCHAR)); + if (dst) + { + MultiByteToWideChar(CP_UNIXCP, 0, data, -1, dst, filename_len); + ret = image_check_debug_link_gnu_id(dst, fmap_link, id, data + sect_len - (const char*)id); + HeapFree(GetProcessHeap(), 0, dst); + } + /* Trying relative path to build-id directory */ + if (!ret) + { + static const WCHAR globalDebugDirW[] = + {'/','u','s','r','/','l','i','b','/','d','e','b','u','g','/','.','b','u','i','l','d','-','i','d','/'}; + dst = HeapAlloc(GetProcessHeap(), 0, sizeof(globalDebugDirW) + (3 + filename_len) * sizeof(WCHAR)); + if (dst) + { + WCHAR* p; + + /* SIGH.... + * some relative links are relative to /usr/lib/debug/.build-id, some others are from the directory + * where the alternate file is... + * so try both + */ + p = memcpy(dst, globalDebugDirW, sizeof(globalDebugDirW)); + p += ARRAY_SIZE(globalDebugDirW); + MultiByteToWideChar(CP_UNIXCP, 0, data, -1, p, filename_len); + ret = image_check_debug_link_gnu_id(dst, fmap_link, id, data + sect_len - (const char*)id); + if (!ret) + { + p = dst + ARRAY_SIZE(globalDebugDirW); + if ((const char*)id < data + sect_len) + { + *p++ = "0123456789abcdef"[*id >> 4 ]; + *p++ = "0123456789abcdef"[*id & 0x0F]; + } + *p++ = '/'; + MultiByteToWideChar(CP_UNIXCP, 0, data, -1, p, filename_len); + ret = image_check_debug_link_gnu_id(dst, fmap_link, id, data + sect_len - (const char*)id); + } + HeapFree(GetProcessHeap(), 0, dst); + } + } + if (!ret) + { + HeapFree(GetProcessHeap(), 0, fmap_link); + WARN("Couldn't find a match for .gnu_debugaltlink section %s for %s\n", data, debugstr_w(module->modulename)); + fmap_link = NULL; + } + } + } + } + image_unmap_section(&debugaltlink_sect); + if (fmap_link) TRACE("Found match .gnu_debugaltlink section for %s\n", debugstr_w(module->modulename)); + return fmap_link; +} + /****************************************************************** * image_locate_build_id_target *
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 90addb9a6b7..af0244c8311 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -182,9 +182,17 @@ typedef struct dwarf2_parse_module_context_s const struct elf_thunk_area*thunks; struct symt* symt_cache[sc_num]; /* void, unknown */ struct vector unit_contexts; + struct dwarf2_dwz_alternate_s* dwz; DWORD cu_versions; } dwarf2_parse_module_context_t;
+typedef struct dwarf2_dwz_alternate_s +{ + struct image_file_map* fmap; + dwarf2_section_t sections[section_max]; + struct image_section_map sectmap[section_max]; +} dwarf2_dwz_alternate_t; + enum unit_status { UNIT_ERROR, @@ -3663,6 +3671,49 @@ static void dwarf2_module_remove(struct process* pcs, struct module_format* modf HeapFree(GetProcessHeap(), 0, modfmt); }
+static dwarf2_dwz_alternate_t* dwarf2_load_dwz(struct image_file_map* fmap, struct module* module) +{ + struct image_file_map* fmap_dwz; + dwarf2_dwz_alternate_t* dwz; + + fmap_dwz = image_load_debugaltlink(fmap, module); + if (!fmap_dwz) return NULL; + if (!(dwz = HeapAlloc(GetProcessHeap(), 0, sizeof(*dwz)))) + { + image_unmap_file(fmap_dwz); + HeapFree(GetProcessHeap(), 0, fmap_dwz); + return NULL; + } + + dwz->fmap = fmap_dwz; + dwarf2_init_section(&dwz->sections[section_debug], fmap_dwz, ".debug_info", ".zdebug_info", &dwz->sectmap[section_debug]); + dwarf2_init_section(&dwz->sections[section_abbrev], fmap_dwz, ".debug_abbrev", ".zdebug_abbrev", &dwz->sectmap[section_abbrev]); + dwarf2_init_section(&dwz->sections[section_string], fmap_dwz, ".debug_str", ".zdebug_str", &dwz->sectmap[section_string]); + dwarf2_init_section(&dwz->sections[section_line], fmap_dwz, ".debug_line", ".zdebug_line", &dwz->sectmap[section_line]); + dwarf2_init_section(&dwz->sections[section_ranges], fmap_dwz, ".debug_ranges", ".zdebug_ranges", &dwz->sectmap[section_ranges]); + + return dwz; +} + +static void dwarf2_unload_dwz(dwarf2_dwz_alternate_t* dwz) +{ + if (!dwz) return; + dwarf2_fini_section(&dwz->sections[section_debug]); + dwarf2_fini_section(&dwz->sections[section_abbrev]); + dwarf2_fini_section(&dwz->sections[section_string]); + dwarf2_fini_section(&dwz->sections[section_line]); + dwarf2_fini_section(&dwz->sections[section_ranges]); + + image_unmap_section(&dwz->sectmap[section_debug]); + image_unmap_section(&dwz->sectmap[section_abbrev]); + image_unmap_section(&dwz->sectmap[section_string]); + image_unmap_section(&dwz->sectmap[section_line]); + image_unmap_section(&dwz->sectmap[section_ranges]); + + image_unmap_file(dwz->fmap); + HeapFree(GetProcessHeap(), 0, dwz); +} + BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, const struct elf_thunk_area* thunks, struct image_file_map* fmap) @@ -3676,6 +3727,8 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, dwarf2_parse_module_context_t module_ctx; unsigned i;
+ module_ctx.dwz = dwarf2_load_dwz(fmap, module); + if (!dwarf2_init_section(&eh_frame, fmap, ".eh_frame", NULL, &eh_frame_sect)) /* lld produces .eh_fram to avoid generating a long name */ dwarf2_init_section(&eh_frame, fmap, ".eh_fram", NULL, &eh_frame_sect); @@ -3772,6 +3825,8 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, }
leave: + dwarf2_unload_dwz(module_ctx.dwz); + dwarf2_fini_section(§ion[section_debug]); dwarf2_fini_section(§ion[section_abbrev]); dwarf2_fini_section(§ion[section_string]);
(string located in an alternate DWZ file)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index af0244c8311..e3d1e35c179 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -682,9 +682,27 @@ static BOOL dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, attr->u.uvalue = 0; return FALSE; case DW_FORM_GNU_strp_alt: - FIXME("Unhandled FORM_GNU_strp_alt\n"); - attr->u.string = NULL; - return FALSE; + if (ctx->module_ctx->dwz) + { + ULONG_PTR ofs = dwarf2_get_addr(data, ctx->head.offset_size); + if (ofs < ctx->module_ctx->dwz->sections[section_string].size) + { + attr->u.string = (const char*)ctx->module_ctx->dwz->sections[section_string].address + ofs; + TRACE("strp_alt<%s>\n", debugstr_a(attr->u.string)); + } + else + { + ERR("out of bounds strp_alt: 0x%lx 0x%x (%u)\n", ofs, ctx->module_ctx->dwz->sections[section_string].size, ctx->head.offset_size); + attr->u.string = "<<outofbounds-strpalt>>"; + } + } + else + { + ERR("No DWZ file present for GNU_strp_alt in %s\n", debugstr_w(ctx->module_ctx->module->modulename)); + attr->u.string = "<<noDWZ-strpalt>>"; + } + break; + default: FIXME("Unhandled attribute form %lx\n", abbrev_attr->form); break;
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 90 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 36 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index e3d1e35c179..34e59aa3a75 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -191,6 +191,7 @@ typedef struct dwarf2_dwz_alternate_s struct image_file_map* fmap; dwarf2_section_t sections[section_max]; struct image_section_map sectmap[section_max]; + dwarf2_parse_module_context_t module_ctx; } dwarf2_dwz_alternate_t;
enum unit_status @@ -3689,6 +3690,41 @@ static void dwarf2_module_remove(struct process* pcs, struct module_format* modf HeapFree(GetProcessHeap(), 0, modfmt); }
+static BOOL dwarf2_load_CU_module(dwarf2_parse_module_context_t* module_ctx, struct module* module, + dwarf2_section_t* sections, ULONG_PTR load_offset, + const struct elf_thunk_area* thunks) +{ + dwarf2_traverse_context_t mod_ctx; + unsigned i; + + module_ctx->sections = sections; + module_ctx->module = module; + module_ctx->thunks = thunks; + module_ctx->load_offset = load_offset; + memset(module_ctx->symt_cache, 0, sizeof(module_ctx->symt_cache)); + module_ctx->symt_cache[sc_void] = &symt_new_basic(module_ctx->module, btVoid, "void", 0)->symt; + module_ctx->symt_cache[sc_unknown] = &symt_new_basic(module_ctx->module, btNoType, "# unknown", 0)->symt; + vector_init(&module_ctx->unit_contexts, sizeof(dwarf2_parse_context_t), 16); + module_ctx->cu_versions = 0; + + /* phase I: parse all CU heads */ + mod_ctx.data = sections[section_debug].address; + mod_ctx.end_data = mod_ctx.data + sections[section_debug].size; + while (mod_ctx.data < mod_ctx.end_data) + { + dwarf2_parse_context_t* unit_ctx = vector_add(&module_ctx->unit_contexts, &module_ctx->module->pool); + + unit_ctx->module_ctx = module_ctx; + dwarf2_parse_compilation_unit_head(unit_ctx, &mod_ctx); + } + + /* phase2: load content of all CU */ + for (i = 0; i < module_ctx->unit_contexts.num_elts; ++i) + dwarf2_parse_compilation_unit((dwarf2_parse_context_t*)vector_at(&module_ctx->unit_contexts, i)); + + return TRUE; +} + static dwarf2_dwz_alternate_t* dwarf2_load_dwz(struct image_file_map* fmap, struct module* module) { struct image_file_map* fmap_dwz; @@ -3710,6 +3746,8 @@ static dwarf2_dwz_alternate_t* dwarf2_load_dwz(struct image_file_map* fmap, stru dwarf2_init_section(&dwz->sections[section_line], fmap_dwz, ".debug_line", ".zdebug_line", &dwz->sectmap[section_line]); dwarf2_init_section(&dwz->sections[section_ranges], fmap_dwz, ".debug_ranges", ".zdebug_ranges", &dwz->sectmap[section_ranges]);
+ dwz->module_ctx.dwz = NULL; + dwarf2_load_CU_module(&dwz->module_ctx, module, dwz->sections, 0/*FIXME*/, NULL); return dwz; }
@@ -3732,20 +3770,29 @@ static void dwarf2_unload_dwz(dwarf2_dwz_alternate_t* dwz) HeapFree(GetProcessHeap(), 0, dwz); }
+static BOOL dwarf2_unload_CU_module(dwarf2_parse_module_context_t* module_ctx) +{ + unsigned i; + for (i = 0; i < module_ctx->unit_contexts.num_elts; ++i) + { + dwarf2_parse_context_t* unit = vector_at(&module_ctx->unit_contexts, i); + if (unit->status != UNIT_ERROR) + pool_destroy(&unit->pool); + } + dwarf2_unload_dwz(module_ctx->dwz); + return TRUE; +} + BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, const struct elf_thunk_area* thunks, struct image_file_map* fmap) { dwarf2_section_t eh_frame, section[section_max]; - dwarf2_traverse_context_t mod_ctx; struct image_section_map debug_sect, debug_str_sect, debug_abbrev_sect, debug_line_sect, debug_ranges_sect, eh_frame_sect; BOOL ret = TRUE; struct module_format* dwarf2_modfmt; dwarf2_parse_module_context_t module_ctx; - unsigned i; - - module_ctx.dwz = dwarf2_load_dwz(fmap, module);
if (!dwarf2_init_section(&eh_frame, fmap, ".eh_frame", NULL, &eh_frame_sect)) /* lld produces .eh_fram to avoid generating a long name */ @@ -3798,30 +3845,8 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, dwarf2_modfmt->u.dwarf2_info->cuheads = NULL; dwarf2_modfmt->u.dwarf2_info->num_cuheads = 0;
- module_ctx.sections = section; - module_ctx.module = dwarf2_modfmt->module; - module_ctx.thunks = thunks; - module_ctx.load_offset = load_offset; - memset(module_ctx.symt_cache, 0, sizeof(module_ctx.symt_cache)); - module_ctx.symt_cache[sc_void] = &symt_new_basic(module_ctx.module, btVoid, "void", 0)->symt; - module_ctx.symt_cache[sc_unknown] = &symt_new_basic(module_ctx.module, btNoType, "# unknown", 0)->symt; - vector_init(&module_ctx.unit_contexts, sizeof(dwarf2_parse_context_t), 16); - module_ctx.cu_versions = 0; - - /* phase I: parse all CU heads */ - mod_ctx.data = section[section_debug].address; - mod_ctx.end_data = mod_ctx.data + section[section_debug].size; - while (mod_ctx.data < mod_ctx.end_data) - { - dwarf2_parse_context_t* unit_ctx = vector_add(&module_ctx.unit_contexts, &module_ctx.module->pool); - - unit_ctx->module_ctx = &module_ctx; - dwarf2_parse_compilation_unit_head(unit_ctx, &mod_ctx); - } - - /* phase2: load content of all CU */ - for (i = 0; i < module_ctx.unit_contexts.num_elts; ++i) - dwarf2_parse_compilation_unit((dwarf2_parse_context_t*)vector_at(&module_ctx.unit_contexts, i)); + module_ctx.dwz = dwarf2_load_dwz(fmap, module); + dwarf2_load_CU_module(&module_ctx, module, section, load_offset, thunks);
dwarf2_modfmt->module->module.SymType = SymDia; /* hide dwarf versions in CVSig @@ -3835,15 +3860,8 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, dwarf2_modfmt->module->module.SourceIndexed = TRUE; dwarf2_modfmt->module->module.Publics = TRUE;
- for (i = 0; i < module_ctx.unit_contexts.num_elts; ++i) - { - dwarf2_parse_context_t* unit = vector_at(&module_ctx.unit_contexts, i); - if (unit->status != UNIT_ERROR) - pool_destroy(&unit->pool); - } - + dwarf2_unload_CU_module(&module_ctx); leave: - dwarf2_unload_dwz(module_ctx.dwz);
dwarf2_fini_section(§ion[section_debug]); dwarf2_fini_section(§ion[section_abbrev]);
instead using debug_info's unit context instead
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 89 +++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 45 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 34e59aa3a75..0bbbe0907e2 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -711,8 +711,7 @@ static BOOL dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, return TRUE; }
-static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx, - const dwarf2_debug_info_t* di, +static BOOL dwarf2_find_attribute(const dwarf2_debug_info_t* di, unsigned at, struct attribute* attr) { unsigned i, refidx = 0; @@ -727,7 +726,7 @@ static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx, { if (abbrev_attr->attribute == at) { - return dwarf2_fill_attr(ctx, abbrev_attr, di->data[i], attr); + return dwarf2_fill_attr(di->unit_ctx, abbrev_attr, di->data[i], attr); } if ((abbrev_attr->attribute == DW_AT_abstract_origin || abbrev_attr->attribute == DW_AT_specification) && @@ -742,9 +741,9 @@ static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx, } } /* do we have either an abstract origin or a specification debug entry to look into ? */ - if (!ref_abbrev_attr || !dwarf2_fill_attr(ctx, ref_abbrev_attr, di->data[refidx], attr)) + if (!ref_abbrev_attr || !dwarf2_fill_attr(di->unit_ctx, ref_abbrev_attr, di->data[refidx], attr)) break; - if (!(di = sparse_array_find(&ctx->debug_info_table, attr->u.uvalue))) + if (!(di = sparse_array_find(&di->unit_ctx->debug_info_table, attr->u.uvalue))) FIXME("Should have found the debug info entry\n"); } return FALSE; @@ -1004,7 +1003,7 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx, { struct attribute xloc;
- if (!dwarf2_find_attribute(ctx, di, dw, &xloc)) return FALSE; + if (!dwarf2_find_attribute(di, dw, &xloc)) return FALSE;
switch (xloc.form) { @@ -1067,7 +1066,7 @@ static struct symt* dwarf2_lookup_type(const dwarf2_debug_info_t* di) struct attribute attr; dwarf2_debug_info_t* type;
- if (!dwarf2_find_attribute(di->unit_ctx, di, DW_AT_type, &attr)) + if (!dwarf2_find_attribute(di, DW_AT_type, &attr)) /* this is only valid if current language of CU is C or C++ */ return di->unit_ctx->module_ctx->symt_cache[sc_void]; if (!(type = sparse_array_find(&di->unit_ctx->debug_info_table, attr.u.uvalue))) @@ -1121,7 +1120,7 @@ static const char* dwarf2_get_cpp_name(dwarf2_parse_context_t* ctx, dwarf2_debug /* if the di is a definition, but has also a (previous) declaration, then scope must * be gotten from declaration not definition */ - if (dwarf2_find_attribute(ctx, di, DW_AT_specification, &spec) && spec.gotten_from == attr_direct) + if (dwarf2_find_attribute(di, DW_AT_specification, &spec) && spec.gotten_from == attr_direct) { di = sparse_array_find(&ctx->debug_info_table, spec.u.uvalue); if (!di) @@ -1140,7 +1139,7 @@ static const char* dwarf2_get_cpp_name(dwarf2_parse_context_t* ctx, dwarf2_debug case DW_TAG_class_type: case DW_TAG_interface_type: case DW_TAG_union_type: - if (dwarf2_find_attribute(ctx, di, DW_AT_name, &diname)) + if (dwarf2_find_attribute(di, DW_AT_name, &diname)) { size_t len = strlen(diname.u.string); last -= 2 + len; @@ -1168,7 +1167,7 @@ static BOOL dwarf2_read_range(dwarf2_parse_context_t* ctx, const dwarf2_debug_in { struct attribute range;
- if (dwarf2_find_attribute(ctx, di, DW_AT_ranges, &range)) + if (dwarf2_find_attribute(di, DW_AT_ranges, &range)) { dwarf2_traverse_context_t traverse; ULONG_PTR low, high; @@ -1198,8 +1197,8 @@ static BOOL dwarf2_read_range(dwarf2_parse_context_t* ctx, const dwarf2_debug_in struct attribute low_pc; struct attribute high_pc;
- if (!dwarf2_find_attribute(ctx, di, DW_AT_low_pc, &low_pc) || - !dwarf2_find_attribute(ctx, di, DW_AT_high_pc, &high_pc)) + if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc) || + !dwarf2_find_attribute(di, DW_AT_high_pc, &high_pc)) return FALSE; *plow = low_pc.u.uvalue; *phigh = high_pc.u.uvalue; @@ -1270,7 +1269,7 @@ static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx, *where = child; } } - if (dwarf2_find_attribute(ctx, di, DW_AT_sibling, &sibling) && + if (dwarf2_find_attribute(di, DW_AT_sibling, &sibling) && traverse->data != ctx->module_ctx->sections[ctx->section].address + sibling.u.uvalue) { if (sibling.u.uvalue >= ctx->module_ctx->sections[ctx->section].size) @@ -1295,7 +1294,7 @@ static struct vector* dwarf2_get_di_children(dwarf2_debug_info_t* di) { if (di->abbrev->have_child) return &di->children; - if (!dwarf2_find_attribute(di->unit_ctx, di, DW_AT_specification, &spec)) break; + if (!dwarf2_find_attribute(di, DW_AT_specification, &spec)) break; if (!(di = sparse_array_find(&di->unit_ctx->debug_info_table, spec.u.uvalue))) FIXME("Should have found the debug info entry\n"); } @@ -1313,10 +1312,10 @@ static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL; - if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = 0; - if (!dwarf2_find_attribute(ctx, di, DW_AT_encoding, &encoding)) encoding.u.uvalue = DW_ATE_void; + if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = 0; + if (!dwarf2_find_attribute(di, DW_AT_encoding, &encoding)) encoding.u.uvalue = DW_ATE_void;
switch (encoding.u.uvalue) { @@ -1347,7 +1346,7 @@ static struct symt* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx,
TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), di->abbrev->entry_code);
- if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) name.u.string = NULL; + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL; ref_type = dwarf2_lookup_type(di);
if (name.u.string) @@ -1366,7 +1365,7 @@ static struct symt* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = sizeof(void *); + if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = sizeof(void *); ref_type = dwarf2_lookup_type(di); di->symt = &symt_new_pointer(ctx->module_ctx->module, ref_type, size.u.uvalue)->symt; if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); @@ -1405,11 +1404,11 @@ static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, { case DW_TAG_subrange_type: idx_type = dwarf2_lookup_type(child); - if (!dwarf2_find_attribute(ctx, child, DW_AT_lower_bound, &min)) + if (!dwarf2_find_attribute(child, DW_AT_lower_bound, &min)) min.u.uvalue = 0; - if (dwarf2_find_attribute(ctx, child, DW_AT_upper_bound, &max)) + if (dwarf2_find_attribute(child, DW_AT_upper_bound, &max)) cnt.u.uvalue = max.u.uvalue + 1 - min.u.uvalue; - else if (!dwarf2_find_attribute(ctx, child, DW_AT_count, &cnt)) + else if (!dwarf2_find_attribute(child, DW_AT_count, &cnt)) cnt.u.uvalue = 0; break; default: @@ -1465,7 +1464,7 @@ static struct symt* dwarf2_parse_unspecified_type(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = "void"; size.u.uvalue = sizeof(void *);
@@ -1508,7 +1507,7 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) name.u.string = NULL; + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL; elt_type = dwarf2_lookup_type(di); if (dwarf2_compute_location_attr(ctx, di, DW_AT_data_member_location, &loc, NULL)) { @@ -1523,15 +1522,15 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx, } else loc.offset = 0; - if (!dwarf2_find_attribute(ctx, di, DW_AT_bit_size, &bit_size)) + if (!dwarf2_find_attribute(di, DW_AT_bit_size, &bit_size)) bit_size.u.uvalue = 0; - if (dwarf2_find_attribute(ctx, di, DW_AT_bit_offset, &bit_offset)) + if (dwarf2_find_attribute(di, DW_AT_bit_offset, &bit_offset)) { /* FIXME: we should only do this when implementation is LSB (which is * the case on i386 processors) */ struct attribute nbytes; - if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &nbytes)) + if (!dwarf2_find_attribute(di, DW_AT_byte_size, &nbytes)) { DWORD64 size; nbytes.u.uvalue = symt_get_info(ctx->module_ctx->module, elt_type, TI_GET_LENGTH, &size) ? @@ -1565,9 +1564,9 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
/* quirk... FIXME provide real support for anonymous UDTs */ - if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = "zz_anon_zz"; - if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = 0; + if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = 0;
di->symt = &symt_new_udt(ctx->module_ctx->module, dwarf2_get_cpp_name(ctx, di, name.u.string), size.u.uvalue, udt)->symt; @@ -1630,8 +1629,8 @@ static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) return; - if (!dwarf2_find_attribute(ctx, di, DW_AT_const_value, &value)) value.u.svalue = 0; + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) return; + if (!dwarf2_find_attribute(di, DW_AT_const_value, &value)) value.u.svalue = 0; symt_add_enum_element(ctx->module_ctx->module, parent, name.u.string, value.u.svalue);
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); @@ -1651,8 +1650,8 @@ static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) name.u.string = NULL; - if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = 4; + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL; + if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = 4;
switch (size.u.uvalue) /* FIXME: that's wrong */ { @@ -1712,7 +1711,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, is_pmt = !block && di->abbrev->tag == DW_TAG_formal_parameter; param_type = dwarf2_lookup_type(di);
- if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_name, &name)) { + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) { /* cannot do much without the name, the functions below won't like it. */ return; } @@ -1732,7 +1731,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, case loc_absolute: /* it's a global variable */ /* FIXME: we don't handle its scope yet */ - if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_external, &ext)) + if (!dwarf2_find_attribute(di, DW_AT_external, &ext)) ext.u.uvalue = 0; loc.offset += subpgm->ctx->module_ctx->load_offset; symt_new_global_variable(subpgm->ctx->module_ctx->module, subpgm->ctx->compiland, @@ -1754,7 +1753,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, break; } } - else if (dwarf2_find_attribute(subpgm->ctx, di, DW_AT_const_value, &value)) + else if (dwarf2_find_attribute(di, DW_AT_const_value, &value)) { VARIANT v; if (subpgm->func) WARN("Unsupported constant %s in function\n", debugstr_a(name.u.string)); @@ -1849,8 +1848,8 @@ static void dwarf2_parse_subprogram_label(dwarf2_subprogram_t* subpgm,
TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
- if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0; - if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_name, &name)) + if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0; + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL;
loc.kind = loc_absolute; @@ -2020,7 +2019,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) { WARN("No name for function... dropping function\n"); return NULL; @@ -2028,7 +2027,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, /* if it's an abstract representation of an inline function, there should be * a concrete object that we'll handle */ - if (dwarf2_find_attribute(ctx, di, DW_AT_inline, &inline_flags) && + if (dwarf2_find_attribute(di, DW_AT_inline, &inline_flags) && inline_flags.u.uvalue != DW_INL_not_inlined) { TRACE("Function %s declared as inlined (%ld)... skipping\n", @@ -2036,7 +2035,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, return NULL; }
- if (dwarf2_find_attribute(ctx, di, DW_AT_declaration, &is_decl) && + if (dwarf2_find_attribute(di, DW_AT_declaration, &is_decl) && is_decl.u.uvalue && is_decl.gotten_from == attr_direct) { /* it's a real declaration, skip it */ @@ -2609,14 +2608,14 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx) struct attribute stmt_list, low_pc; struct attribute comp_dir;
- if (!dwarf2_find_attribute(ctx, di, DW_AT_name, &name)) + if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL;
/* get working directory of current compilation unit */ - if (!dwarf2_find_attribute(ctx, di, DW_AT_comp_dir, &comp_dir)) + if (!dwarf2_find_attribute(di, DW_AT_comp_dir, &comp_dir)) comp_dir.u.string = NULL;
- if (!dwarf2_find_attribute(ctx, di, DW_AT_low_pc, &low_pc)) + if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0; ctx->compiland = symt_new_compiland(ctx->module_ctx->module, ctx->module_ctx->load_offset + low_pc.u.uvalue, source_new(ctx->module_ctx->module, comp_dir.u.string, name.u.string)); @@ -2628,7 +2627,7 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx) child = *(dwarf2_debug_info_t**)vector_at(children, i); dwarf2_load_one_entry(ctx, child); } - if (dwarf2_find_attribute(ctx, di, DW_AT_stmt_list, &stmt_list)) + if (dwarf2_find_attribute(di, DW_AT_stmt_list, &stmt_list)) { if (dwarf2_parse_line_numbers(ctx, comp_dir.u.string, stmt_list.u.uvalue)) ctx->module_ctx->module->module.LineNumbers = TRUE;
using debug_info's unit context instead
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 0bbbe0907e2..122e9b71d7e 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1105,16 +1105,16 @@ static struct symt* dwarf2_lookup_type(const dwarf2_debug_info_t* di) return type->symt; }
-static const char* dwarf2_get_cpp_name(dwarf2_parse_context_t* ctx, dwarf2_debug_info_t* di, const char* name) +static const char* dwarf2_get_cpp_name(dwarf2_debug_info_t* di, const char* name) { char* last; struct attribute diname; struct attribute spec;
if (di->abbrev->tag == DW_TAG_compile_unit) return name; - if (!ctx->cpp_name) - ctx->cpp_name = pool_alloc(&ctx->pool, MAX_SYM_NAME); - last = ctx->cpp_name + MAX_SYM_NAME - strlen(name) - 1; + if (!di->unit_ctx->cpp_name) + di->unit_ctx->cpp_name = pool_alloc(&di->unit_ctx->pool, MAX_SYM_NAME); + last = di->unit_ctx->cpp_name + MAX_SYM_NAME - strlen(name) - 1; strcpy(last, name);
/* if the di is a definition, but has also a (previous) declaration, then scope must @@ -1122,7 +1122,7 @@ static const char* dwarf2_get_cpp_name(dwarf2_parse_context_t* ctx, dwarf2_debug */ if (dwarf2_find_attribute(di, DW_AT_specification, &spec) && spec.gotten_from == attr_direct) { - di = sparse_array_find(&ctx->debug_info_table, spec.u.uvalue); + di = sparse_array_find(&di->unit_ctx->debug_info_table, spec.u.uvalue); if (!di) { FIXME("Should have found the debug info entry\n"); @@ -1143,7 +1143,7 @@ static const char* dwarf2_get_cpp_name(dwarf2_parse_context_t* ctx, dwarf2_debug { size_t len = strlen(diname.u.string); last -= 2 + len; - if (last < ctx->cpp_name) return NULL; + if (last < di->unit_ctx->cpp_name) return NULL; memcpy(last, diname.u.string, len); last[len] = last[len + 1] = ':'; } @@ -1568,7 +1568,7 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, name.u.string = "zz_anon_zz"; if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = 0;
- di->symt = &symt_new_udt(ctx->module_ctx->module, dwarf2_get_cpp_name(ctx, di, name.u.string), + di->symt = &symt_new_udt(ctx->module_ctx->module, dwarf2_get_cpp_name(di, name.u.string), size.u.uvalue, udt)->symt;
children = dwarf2_get_di_children(di); @@ -1735,7 +1735,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, ext.u.uvalue = 0; loc.offset += subpgm->ctx->module_ctx->load_offset; symt_new_global_variable(subpgm->ctx->module_ctx->module, subpgm->ctx->compiland, - dwarf2_get_cpp_name(subpgm->ctx, di, name.u.string), !ext.u.uvalue, + dwarf2_get_cpp_name(di, name.u.string), !ext.u.uvalue, loc, 0, param_type); break; default: @@ -2057,7 +2057,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, /* FIXME: assuming C source code */ sig_type = symt_new_function_signature(ctx->module_ctx->module, ret_type, CV_CALL_FAR_C); subpgm.func = symt_new_function(ctx->module_ctx->module, ctx->compiland, - dwarf2_get_cpp_name(ctx, di, name.u.string), + dwarf2_get_cpp_name(di, name.u.string), ctx->module_ctx->load_offset + low_pc, high_pc - low_pc, &sig_type->symt); di->symt = &subpgm.func->symt;
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 81 +++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 41 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 122e9b71d7e..f0fa522c1c9 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -420,7 +420,7 @@ static const char* dwarf2_debug_traverse_ctx(const dwarf2_traverse_context_t* ct return wine_dbg_sprintf("ctx(%p)", ctx->data); }
-static const char* dwarf2_debug_ctx(const dwarf2_parse_context_t* ctx) +static const char* dwarf2_debug_unit_ctx(const dwarf2_parse_context_t* ctx) { return wine_dbg_sprintf("ctx(%p,%s)", ctx, debugstr_w(ctx->module_ctx->module->modulename)); @@ -428,8 +428,8 @@ static const char* dwarf2_debug_ctx(const dwarf2_parse_context_t* ctx)
static const char* dwarf2_debug_di(const dwarf2_debug_info_t* di) { - return wine_dbg_sprintf("debug_info(abbrev:%p,symt:%p)", - di->abbrev, di->symt); + return wine_dbg_sprintf("debug_info(abbrev:%p,symt:%p) in %s", + di->abbrev, di->symt, dwarf2_debug_unit_ctx(di->unit_ctx)); }
static dwarf2_abbrev_entry_t* @@ -1078,7 +1078,7 @@ static struct symt* dwarf2_lookup_type(const dwarf2_debug_info_t* di) if (ref_ctx && dwarf2_parse_compilation_unit(ref_ctx)) { type = sparse_array_find(&ref_ctx->debug_info_table, attr.u.uvalue); - if (type) TRACE("Found type ref %lx in another CU %s\n", attr.u.uvalue, dwarf2_debug_ctx(ref_ctx)); + if (type) TRACE("Found type ref %lx in another CU %s\n", attr.u.uvalue, dwarf2_debug_unit_ctx(ref_ctx)); } } if (!type) @@ -1275,7 +1275,7 @@ static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx, if (sibling.u.uvalue >= ctx->module_ctx->sections[ctx->section].size) { FIXME("cursor sibling after section end %s: 0x%lx 0x%x\n", - dwarf2_debug_ctx(ctx), sibling.u.uvalue, ctx->module_ctx->sections[ctx->section].size); + dwarf2_debug_unit_ctx(ctx), sibling.u.uvalue, ctx->module_ctx->sections[ctx->section].size); return FALSE; } WARN("setting cursor for %s to next sibling <0x%lx>\n", @@ -1310,7 +1310,7 @@ static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx, enum BasicType bt; if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL; @@ -1344,7 +1344,7 @@ static struct symt* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %lu\n", dwarf2_debug_ctx(ctx), di->abbrev->entry_code); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL; ref_type = dwarf2_lookup_type(di); @@ -1363,7 +1363,7 @@ static struct symt* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = sizeof(void *); ref_type = dwarf2_lookup_type(di); @@ -1384,7 +1384,7 @@ static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
ref_type = dwarf2_lookup_type(di);
@@ -1412,8 +1412,8 @@ static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, cnt.u.uvalue = 0; break; default: - FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", - child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + FIXME("Unhandled Tag type 0x%lx at %s\n", + child->abbrev->tag, dwarf2_debug_di(di)); break; } } @@ -1428,7 +1428,7 @@ static struct symt* dwarf2_parse_const_type(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
ref_type = dwarf2_lookup_type(di); if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); @@ -1444,7 +1444,7 @@ static struct symt* dwarf2_parse_volatile_type(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
ref_type = dwarf2_lookup_type(di); if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); @@ -1460,7 +1460,7 @@ static struct symt* dwarf2_parse_unspecified_type(dwarf2_parse_context_t* ctx, struct attribute size; struct symt_basic *basic;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (di->symt) return di->symt;
@@ -1482,7 +1482,7 @@ static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
ref_type = dwarf2_lookup_type(di); /* FIXME: for now, we hard-wire C++ references to pointers */ @@ -1505,7 +1505,7 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx,
assert(parent);
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL; elt_type = dwarf2_lookup_type(di); @@ -1518,7 +1518,7 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx, } else TRACE("found member_location at %s -> %lu\n", - dwarf2_debug_ctx(ctx), loc.offset); + dwarf2_debug_di(di), loc.offset); } else loc.offset = 0; @@ -1561,7 +1561,7 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
/* quirk... FIXME provide real support for anonymous UDTs */ if (!dwarf2_find_attribute(di, DW_AT_name, &name)) @@ -1611,8 +1611,8 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, /* FIXME: some C++ related stuff */ break; default: - FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", - child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + FIXME("Unhandled Tag type 0x%lx at %s\n", + child->abbrev->tag, dwarf2_debug_di(di)); break; } } @@ -1627,7 +1627,7 @@ static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx, struct attribute name; struct attribute value;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_find_attribute(di, DW_AT_name, &name)) return; if (!dwarf2_find_attribute(di, DW_AT_const_value, &value)) value.u.svalue = 0; @@ -1648,7 +1648,7 @@ static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL; if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = 4; @@ -1676,8 +1676,8 @@ static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_parse_enumerator(ctx, child, (struct symt_enum*)di->symt); break; default: - FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", - di->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + FIXME("Unhandled Tag type 0x%lx at %s\n", + di->abbrev->tag, dwarf2_debug_di(di)); } } return di->symt; @@ -1706,7 +1706,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, struct location loc; BOOL is_pmt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
is_pmt = !block && di->abbrev->tag == DW_TAG_formal_parameter; param_type = dwarf2_lookup_type(di); @@ -1722,7 +1722,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
TRACE("found parameter %s (kind=%d, offset=%ld, reg=%d) at %s\n", debugstr_a(name.u.string), loc.kind, loc.offset, loc.reg, - dwarf2_debug_ctx(subpgm->ctx)); + dwarf2_debug_unit_ctx(subpgm->ctx));
switch (loc.kind) { @@ -1846,7 +1846,7 @@ static void dwarf2_parse_subprogram_label(dwarf2_subprogram_t* subpgm, struct attribute low_pc; struct location loc;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0; if (!dwarf2_find_attribute(di, DW_AT_name, &name)) @@ -1875,7 +1875,7 @@ static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm, dwarf2_debug_info_t*child; unsigned int i;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_read_range(subpgm->ctx, di, &low_pc, &high_pc)) { @@ -1911,9 +1911,8 @@ static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm, /* this isn't properly supported by dbghelp interface. skip it for now */ break; default: - FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", - child->abbrev->tag, dwarf2_debug_ctx(subpgm->ctx), - dwarf2_debug_di(di)); + FIXME("Unhandled Tag type 0x%lx at %s\n", + child->abbrev->tag, dwarf2_debug_di(di)); } } symt_close_func_block(subpgm->ctx->module_ctx->module, subpgm->func, block, 0); @@ -1929,7 +1928,7 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, dwarf2_debug_info_t*child; unsigned int i;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_read_range(subpgm->ctx, di, &low_pc, &high_pc)) { @@ -1993,8 +1992,8 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, /* the type referred to will be loaded when we need it, so skip it */ break; default: - FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", - child->abbrev->tag, dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di)); + FIXME("Unhandled Tag type 0x%lx at %s\n", + child->abbrev->tag, dwarf2_debug_di(di)); } }
@@ -2017,7 +2016,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
if (!dwarf2_find_attribute(di, DW_AT_name, &name)) { @@ -2119,8 +2118,8 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, /* FIXME: no support in dbghelp's internals so far */ break; default: - FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", - child->abbrev->tag, dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + FIXME("Unhandled Tag type 0x%lx at %s\n", + child->abbrev->tag, dwarf2_debug_di(di)); } }
@@ -2144,7 +2143,7 @@ static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx,
if (di->symt) return di->symt;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
ret_type = dwarf2_lookup_type(di);
@@ -2180,7 +2179,7 @@ static void dwarf2_parse_namespace(dwarf2_parse_context_t* ctx,
if (di->symt) return;
- TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); + TRACE("%s\n", dwarf2_debug_di(di));
di->symt = ctx->module_ctx->symt_cache[sc_void];
@@ -2260,8 +2259,8 @@ static void dwarf2_load_one_entry(dwarf2_parse_context_t* ctx, case DW_TAG_ptr_to_member_type: break; default: - FIXME("Unhandled Tag type 0x%lx at %s, for %lu\n", - di->abbrev->tag, dwarf2_debug_ctx(ctx), di->abbrev->entry_code); + FIXME("Unhandled Tag type 0x%lx at %s\n", + di->abbrev->tag, dwarf2_debug_di(di)); } }
(but using debug_info's unit_context instead)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 174 ++++++++++++++++++++++---------------------------- 1 file changed, 78 insertions(+), 96 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index f0fa522c1c9..bf4999ab0bb 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -236,7 +236,7 @@ struct dwarf2_module_info_s #define loc_dwarf2_block (loc_user + 1)
/* forward declarations */ -static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, dwarf2_debug_info_t* entry); +static struct symt* dwarf2_parse_enumeration_type(dwarf2_debug_info_t* entry); static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx); static dwarf2_parse_context_t* dwarf2_locate_cu(dwarf2_parse_module_context_t* module_ctx, ULONG_PTR ref);
@@ -749,7 +749,7 @@ static BOOL dwarf2_find_attribute(const dwarf2_debug_info_t* di, return FALSE; }
-static void dwarf2_load_one_entry(dwarf2_parse_context_t*, dwarf2_debug_info_t*); +static void dwarf2_load_one_entry(dwarf2_debug_info_t*);
#define Wine_DW_no_register 0x7FFFFFFF
@@ -1095,7 +1095,7 @@ static struct symt* dwarf2_lookup_type(const dwarf2_debug_info_t* di) if (!type->symt) { /* load the debug info entity */ - dwarf2_load_one_entry(di->unit_ctx, type); + dwarf2_load_one_entry(type); if (!type->symt) { FIXME("Unable to load forward reference for tag %lx\n", type->abbrev->tag); @@ -1301,8 +1301,7 @@ static struct vector* dwarf2_get_di_children(dwarf2_debug_info_t* di) return NULL; }
-static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_base_type(dwarf2_debug_info_t* di) { struct attribute name; struct attribute size; @@ -1330,14 +1329,13 @@ static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx, case DW_ATE_unsigned_char: bt = btChar; break; default: bt = btNoType; break; } - di->symt = &symt_new_basic(ctx->module_ctx->module, bt, name.u.string, size.u.uvalue)->symt; + di->symt = &symt_new_basic(di->unit_ctx->module_ctx->module, bt, name.u.string, size.u.uvalue)->symt;
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); return di->symt; }
-static struct symt* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_typedef(dwarf2_debug_info_t* di) { struct symt* ref_type; struct attribute name; @@ -1350,13 +1348,12 @@ static struct symt* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx, ref_type = dwarf2_lookup_type(di);
if (name.u.string) - di->symt = &symt_new_typedef(ctx->module_ctx->module, ref_type, name.u.string)->symt; + di->symt = &symt_new_typedef(di->unit_ctx->module_ctx->module, ref_type, name.u.string)->symt; if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); return di->symt; }
-static struct symt* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_pointer_type(dwarf2_debug_info_t* di) { struct symt* ref_type; struct attribute size; @@ -1367,13 +1364,12 @@ static struct symt* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx,
if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = sizeof(void *); ref_type = dwarf2_lookup_type(di); - di->symt = &symt_new_pointer(ctx->module_ctx->module, ref_type, size.u.uvalue)->symt; + di->symt = &symt_new_pointer(di->unit_ctx->module_ctx->module, ref_type, size.u.uvalue)->symt; if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); return di->symt; }
-static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_array_type(dwarf2_debug_info_t* di) { struct symt* ref_type; struct symt* idx_type = NULL; @@ -1392,14 +1388,14 @@ static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, { /* fake an array with unknown size */ /* FIXME: int4 even on 64bit machines??? */ - idx_type = &symt_new_basic(ctx->module_ctx->module, btInt, "int", 4)->symt; + idx_type = &symt_new_basic(di->unit_ctx->module_ctx->module, btInt, "int", 4)->symt; min.u.uvalue = 0; cnt.u.uvalue = 0; } else for (i = 0; i < vector_length(children); i++) { child = *(dwarf2_debug_info_t**)vector_at(children, i); - if (child->symt == ctx->module_ctx->symt_cache[sc_unknown]) continue; + if (child->symt == di->unit_ctx->module_ctx->symt_cache[sc_unknown]) continue; switch (child->abbrev->tag) { case DW_TAG_subrange_type: @@ -1417,12 +1413,11 @@ static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, break; } } - di->symt = &symt_new_array(ctx->module_ctx->module, min.u.uvalue, cnt.u.uvalue, ref_type, idx_type)->symt; + di->symt = &symt_new_array(di->unit_ctx->module_ctx->module, min.u.uvalue, cnt.u.uvalue, ref_type, idx_type)->symt; return di->symt; }
-static struct symt* dwarf2_parse_const_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_const_type(dwarf2_debug_info_t* di) { struct symt* ref_type;
@@ -1437,8 +1432,7 @@ static struct symt* dwarf2_parse_const_type(dwarf2_parse_context_t* ctx, return ref_type; }
-static struct symt* dwarf2_parse_volatile_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_volatile_type(dwarf2_debug_info_t* di) { struct symt* ref_type;
@@ -1453,8 +1447,7 @@ static struct symt* dwarf2_parse_volatile_type(dwarf2_parse_context_t* ctx, return ref_type; }
-static struct symt* dwarf2_parse_unspecified_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_unspecified_type(dwarf2_debug_info_t* di) { struct attribute name; struct attribute size; @@ -1468,15 +1461,14 @@ static struct symt* dwarf2_parse_unspecified_type(dwarf2_parse_context_t* ctx, name.u.string = "void"; size.u.uvalue = sizeof(void *);
- basic = symt_new_basic(ctx->module_ctx->module, btVoid, name.u.string, size.u.uvalue); + basic = symt_new_basic(di->unit_ctx->module_ctx->module, btVoid, name.u.string, size.u.uvalue); di->symt = &basic->symt;
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); return di->symt; }
-static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_reference_type(dwarf2_debug_info_t* di) { struct symt* ref_type = NULL;
@@ -1486,15 +1478,14 @@ static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx,
ref_type = dwarf2_lookup_type(di); /* FIXME: for now, we hard-wire C++ references to pointers */ - di->symt = &symt_new_pointer(ctx->module_ctx->module, ref_type, sizeof(void *))->symt; + di->symt = &symt_new_pointer(di->unit_ctx->module_ctx->module, ref_type, sizeof(void *))->symt;
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n");
return di->symt; }
-static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di, +static void dwarf2_parse_udt_member(dwarf2_debug_info_t* di, struct symt_udt* parent) { struct symt* elt_type; @@ -1509,7 +1500,7 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx,
if (!dwarf2_find_attribute(di, DW_AT_name, &name)) name.u.string = NULL; elt_type = dwarf2_lookup_type(di); - if (dwarf2_compute_location_attr(ctx, di, DW_AT_data_member_location, &loc, NULL)) + if (dwarf2_compute_location_attr(di->unit_ctx, di, DW_AT_data_member_location, &loc, NULL)) { if (loc.kind != loc_absolute) { @@ -1533,24 +1524,22 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx, if (!dwarf2_find_attribute(di, DW_AT_byte_size, &nbytes)) { DWORD64 size; - nbytes.u.uvalue = symt_get_info(ctx->module_ctx->module, elt_type, TI_GET_LENGTH, &size) ? + nbytes.u.uvalue = symt_get_info(di->unit_ctx->module_ctx->module, elt_type, TI_GET_LENGTH, &size) ? (ULONG_PTR)size : 0; } bit_offset.u.uvalue = nbytes.u.uvalue * 8 - bit_offset.u.uvalue - bit_size.u.uvalue; } else bit_offset.u.uvalue = 0; - symt_add_udt_element(ctx->module_ctx->module, parent, name.u.string, elt_type, + symt_add_udt_element(di->unit_ctx->module_ctx->module, parent, name.u.string, elt_type, loc.offset, bit_offset.u.uvalue, bit_size.u.uvalue);
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); }
-static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di); +static struct symt* dwarf2_parse_subprogram(dwarf2_debug_info_t* di);
-static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di, +static struct symt* dwarf2_parse_udt_type(dwarf2_debug_info_t* di, enum UdtKind udt) { struct attribute name; @@ -1568,7 +1557,7 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, name.u.string = "zz_anon_zz"; if (!dwarf2_find_attribute(di, DW_AT_byte_size, &size)) size.u.uvalue = 0;
- di->symt = &symt_new_udt(ctx->module_ctx->module, dwarf2_get_cpp_name(di, name.u.string), + di->symt = &symt_new_udt(di->unit_ctx->module_ctx->module, dwarf2_get_cpp_name(di, name.u.string), size.u.uvalue, udt)->symt;
children = dwarf2_get_di_children(di); @@ -1579,21 +1568,21 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, switch (child->abbrev->tag) { case DW_TAG_array_type: - dwarf2_parse_array_type(ctx, di); + dwarf2_parse_array_type(di); break; case DW_TAG_member: /* FIXME: should I follow the sibling stuff ?? */ if (symt_check_tag(di->symt, SymTagUDT)) - dwarf2_parse_udt_member(ctx, child, (struct symt_udt*)di->symt); + dwarf2_parse_udt_member(child, (struct symt_udt*)di->symt); break; case DW_TAG_enumeration_type: - dwarf2_parse_enumeration_type(ctx, child); + dwarf2_parse_enumeration_type(child); break; case DW_TAG_subprogram: - dwarf2_parse_subprogram(ctx, child); + dwarf2_parse_subprogram(child); break; case DW_TAG_const_type: - dwarf2_parse_const_type(ctx, child); + dwarf2_parse_const_type(child); break; case DW_TAG_structure_type: case DW_TAG_class_type: @@ -1620,8 +1609,7 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, return di->symt; }
-static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di, +static void dwarf2_parse_enumerator(dwarf2_debug_info_t* di, struct symt_enum* parent) { struct attribute name; @@ -1631,13 +1619,12 @@ static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx,
if (!dwarf2_find_attribute(di, DW_AT_name, &name)) return; if (!dwarf2_find_attribute(di, DW_AT_const_value, &value)) value.u.svalue = 0; - symt_add_enum_element(ctx->module_ctx->module, parent, name.u.string, value.u.svalue); + symt_add_enum_element(di->unit_ctx->module_ctx->module, parent, name.u.string, value.u.svalue);
if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); }
-static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_enumeration_type(dwarf2_debug_info_t* di) { struct attribute name; struct attribute size; @@ -1655,13 +1642,13 @@ static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx,
switch (size.u.uvalue) /* FIXME: that's wrong */ { - case 1: basetype = symt_new_basic(ctx->module_ctx->module, btInt, "char", 1); break; - case 2: basetype = symt_new_basic(ctx->module_ctx->module, btInt, "short", 2); break; + case 1: basetype = symt_new_basic(di->unit_ctx->module_ctx->module, btInt, "char", 1); break; + case 2: basetype = symt_new_basic(di->unit_ctx->module_ctx->module, btInt, "short", 2); break; default: - case 4: basetype = symt_new_basic(ctx->module_ctx->module, btInt, "int", 4); break; + case 4: basetype = symt_new_basic(di->unit_ctx->module_ctx->module, btInt, "int", 4); break; }
- di->symt = &symt_new_enum(ctx->module_ctx->module, name.u.string, &basetype->symt)->symt; + di->symt = &symt_new_enum(di->unit_ctx->module_ctx->module, name.u.string, &basetype->symt)->symt;
children = dwarf2_get_di_children(di); /* FIXME: should we use the sibling stuff ?? */ @@ -1673,7 +1660,7 @@ static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, { case DW_TAG_enumerator: if (symt_check_tag(di->symt, SymTagEnum)) - dwarf2_parse_enumerator(ctx, child, (struct symt_enum*)di->symt); + dwarf2_parse_enumerator(child, (struct symt_enum*)di->symt); break; default: FIXME("Unhandled Tag type 0x%lx at %s\n", @@ -1862,8 +1849,7 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, struct symt_block* parent_block, dwarf2_debug_info_t* di);
-static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di); +static struct symt* dwarf2_parse_subroutine_type(dwarf2_debug_info_t* di);
static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm, struct symt_block* parent_block, @@ -1954,13 +1940,13 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, dwarf2_parse_variable(subpgm, block, child); break; case DW_TAG_pointer_type: - dwarf2_parse_pointer_type(subpgm->ctx, child); + dwarf2_parse_pointer_type(child); break; case DW_TAG_subroutine_type: - dwarf2_parse_subroutine_type(subpgm->ctx, child); + dwarf2_parse_subroutine_type(child); break; case DW_TAG_const_type: - dwarf2_parse_const_type(subpgm->ctx, child); + dwarf2_parse_const_type(child); break; case DW_TAG_lexical_block: dwarf2_parse_subprogram_block(subpgm, block, child); @@ -2000,8 +1986,7 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, symt_close_func_block(subpgm->ctx->module_ctx->module, subpgm->func, block, 0); }
-static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_subprogram(dwarf2_debug_info_t* di) { struct attribute name; ULONG_PTR low_pc, high_pc; @@ -2040,7 +2025,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, /* it's a real declaration, skip it */ return NULL; } - if (!dwarf2_read_range(ctx, di, &low_pc, &high_pc)) + if (!dwarf2_read_range(di->unit_ctx, di, &low_pc, &high_pc)) { WARN("cannot get range for %s\n", debugstr_a(name.u.string)); return NULL; @@ -2049,19 +2034,19 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, * (not the case for stabs), we just drop Wine's thunks here... * Actual thunks will be created in elf_module from the symbol table */ - if (elf_is_in_thunk_area(ctx->module_ctx->load_offset + low_pc, ctx->module_ctx->thunks) >= 0) + if (elf_is_in_thunk_area(di->unit_ctx->module_ctx->load_offset + low_pc, di->unit_ctx->module_ctx->thunks) >= 0) return NULL; ret_type = dwarf2_lookup_type(di);
/* FIXME: assuming C source code */ - sig_type = symt_new_function_signature(ctx->module_ctx->module, ret_type, CV_CALL_FAR_C); - subpgm.func = symt_new_function(ctx->module_ctx->module, ctx->compiland, + sig_type = symt_new_function_signature(di->unit_ctx->module_ctx->module, ret_type, CV_CALL_FAR_C); + subpgm.func = symt_new_function(di->unit_ctx->module_ctx->module, di->unit_ctx->compiland, dwarf2_get_cpp_name(di, name.u.string), - ctx->module_ctx->load_offset + low_pc, high_pc - low_pc, + di->unit_ctx->module_ctx->load_offset + low_pc, high_pc - low_pc, &sig_type->symt); di->symt = &subpgm.func->symt; - subpgm.ctx = ctx; - if (!dwarf2_compute_location_attr(ctx, di, DW_AT_frame_base, + subpgm.ctx = di->unit_ctx; + if (!dwarf2_compute_location_attr(di->unit_ctx, di, DW_AT_frame_base, &subpgm.frame, NULL)) { /* on stack !! */ @@ -2089,10 +2074,10 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, dwarf2_parse_inlined_subroutine(&subpgm, NULL, child); break; case DW_TAG_pointer_type: - dwarf2_parse_pointer_type(subpgm.ctx, di); + dwarf2_parse_pointer_type(di); break; case DW_TAG_const_type: - dwarf2_parse_const_type(subpgm.ctx, di); + dwarf2_parse_const_type(di); break; case DW_TAG_subprogram: /* FIXME: likely a declaration (to be checked) @@ -2125,15 +2110,14 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx,
if (subpgm.non_computed_variable || subpgm.frame.kind >= loc_user) { - symt_add_function_point(ctx->module_ctx->module, subpgm.func, SymTagCustom, + symt_add_function_point(di->unit_ctx->module_ctx->module, subpgm.func, SymTagCustom, &subpgm.frame, NULL); }
return di->symt; }
-static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct symt* dwarf2_parse_subroutine_type(dwarf2_debug_info_t* di) { struct symt* ret_type; struct symt_function_signature* sig_type; @@ -2148,7 +2132,7 @@ static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx, ret_type = dwarf2_lookup_type(di);
/* FIXME: assuming C source code */ - sig_type = symt_new_function_signature(ctx->module_ctx->module, ret_type, CV_CALL_FAR_C); + sig_type = symt_new_function_signature(di->unit_ctx->module_ctx->module, ret_type, CV_CALL_FAR_C);
children = dwarf2_get_di_children(di); if (children) for (i = 0; i < vector_length(children); i++) @@ -2158,7 +2142,7 @@ static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx, switch (child->abbrev->tag) { case DW_TAG_formal_parameter: - symt_add_function_signature_parameter(ctx->module_ctx->module, sig_type, + symt_add_function_signature_parameter(di->unit_ctx->module_ctx->module, sig_type, dwarf2_lookup_type(child)); break; case DW_TAG_unspecified_parameters: @@ -2170,8 +2154,7 @@ static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx, return di->symt = &sig_type->symt; }
-static void dwarf2_parse_namespace(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static void dwarf2_parse_namespace(dwarf2_debug_info_t* di) { struct vector* children; dwarf2_debug_info_t* child; @@ -2181,68 +2164,67 @@ static void dwarf2_parse_namespace(dwarf2_parse_context_t* ctx,
TRACE("%s\n", dwarf2_debug_di(di));
- di->symt = ctx->module_ctx->symt_cache[sc_void]; + di->symt = di->unit_ctx->module_ctx->symt_cache[sc_void];
children = dwarf2_get_di_children(di); if (children) for (i = 0; i < vector_length(children); i++) { child = *(dwarf2_debug_info_t**)vector_at(children, i); - dwarf2_load_one_entry(ctx, child); + dwarf2_load_one_entry(child); } }
-static void dwarf2_load_one_entry(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static void dwarf2_load_one_entry(dwarf2_debug_info_t* di) { switch (di->abbrev->tag) { case DW_TAG_typedef: - dwarf2_parse_typedef(ctx, di); + dwarf2_parse_typedef(di); break; case DW_TAG_base_type: - dwarf2_parse_base_type(ctx, di); + dwarf2_parse_base_type(di); break; case DW_TAG_pointer_type: - dwarf2_parse_pointer_type(ctx, di); + dwarf2_parse_pointer_type(di); break; case DW_TAG_class_type: - dwarf2_parse_udt_type(ctx, di, UdtClass); + dwarf2_parse_udt_type(di, UdtClass); break; case DW_TAG_structure_type: - dwarf2_parse_udt_type(ctx, di, UdtStruct); + dwarf2_parse_udt_type(di, UdtStruct); break; case DW_TAG_union_type: - dwarf2_parse_udt_type(ctx, di, UdtUnion); + dwarf2_parse_udt_type(di, UdtUnion); break; case DW_TAG_array_type: - dwarf2_parse_array_type(ctx, di); + dwarf2_parse_array_type(di); break; case DW_TAG_const_type: - dwarf2_parse_const_type(ctx, di); + dwarf2_parse_const_type(di); break; case DW_TAG_volatile_type: - dwarf2_parse_volatile_type(ctx, di); + dwarf2_parse_volatile_type(di); break; case DW_TAG_unspecified_type: - dwarf2_parse_unspecified_type(ctx, di); + dwarf2_parse_unspecified_type(di); break; case DW_TAG_reference_type: - dwarf2_parse_reference_type(ctx, di); + dwarf2_parse_reference_type(di); break; case DW_TAG_enumeration_type: - dwarf2_parse_enumeration_type(ctx, di); + dwarf2_parse_enumeration_type(di); break; case DW_TAG_subprogram: - dwarf2_parse_subprogram(ctx, di); + dwarf2_parse_subprogram(di); break; case DW_TAG_subroutine_type: - dwarf2_parse_subroutine_type(ctx, di); + dwarf2_parse_subroutine_type(di); break; case DW_TAG_variable: { dwarf2_subprogram_t subpgm;
- subpgm.ctx = ctx; + subpgm.ctx = di->unit_ctx; subpgm.func = NULL; subpgm.frame.kind = loc_absolute; subpgm.frame.offset = 0; @@ -2251,7 +2233,7 @@ static void dwarf2_load_one_entry(dwarf2_parse_context_t* ctx, } break; case DW_TAG_namespace: - dwarf2_parse_namespace(ctx, di); + dwarf2_parse_namespace(di); break; /* silence a couple of C++ defines */ case DW_TAG_imported_module: @@ -2624,7 +2606,7 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx) if (children) for (i = 0; i < vector_length(children); i++) { child = *(dwarf2_debug_info_t**)vector_at(children, i); - dwarf2_load_one_entry(ctx, child); + dwarf2_load_one_entry(child); } if (dwarf2_find_attribute(di, DW_AT_stmt_list, &stmt_list)) {
This helper takes into account that source and destination debug_info can be in different dwarf units, and even different debug files (DWZ)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 77 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 25 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index bf4999ab0bb..c0f4afcb606 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -134,6 +134,7 @@ struct attribute const char* string; struct dwarf2_block block; } u; + const struct dwarf2_debug_info_s* debug_info; };
typedef struct dwarf2_debug_info_s @@ -711,6 +712,8 @@ static BOOL dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, return TRUE; }
+static dwarf2_debug_info_t* dwarf2_jump_to_debug_info(struct attribute* attr); + static BOOL dwarf2_find_attribute(const dwarf2_debug_info_t* di, unsigned at, struct attribute* attr) { @@ -722,6 +725,7 @@ static BOOL dwarf2_find_attribute(const dwarf2_debug_info_t* di, while (di) { ref_abbrev_attr = NULL; + attr->debug_info = di; for (i = 0, abbrev_attr = di->abbrev->attrs; abbrev_attr; i++, abbrev_attr = abbrev_attr->next) { if (abbrev_attr->attribute == at) @@ -743,12 +747,49 @@ static BOOL dwarf2_find_attribute(const dwarf2_debug_info_t* di, /* do we have either an abstract origin or a specification debug entry to look into ? */ if (!ref_abbrev_attr || !dwarf2_fill_attr(di->unit_ctx, ref_abbrev_attr, di->data[refidx], attr)) break; - if (!(di = sparse_array_find(&di->unit_ctx->debug_info_table, attr->u.uvalue))) + if (!(di = dwarf2_jump_to_debug_info(attr))) + { FIXME("Should have found the debug info entry\n"); + break; + } } return FALSE; }
+static dwarf2_debug_info_t* dwarf2_jump_to_debug_info(struct attribute* attr) +{ + dwarf2_parse_context_t* ref_ctx = NULL; + BOOL with_other = TRUE; + dwarf2_debug_info_t* ret; + + switch (attr->form) + { + case DW_FORM_ref_addr: + ref_ctx = dwarf2_locate_cu(attr->debug_info->unit_ctx->module_ctx, attr->u.uvalue); + break; + default: + with_other = FALSE; + ref_ctx = attr->debug_info->unit_ctx; + break; + } + if (!ref_ctx) return FALSE; + /* There are cases where we end up with a circular reference between two (or more) + * compilation units. Before this happens, try to see if we can refer to an already + * loaded debug_info in the target compilation unit (even if all the debug_info + * haven't been loaded yet). + */ + if (ref_ctx->status == UNIT_BEINGLOADED && + (ret = sparse_array_find(&ref_ctx->debug_info_table, attr->u.uvalue))) + return ret; + if (with_other) + { + /* ensure CU is fully loaded */ + if (ref_ctx != attr->debug_info->unit_ctx && !dwarf2_parse_compilation_unit(ref_ctx)) + return NULL; + } + return sparse_array_find(&ref_ctx->debug_info_table, attr->u.uvalue); +} + static void dwarf2_load_one_entry(dwarf2_debug_info_t*);
#define Wine_DW_no_register 0x7FFFFFFF @@ -1069,24 +1110,9 @@ static struct symt* dwarf2_lookup_type(const dwarf2_debug_info_t* di) if (!dwarf2_find_attribute(di, DW_AT_type, &attr)) /* this is only valid if current language of CU is C or C++ */ return di->unit_ctx->module_ctx->symt_cache[sc_void]; - if (!(type = sparse_array_find(&di->unit_ctx->debug_info_table, attr.u.uvalue))) - { - if (attr.form == DW_FORM_ref_addr) - { - dwarf2_parse_context_t* ref_ctx = dwarf2_locate_cu(di->unit_ctx->module_ctx, attr.u.uvalue); - /* ensure CU is fully loaded */ - if (ref_ctx && dwarf2_parse_compilation_unit(ref_ctx)) - { - type = sparse_array_find(&ref_ctx->debug_info_table, attr.u.uvalue); - if (type) TRACE("Found type ref %lx in another CU %s\n", attr.u.uvalue, dwarf2_debug_unit_ctx(ref_ctx)); - } - } - if (!type) - { - FIXME("Unable to find back reference to type 0x%lx (form=0x%lx)\n", attr.u.uvalue, attr.form); - return di->unit_ctx->module_ctx->symt_cache[sc_unknown]; - } - } + if (!(type = dwarf2_jump_to_debug_info(&attr))) + return di->unit_ctx->module_ctx->symt_cache[sc_unknown]; + if (type == di) { FIXME("Reference to itself\n"); @@ -1112,17 +1138,13 @@ static const char* dwarf2_get_cpp_name(dwarf2_debug_info_t* di, const char* name struct attribute spec;
if (di->abbrev->tag == DW_TAG_compile_unit) return name; - if (!di->unit_ctx->cpp_name) - di->unit_ctx->cpp_name = pool_alloc(&di->unit_ctx->pool, MAX_SYM_NAME); - last = di->unit_ctx->cpp_name + MAX_SYM_NAME - strlen(name) - 1; - strcpy(last, name);
/* if the di is a definition, but has also a (previous) declaration, then scope must * be gotten from declaration not definition */ if (dwarf2_find_attribute(di, DW_AT_specification, &spec) && spec.gotten_from == attr_direct) { - di = sparse_array_find(&di->unit_ctx->debug_info_table, spec.u.uvalue); + di = dwarf2_jump_to_debug_info(&spec); if (!di) { FIXME("Should have found the debug info entry\n"); @@ -1130,6 +1152,11 @@ static const char* dwarf2_get_cpp_name(dwarf2_debug_info_t* di, const char* name } }
+ if (!di->unit_ctx->cpp_name) + di->unit_ctx->cpp_name = pool_alloc(&di->unit_ctx->pool, MAX_SYM_NAME); + last = di->unit_ctx->cpp_name + MAX_SYM_NAME - strlen(name) - 1; + strcpy(last, name); + for (di = di->parent; di; di = di->parent) { switch (di->abbrev->tag) @@ -1295,7 +1322,7 @@ static struct vector* dwarf2_get_di_children(dwarf2_debug_info_t* di) if (di->abbrev->have_child) return &di->children; if (!dwarf2_find_attribute(di, DW_AT_specification, &spec)) break; - if (!(di = sparse_array_find(&di->unit_ctx->debug_info_table, spec.u.uvalue))) + if (!(di = dwarf2_jump_to_debug_info(&spec))) FIXME("Should have found the debug info entry\n"); } return NULL;
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index c0f4afcb606..fffc7c37c13 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -680,9 +680,16 @@ static BOOL dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, break;
case DW_FORM_GNU_ref_alt: - FIXME("Unhandled FORM_GNU_ref_alt\n"); - attr->u.uvalue = 0; - return FALSE; + if (!ctx->module_ctx->dwz) + { + ERR("No DWZ file present for GNU_ref_alt in %s\n", debugstr_w(ctx->module_ctx->module->modulename)); + attr->u.uvalue = 0; + return FALSE; + } + attr->u.uvalue = dwarf2_get_addr(data, ctx->head.offset_size); + TRACE("ref_alt<0x%lx>\n", attr->u.uvalue); + break; + case DW_FORM_GNU_strp_alt: if (ctx->module_ctx->dwz) { @@ -767,6 +774,10 @@ static dwarf2_debug_info_t* dwarf2_jump_to_debug_info(struct attribute* attr) case DW_FORM_ref_addr: ref_ctx = dwarf2_locate_cu(attr->debug_info->unit_ctx->module_ctx, attr->u.uvalue); break; + case DW_FORM_GNU_ref_alt: + if (attr->debug_info->unit_ctx->module_ctx->dwz) + ref_ctx = dwarf2_locate_cu(&attr->debug_info->unit_ctx->module_ctx->dwz->module_ctx, attr->u.uvalue); + break; default: with_other = FALSE; ref_ctx = attr->debug_info->unit_ctx;
Can have huge performance impact: libgcc_s.so.8 load time decreased from 40 seconds down to less than 1 second
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index fffc7c37c13..f67efc43993 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -3710,7 +3710,7 @@ static void dwarf2_module_remove(struct process* pcs, struct module_format* modf
static BOOL dwarf2_load_CU_module(dwarf2_parse_module_context_t* module_ctx, struct module* module, dwarf2_section_t* sections, ULONG_PTR load_offset, - const struct elf_thunk_area* thunks) + const struct elf_thunk_area* thunks, BOOL is_dwz) { dwarf2_traverse_context_t mod_ctx; unsigned i; @@ -3736,9 +3736,14 @@ static BOOL dwarf2_load_CU_module(dwarf2_parse_module_context_t* module_ctx, str dwarf2_parse_compilation_unit_head(unit_ctx, &mod_ctx); }
- /* phase2: load content of all CU */ - for (i = 0; i < module_ctx->unit_contexts.num_elts; ++i) - dwarf2_parse_compilation_unit((dwarf2_parse_context_t*)vector_at(&module_ctx->unit_contexts, i)); + /* phase2: load content of all CU + * If this is a DWZ alternate module, don't load all debug_info at once + * wait for main module to ask for them (it's likely it won't need them all) + * Doing this can lead to a huge performance improvement. + */ + if (!is_dwz) + for (i = 0; i < module_ctx->unit_contexts.num_elts; ++i) + dwarf2_parse_compilation_unit((dwarf2_parse_context_t*)vector_at(&module_ctx->unit_contexts, i));
return TRUE; } @@ -3765,7 +3770,7 @@ static dwarf2_dwz_alternate_t* dwarf2_load_dwz(struct image_file_map* fmap, stru dwarf2_init_section(&dwz->sections[section_ranges], fmap_dwz, ".debug_ranges", ".zdebug_ranges", &dwz->sectmap[section_ranges]);
dwz->module_ctx.dwz = NULL; - dwarf2_load_CU_module(&dwz->module_ctx, module, dwz->sections, 0/*FIXME*/, NULL); + dwarf2_load_CU_module(&dwz->module_ctx, module, dwz->sections, 0/*FIXME*/, NULL, TRUE); return dwz; }
@@ -3864,7 +3869,7 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, dwarf2_modfmt->u.dwarf2_info->num_cuheads = 0;
module_ctx.dwz = dwarf2_load_dwz(fmap, module); - dwarf2_load_CU_module(&module_ctx, module, section, load_offset, thunks); + dwarf2_load_CU_module(&module_ctx, module, section, load_offset, thunks, FALSE);
dwarf2_modfmt->module->module.SymType = SymDia; /* hide dwarf versions in CVSig