Structure of dwarf info: an image, made of several compilation units, each compilation unit contains several debug info entries (DIE in dwarf-ish)
We currently parse all of those in one pass. This needs to be reviewed for Dwarf4: - a DIE can reference another DIE in another compilation unit we currently support reference into the same CU only => we need to handle parsing of several CU at the same time - a DIE can reference a DIE in another image (with GNU's extension in dwarf4, will become standard in dwarf5) => this is used for example to store all C++ basic debug info (like STL) in a dedicated image, that is shared across several modules (this case is done at system level)
This serie basically refactors the parsing mechanism to decouple the module parsing from the compilation unit parsing. It implements reference to DIE in another CU of same image.
Next serie will focus on reference into another image.
--
Eric Pouech (9): dbghelp/dwarf: separate cu handling from module handling dbghelp/dwarf: Moving the symt_cache from the unit context into the module context dbghelp/dwarf: Keep open and keep track of parse_context_t inside a module_context_t dbghelp: split in two phases the parsing of a dwarf compilation unit dbghelp/dwarf: Added ability to get to a DIE in a different CU dbghelp/dwarf: Properly supporting DW_FORM_ref_addr in type DIE lookup dbghelp/dwarf: Detect out of section sibling DIE information dbghelp/dwarf: add reference for a DIE to its CU programs/winedbg: show dwarf version(s) used for a module
dlls/dbghelp/dwarf.c | 288 ++++++++++++++++++++++++++-------------- programs/winedbg/info.c | 13 +- 2 files changed, 202 insertions(+), 99 deletions(-)
Move out of dwarf2_parse_context_s structure information related to the module and put them into the dwarf2_parse_module_context_s structure (actually the dwarf2_parse_context should be named dwarf2_parse_cu_context as it only related to a compilation unit)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 180 ++++++++++++++++++++++++++------------------------ 1 file changed, 95 insertions(+), 85 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 098576d620f..e9d62404eba 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -173,17 +173,25 @@ typedef struct dwarf2_cuhead_s unsigned char offset_size; /* size of offset inside DWARF */ } dwarf2_cuhead_t;
-typedef struct dwarf2_parse_context_s +typedef struct dwarf2_parse_module_context_s { + ULONG_PTR load_offset; const dwarf2_section_t* sections; + struct module* module; + const struct elf_thunk_area*thunks; +} dwarf2_parse_module_context_t; + +/* this is the context used for parsing a compilation unit + * inside an ELF/PE section (likely .debug_info) + */ +typedef struct dwarf2_parse_context_s +{ + dwarf2_parse_module_context_t* module_ctx; unsigned section; struct pool pool; - struct module* module; struct symt_compiland* compiland; - const struct elf_thunk_area*thunks; struct sparse_array abbrev_table; struct sparse_array debug_info_table; - ULONG_PTR load_offset; ULONG_PTR ref_offset; struct symt* symt_cache[sc_num]; /* void, unknown */ char* cpp_name; @@ -390,7 +398,7 @@ static const char* dwarf2_debug_traverse_ctx(const dwarf2_traverse_context_t* ct static const char* dwarf2_debug_ctx(const dwarf2_parse_context_t* ctx) { return wine_dbg_sprintf("ctx(%p,%s)", - ctx, debugstr_w(ctx->module->modulename)); + ctx, debugstr_w(ctx->module_ctx->module->modulename)); }
static const char* dwarf2_debug_di(const dwarf2_debug_info_t* di) @@ -603,14 +611,14 @@ static BOOL dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, case DW_FORM_strp: { ULONG_PTR ofs = dwarf2_get_addr(data, ctx->head.offset_size); - if (ofs >= ctx->sections[section_string].size) + if (ofs >= ctx->module_ctx->sections[section_string].size) { ERR("Out of bounds string offset (%08lx)\n", ofs); attr->u.string = "<<outofbounds-strp>>"; } else { - attr->u.string = (const char*)ctx->sections[section_string].address + ofs; + attr->u.string = (const char*)ctx->module_ctx->sections[section_string].address + ofs; TRACE("strp<%s>\n", debugstr_a(attr->u.string)); } } @@ -993,7 +1001,7 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx, lctx.data = xloc.u.block.ptr; lctx.end_data = xloc.u.block.ptr + xloc.u.block.size;
- err = compute_location(ctx->module, &ctx->head, &lctx, loc, NULL, frame); + err = compute_location(ctx->module_ctx->module, &ctx->head, &lctx, loc, NULL, frame); if (err < 0) { loc->kind = loc_error; @@ -1001,7 +1009,7 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx, } else if (loc->kind == loc_dwarf2_block) { - unsigned* ptr = pool_alloc(&ctx->module->pool, + unsigned* ptr = pool_alloc(&ctx->module_ctx->module->pool, sizeof(unsigned) + xloc.u.block.size); *ptr = xloc.u.block.size; memcpy(ptr + 1, xloc.u.block.ptr, xloc.u.block.size); @@ -1110,9 +1118,9 @@ static BOOL dwarf2_read_range(dwarf2_parse_context_t* ctx, const dwarf2_debug_in dwarf2_traverse_context_t traverse; ULONG_PTR low, high;
- traverse.data = ctx->sections[section_ranges].address + range.u.uvalue; - traverse.end_data = ctx->sections[section_ranges].address + - ctx->sections[section_ranges].size; + traverse.data = ctx->module_ctx->sections[section_ranges].address + range.u.uvalue; + traverse.end_data = ctx->module_ctx->sections[section_ranges].address + + ctx->module_ctx->sections[section_ranges].size;
*plow = ULONG_MAX; *phigh = 0; @@ -1164,7 +1172,7 @@ static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx, unsigned i; struct attribute sibling;
- offset = traverse->data - ctx->sections[ctx->section].address; + offset = traverse->data - ctx->module_ctx->sections[ctx->section].address; entry_code = dwarf2_leb128_as_unsigned(traverse); TRACE("found entry_code %lu at 0x%lx\n", entry_code, offset); if (!entry_code) @@ -1207,11 +1215,11 @@ static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx, } } if (dwarf2_find_attribute(ctx, di, DW_AT_sibling, &sibling) && - traverse->data != ctx->sections[ctx->section].address + sibling.u.uvalue) + traverse->data != ctx->module_ctx->sections[ctx->section].address + sibling.u.uvalue) { WARN("setting cursor for %s to next sibling <0x%lx>\n", dwarf2_debug_traverse_ctx(traverse), sibling.u.uvalue); - traverse->data = ctx->sections[ctx->section].address + sibling.u.uvalue; + traverse->data = ctx->module_ctx->sections[ctx->section].address + sibling.u.uvalue; } *pdi = di; return TRUE; @@ -1262,7 +1270,7 @@ 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, bt, name.u.string, size.u.uvalue)->symt; + di->symt = &symt_new_basic(ctx->module_ctx->module, bt, name.u.string, size.u.uvalue)->symt;
if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); return di->symt; @@ -1282,7 +1290,7 @@ static struct symt* dwarf2_parse_typedef(dwarf2_parse_context_t* ctx, ref_type = dwarf2_lookup_type(ctx, di);
if (name.u.string) - di->symt = &symt_new_typedef(ctx->module, ref_type, name.u.string)->symt; + di->symt = &symt_new_typedef(ctx->module_ctx->module, ref_type, name.u.string)->symt; if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); return di->symt; } @@ -1299,7 +1307,7 @@ static struct symt* dwarf2_parse_pointer_type(dwarf2_parse_context_t* ctx,
if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = sizeof(void *); ref_type = dwarf2_lookup_type(ctx, di); - di->symt = &symt_new_pointer(ctx->module, ref_type, size.u.uvalue)->symt; + di->symt = &symt_new_pointer(ctx->module_ctx->module, ref_type, size.u.uvalue)->symt; if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); return di->symt; } @@ -1324,7 +1332,7 @@ 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, btInt, "int", 4)->symt; + idx_type = &symt_new_basic(ctx->module_ctx->module, btInt, "int", 4)->symt; min.u.uvalue = 0; cnt.u.uvalue = 0; } @@ -1348,7 +1356,7 @@ static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, break; } } - di->symt = &symt_new_array(ctx->module, min.u.uvalue, cnt.u.uvalue, ref_type, idx_type)->symt; + di->symt = &symt_new_array(ctx->module_ctx->module, min.u.uvalue, cnt.u.uvalue, ref_type, idx_type)->symt; return di->symt; }
@@ -1399,7 +1407,7 @@ 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, btVoid, name.u.string, size.u.uvalue); + basic = symt_new_basic(ctx->module_ctx->module, btVoid, name.u.string, size.u.uvalue); di->symt = &basic->symt;
if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); @@ -1417,7 +1425,7 @@ static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx,
ref_type = dwarf2_lookup_type(ctx, di); /* FIXME: for now, we hard-wire C++ references to pointers */ - di->symt = &symt_new_pointer(ctx->module, ref_type, sizeof(void *))->symt; + di->symt = &symt_new_pointer(ctx->module_ctx->module, ref_type, sizeof(void *))->symt;
if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n");
@@ -1464,13 +1472,13 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx, if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &nbytes)) { DWORD64 size; - nbytes.u.uvalue = symt_get_info(ctx->module, elt_type, TI_GET_LENGTH, &size) ? + nbytes.u.uvalue = symt_get_info(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, parent, name.u.string, elt_type, + symt_add_udt_element(ctx->module_ctx->module, parent, name.u.string, elt_type, loc.offset, bit_offset.u.uvalue, bit_size.u.uvalue);
@@ -1499,7 +1507,7 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, name.u.string = "zz_anon_zz"; if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &size)) size.u.uvalue = 0;
- di->symt = &symt_new_udt(ctx->module, dwarf2_get_cpp_name(ctx, di, name.u.string), + di->symt = &symt_new_udt(ctx->module_ctx->module, dwarf2_get_cpp_name(ctx, di, name.u.string), size.u.uvalue, udt)->symt;
children = dwarf2_get_di_children(ctx, di); @@ -1562,7 +1570,7 @@ static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx,
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; - symt_add_enum_element(ctx->module, parent, name.u.string, value.u.svalue); + symt_add_enum_element(ctx->module_ctx->module, parent, name.u.string, value.u.svalue);
if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); } @@ -1586,13 +1594,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, btInt, "char", 1); break; - case 2: basetype = symt_new_basic(ctx->module, btInt, "short", 2); break; + 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; default: - case 4: basetype = symt_new_basic(ctx->module, btInt, "int", 4); break; + case 4: basetype = symt_new_basic(ctx->module_ctx->module, btInt, "int", 4); break; }
- di->symt = &symt_new_enum(ctx->module, name.u.string, &basetype->symt)->symt; + di->symt = &symt_new_enum(ctx->module_ctx->module, name.u.string, &basetype->symt)->symt;
children = dwarf2_get_di_children(ctx, di); /* FIXME: should we use the sibling stuff ?? */ @@ -1664,8 +1672,8 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, /* FIXME: we don't handle its scope yet */ if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_external, &ext)) ext.u.uvalue = 0; - loc.offset += subpgm->ctx->load_offset; - symt_new_global_variable(subpgm->ctx->module, subpgm->ctx->compiland, + 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, loc, 0, param_type); break; @@ -1678,7 +1686,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, * pmt/variable in a register */ if (subpgm->func) - symt_add_func_local(subpgm->ctx->module, subpgm->func, + symt_add_func_local(subpgm->ctx->module_ctx->module, subpgm->func, is_pmt ? DataIsParam : DataIsLocal, &loc, block, param_type, name.u.string); break; @@ -1717,7 +1725,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, * however, the value of the string is in the code somewhere */ v.n1.n2.vt = VT_I1 | VT_BYREF; - v.n1.n2.n3.byref = pool_strdup(&subpgm->ctx->module->pool, value.u.string); + v.n1.n2.n3.byref = pool_strdup(&subpgm->ctx->module_ctx->module->pool, value.u.string); break;
case DW_FORM_block: @@ -1733,7 +1741,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, case 4: v.n1.n2.n3.lVal = *(DWORD*)value.u.block.ptr; break; default: v.n1.n2.vt = VT_I1 | VT_BYREF; - v.n1.n2.n3.byref = pool_alloc(&subpgm->ctx->module->pool, value.u.block.size); + v.n1.n2.n3.byref = pool_alloc(&subpgm->ctx->module_ctx->module->pool, value.u.block.size); memcpy(v.n1.n2.n3.byref, value.u.block.ptr, value.u.block.size); } break; @@ -1743,7 +1751,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, debugstr_a(name.u.string), value.form); v.n1.n2.vt = VT_EMPTY; } - di->symt = &symt_new_constant(subpgm->ctx->module, subpgm->ctx->compiland, + di->symt = &symt_new_constant(subpgm->ctx->module_ctx->module, subpgm->ctx->compiland, name.u.string, param_type, &v)->symt; } else @@ -1753,7 +1761,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, loc.reg = loc_err_no_location; if (subpgm->func) { - symt_add_func_local(subpgm->ctx->module, subpgm->func, + symt_add_func_local(subpgm->ctx->module_ctx->module, subpgm->func, is_pmt ? DataIsParam : DataIsLocal, &loc, block, param_type, name.u.string); } @@ -1763,7 +1771,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, } } if (is_pmt && subpgm->func && symt_check_tag(subpgm->func->type, SymTagFunctionType)) - symt_add_function_signature_parameter(subpgm->ctx->module, + symt_add_function_signature_parameter(subpgm->ctx->module_ctx->module, (struct symt_function_signature*)subpgm->func->type, param_type);
@@ -1784,8 +1792,8 @@ static void dwarf2_parse_subprogram_label(dwarf2_subprogram_t* subpgm, name.u.string = NULL;
loc.kind = loc_absolute; - loc.offset = subpgm->ctx->load_offset + low_pc.u.uvalue; - symt_add_function_point(subpgm->ctx->module, subpgm->func, SymTagLabel, + loc.offset = subpgm->ctx->module_ctx->load_offset + low_pc.u.uvalue; + symt_add_function_point(subpgm->ctx->module_ctx->module, subpgm->func, SymTagLabel, &loc, name.u.string); }
@@ -1814,8 +1822,8 @@ static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm, return; }
- block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block, - subpgm->ctx->load_offset + low_pc - subpgm->func->address, + block = symt_open_func_block(subpgm->ctx->module_ctx->module, subpgm->func, parent_block, + subpgm->ctx->module_ctx->load_offset + low_pc - subpgm->func->address, high_pc - low_pc);
children = dwarf2_get_di_children(subpgm->ctx, di); @@ -1847,7 +1855,7 @@ static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm, dwarf2_debug_di(di)); } } - symt_close_func_block(subpgm->ctx->module, subpgm->func, block, 0); + symt_close_func_block(subpgm->ctx->module_ctx->module, subpgm->func, block, 0); }
static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, @@ -1868,8 +1876,8 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, return; }
- block = symt_open_func_block(subpgm->ctx->module, subpgm->func, parent_block, - subpgm->ctx->load_offset + low_pc - subpgm->func->address, + block = symt_open_func_block(subpgm->ctx->module_ctx->module, subpgm->func, parent_block, + subpgm->ctx->module_ctx->load_offset + low_pc - subpgm->func->address, high_pc - low_pc);
children = dwarf2_get_di_children(subpgm->ctx, di); @@ -1929,7 +1937,7 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, } }
- symt_close_func_block(subpgm->ctx->module, subpgm->func, block, 0); + symt_close_func_block(subpgm->ctx->module_ctx->module, subpgm->func, block, 0); }
static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, @@ -1981,15 +1989,15 @@ 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->load_offset + low_pc, ctx->thunks) >= 0) + if (elf_is_in_thunk_area(ctx->module_ctx->load_offset + low_pc, ctx->module_ctx->thunks) >= 0) return NULL; ret_type = dwarf2_lookup_type(ctx, di);
/* FIXME: assuming C source code */ - sig_type = symt_new_function_signature(ctx->module, ret_type, CV_CALL_FAR_C); - subpgm.func = symt_new_function(ctx->module, ctx->compiland, + 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), - ctx->load_offset + low_pc, high_pc - low_pc, + ctx->module_ctx->load_offset + low_pc, high_pc - low_pc, &sig_type->symt); di->symt = &subpgm.func->symt; subpgm.ctx = ctx; @@ -2057,7 +2065,7 @@ 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, subpgm.func, SymTagCustom, + symt_add_function_point(ctx->module_ctx->module, subpgm.func, SymTagCustom, &subpgm.frame, NULL); }
@@ -2080,7 +2088,7 @@ static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx, ret_type = dwarf2_lookup_type(ctx, di);
/* FIXME: assuming C source code */ - sig_type = symt_new_function_signature(ctx->module, ret_type, CV_CALL_FAR_C); + sig_type = symt_new_function_signature(ctx->module_ctx->module, ret_type, CV_CALL_FAR_C);
children = dwarf2_get_di_children(ctx, di); if (children) for (i = 0; i < vector_length(children); i++) @@ -2090,7 +2098,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, sig_type, + symt_add_function_signature_parameter(ctx->module_ctx->module, sig_type, dwarf2_lookup_type(ctx, child)); break; case DW_TAG_unspecified_parameters: @@ -2215,8 +2223,7 @@ static void dwarf2_set_line_number(struct module* module, ULONG_PTR address, } }
-static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, - dwarf2_parse_context_t* ctx, +static BOOL dwarf2_parse_line_numbers(dwarf2_parse_context_t* ctx, const char* compile_dir, ULONG_PTR offset) { @@ -2232,16 +2239,16 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, const char** p;
/* section with line numbers stripped */ - if (sections[section_line].address == IMAGE_NO_MAP) + if (ctx->module_ctx->sections[section_line].address == IMAGE_NO_MAP) return FALSE;
- if (offset + 4 > sections[section_line].size) + if (offset + 4 > ctx->module_ctx->sections[section_line].size) { WARN("out of bounds offset\n"); return FALSE; } - traverse.data = sections[section_line].address + offset; - traverse.end_data = sections[section_line].address + sections[section_line].size; + traverse.data = ctx->module_ctx->sections[section_line].address + offset; + traverse.end_data = ctx->module_ctx->sections[section_line].address + ctx->module_ctx->sections[section_line].size;
length = dwarf2_parse_3264(&traverse, &offset_size); if (offset_size != ctx->head.offset_size) @@ -2251,7 +2258,7 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, } traverse.end_data = traverse.data + length;
- if (traverse.end_data > sections[section_line].address + sections[section_line].size) + if (traverse.end_data > ctx->module_ctx->sections[section_line].address + ctx->module_ctx->sections[section_line].size) { WARN("out of bounds header\n"); return FALSE; @@ -2312,7 +2319,7 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, dir = *(const char**)vector_at(&dirs, dir_index); TRACE("Got file %s/%s (%u,%lu)\n", debugstr_a(dir), debugstr_a(name), mod_time, length); psrc = vector_add(&files, &ctx->pool); - *psrc = source_new(ctx->module, dir, name); + *psrc = source_new(ctx->module_ctx->module, dir, name); } traverse.data++;
@@ -2336,14 +2343,14 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections,
address += (delta / line_range) * insn_size; line += line_base + (delta % line_range); - dwarf2_set_line_number(ctx->module, address, &files, file, line); + dwarf2_set_line_number(ctx->module_ctx->module, address, &files, file, line); } else { switch (opcode) { case DW_LNS_copy: - dwarf2_set_line_number(ctx->module, address, &files, file, line); + dwarf2_set_line_number(ctx->module_ctx->module, address, &files, file, line); break; case DW_LNS_advance_pc: address += insn_size * dwarf2_leb128_as_unsigned(&traverse); @@ -2374,11 +2381,11 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, switch (extopcode) { case DW_LNE_end_sequence: - dwarf2_set_line_number(ctx->module, address, &files, file, line); + dwarf2_set_line_number(ctx->module_ctx->module, address, &files, file, line); end_sequence = TRUE; break; case DW_LNE_set_address: - address = ctx->load_offset + dwarf2_parse_addr_head(&traverse, &ctx->head); + address = ctx->module_ctx->load_offset + dwarf2_parse_addr_head(&traverse, &ctx->head); break; case DW_LNE_define_file: FIXME("not handled define file %s\n", debugstr_a((char *)traverse.data)); @@ -2432,11 +2439,8 @@ unsigned dwarf2_cache_cuhead(struct dwarf2_module_info_s* module, struct symt_co return TRUE; }
-static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, - struct module* module, - const struct elf_thunk_area* thunks, - dwarf2_traverse_context_t* mod_ctx, - ULONG_PTR load_offset) +static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_ctx, + dwarf2_traverse_context_t* mod_ctx) { dwarf2_parse_context_t ctx; dwarf2_traverse_context_t abbrev_ctx; @@ -2459,7 +2463,7 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, ctx.head.word_size = dwarf2_parse_byte(&cu_ctx);
TRACE("Compilation Unit Header found at 0x%x:\n", - (int)(comp_unit_start - sections[section_debug].address)); + (int)(comp_unit_start - module_ctx->sections[section_debug].address)); TRACE("- length: %lu\n", cu_length); TRACE("- version: %u\n", ctx.head.version); TRACE("- abbrev_offset: %lu\n", cu_abbrev_offset); @@ -2485,19 +2489,16 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, }
pool_init(&ctx.pool, 65536); - ctx.sections = sections; ctx.section = section_debug; - ctx.module = module; - ctx.thunks = thunks; - ctx.load_offset = load_offset; - ctx.ref_offset = comp_unit_start - sections[section_debug].address; + ctx.ref_offset = comp_unit_start - module_ctx->sections[section_debug].address; memset(ctx.symt_cache, 0, sizeof(ctx.symt_cache)); - ctx.symt_cache[sc_void] = &symt_new_basic(module, btVoid, "void", 0)->symt; - ctx.symt_cache[sc_unknown] = &symt_new_basic(module, btNoType, "# unknown", 0)->symt; + ctx.symt_cache[sc_void] = &symt_new_basic(module_ctx->module, btVoid, "void", 0)->symt; + ctx.symt_cache[sc_unknown] = &symt_new_basic(module_ctx->module, btNoType, "# unknown", 0)->symt; ctx.cpp_name = NULL; + ctx.module_ctx = module_ctx;
- abbrev_ctx.data = sections[section_abbrev].address + cu_abbrev_offset; - abbrev_ctx.end_data = sections[section_abbrev].address + sections[section_abbrev].size; + abbrev_ctx.data = module_ctx->sections[section_abbrev].address + cu_abbrev_offset; + abbrev_ctx.end_data = module_ctx->sections[section_abbrev].address + module_ctx->sections[section_abbrev].size; dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128); @@ -2522,8 +2523,11 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections,
if (!dwarf2_find_attribute(&ctx, di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0; - ctx.compiland = symt_new_compiland(module, ctx.load_offset + low_pc.u.uvalue, - source_new(module, comp_dir.u.string, name.u.string)); + + ctx.compiland = symt_new_compiland(module_ctx->module, module_ctx->load_offset + low_pc.u.uvalue, + source_new(module_ctx->module, comp_dir.u.string, name.u.string)); + dwarf2_cache_cuhead(module_ctx->module->format_info[DFI_DWARF]->u.dwarf2_info, ctx.compiland, &ctx.head); + di->symt = &ctx.compiland->symt; children = dwarf2_get_di_children(&ctx, di); if (children) for (i = 0; i < vector_length(children); i++) @@ -2533,8 +2537,8 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, } if (dwarf2_find_attribute(&ctx, di, DW_AT_stmt_list, &stmt_list)) { - if (dwarf2_parse_line_numbers(sections, &ctx, comp_dir.u.string, stmt_list.u.uvalue)) - module->module.LineNumbers = TRUE; + if (dwarf2_parse_line_numbers(&ctx, comp_dir.u.string, stmt_list.u.uvalue)) + module_ctx->module->module.LineNumbers = TRUE; } ret = TRUE; } @@ -3602,6 +3606,7 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, debug_line_sect, debug_ranges_sect, eh_frame_sect; BOOL ret = TRUE; struct module_format* dwarf2_modfmt; + dwarf2_parse_module_context_t module_ctx;
if (!dwarf2_init_section(&eh_frame, fmap, ".eh_frame", NULL, &eh_frame_sect)) /* lld produces .eh_fram to avoid generating a long name */ @@ -3657,9 +3662,14 @@ 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; + while (mod_ctx.data < mod_ctx.end_data) { - dwarf2_parse_compilation_unit(section, dwarf2_modfmt->module, thunks, &mod_ctx, load_offset); + dwarf2_parse_compilation_unit(&module_ctx, &mod_ctx); } dwarf2_modfmt->module->module.SymType = SymDia; dwarf2_modfmt->module->module.CVSig = 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24);
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index e9d62404eba..4bb5bb23ac6 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -179,6 +179,7 @@ typedef struct dwarf2_parse_module_context_s const dwarf2_section_t* sections; struct module* module; const struct elf_thunk_area*thunks; + struct symt* symt_cache[sc_num]; /* void, unknown */ } dwarf2_parse_module_context_t;
/* this is the context used for parsing a compilation unit @@ -193,7 +194,6 @@ typedef struct dwarf2_parse_context_s struct sparse_array abbrev_table; struct sparse_array debug_info_table; ULONG_PTR ref_offset; - struct symt* symt_cache[sc_num]; /* void, unknown */ char* cpp_name; dwarf2_cuhead_t head; } dwarf2_parse_context_t; @@ -1027,16 +1027,16 @@ static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx,
if (!dwarf2_find_attribute(ctx, di, DW_AT_type, &attr)) /* this is only valid if current language of CU is C or C++ */ - return ctx->symt_cache[sc_void]; + return ctx->module_ctx->symt_cache[sc_void]; if (!(type = sparse_array_find(&ctx->debug_info_table, attr.u.uvalue))) { FIXME("Unable to find back reference to type %lx\n", attr.u.uvalue); - return ctx->symt_cache[sc_unknown]; + return ctx->module_ctx->symt_cache[sc_unknown]; } if (type == di) { FIXME("Reference to itself\n"); - return ctx->symt_cache[sc_unknown]; + return ctx->module_ctx->symt_cache[sc_unknown]; } if (!type->symt) { @@ -1045,7 +1045,7 @@ static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx, if (!type->symt) { FIXME("Unable to load forward reference for tag %lx\n", type->abbrev->tag); - return ctx->symt_cache[sc_unknown]; + return ctx->module_ctx->symt_cache[sc_unknown]; } } return type->symt; @@ -1339,6 +1339,7 @@ static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, 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; switch (child->abbrev->tag) { case DW_TAG_subrange_type: @@ -2121,7 +2122,7 @@ static void dwarf2_parse_namespace(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- di->symt = ctx->symt_cache[sc_void]; + di->symt = ctx->module_ctx->symt_cache[sc_void];
children = dwarf2_get_di_children(ctx, di); if (children) for (i = 0; i < vector_length(children); i++) @@ -2491,9 +2492,6 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_ pool_init(&ctx.pool, 65536); ctx.section = section_debug; ctx.ref_offset = comp_unit_start - module_ctx->sections[section_debug].address; - memset(ctx.symt_cache, 0, sizeof(ctx.symt_cache)); - ctx.symt_cache[sc_void] = &symt_new_basic(module_ctx->module, btVoid, "void", 0)->symt; - ctx.symt_cache[sc_unknown] = &symt_new_basic(module_ctx->module, btNoType, "# unknown", 0)->symt; ctx.cpp_name = NULL; ctx.module_ctx = module_ctx;
@@ -3666,6 +3664,9 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, 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;
while (mod_ctx.data < mod_ctx.end_data) {
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 97 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 39 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 4bb5bb23ac6..e64fcbb822e 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -180,8 +180,16 @@ typedef struct dwarf2_parse_module_context_s struct module* module; const struct elf_thunk_area*thunks; struct symt* symt_cache[sc_num]; /* void, unknown */ + struct vector unit_contexts; } dwarf2_parse_module_context_t;
+enum unit_status +{ + UNIT_ERROR, + UNIT_NOTLOADED, + UNIT_LOADED, +}; + /* this is the context used for parsing a compilation unit * inside an ELF/PE section (likely .debug_info) */ @@ -196,6 +204,7 @@ typedef struct dwarf2_parse_context_s ULONG_PTR ref_offset; char* cpp_name; dwarf2_cuhead_t head; + enum unit_status status; } dwarf2_parse_context_t;
/* stored in the dbghelp's module internal structure for later reuse */ @@ -2440,10 +2449,9 @@ unsigned dwarf2_cache_cuhead(struct dwarf2_module_info_s* module, struct symt_co return TRUE; }
-static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_ctx, +static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx, dwarf2_traverse_context_t* mod_ctx) { - dwarf2_parse_context_t ctx; dwarf2_traverse_context_t abbrev_ctx; dwarf2_debug_info_t* di; dwarf2_traverse_context_t cu_ctx; @@ -2454,22 +2462,23 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_ /* FIXME this is a temporary configuration while adding support for dwarf3&4 bits */ static LONG max_supported_dwarf_version = 0;
- cu_length = dwarf2_parse_3264(mod_ctx, &ctx.head.offset_size); + cu_length = dwarf2_parse_3264(mod_ctx, &ctx->head.offset_size);
cu_ctx.data = mod_ctx->data; cu_ctx.end_data = mod_ctx->data + cu_length; mod_ctx->data += cu_length; - ctx.head.version = dwarf2_parse_u2(&cu_ctx); - cu_abbrev_offset = dwarf2_parse_offset(&cu_ctx, ctx.head.offset_size); - ctx.head.word_size = dwarf2_parse_byte(&cu_ctx); + ctx->head.version = dwarf2_parse_u2(&cu_ctx); + cu_abbrev_offset = dwarf2_parse_offset(&cu_ctx, ctx->head.offset_size); + ctx->head.word_size = dwarf2_parse_byte(&cu_ctx); + ctx->status = UNIT_ERROR;
TRACE("Compilation Unit Header found at 0x%x:\n", - (int)(comp_unit_start - module_ctx->sections[section_debug].address)); + (int)(comp_unit_start - ctx->module_ctx->sections[section_debug].address)); TRACE("- length: %lu\n", cu_length); - TRACE("- version: %u\n", ctx.head.version); + TRACE("- version: %u\n", ctx->head.version); TRACE("- abbrev_offset: %lu\n", cu_abbrev_offset); - TRACE("- word_size: %u\n", ctx.head.word_size); - TRACE("- offset_size: %u\n", ctx.head.offset_size); + TRACE("- word_size: %u\n", ctx->head.word_size); + TRACE("- offset_size: %u\n", ctx->head.offset_size);
if (max_supported_dwarf_version == 0) { @@ -2478,30 +2487,30 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_ max_supported_dwarf_version = (v >= 2 && v <= 4) ? v : 2; }
- if (ctx.head.version < 2 || ctx.head.version > max_supported_dwarf_version) + if (ctx->head.version < 2 || ctx->head.version > max_supported_dwarf_version) { if (max_supported_dwarf_version > 2) WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2 up to %u.\n", - ctx.head.version, max_supported_dwarf_version); + ctx->head.version, max_supported_dwarf_version); else WARN("%u DWARF version unsupported. Wine dbghelp only support DWARF 2.\n", - ctx.head.version); + ctx->head.version); return FALSE; }
- pool_init(&ctx.pool, 65536); - ctx.section = section_debug; - ctx.ref_offset = comp_unit_start - module_ctx->sections[section_debug].address; - ctx.cpp_name = NULL; - ctx.module_ctx = module_ctx; + pool_init(&ctx->pool, 65536); + ctx->section = section_debug; + ctx->ref_offset = comp_unit_start - ctx->module_ctx->sections[section_debug].address; + ctx->cpp_name = NULL; + ctx->status = UNIT_NOTLOADED;
- abbrev_ctx.data = module_ctx->sections[section_abbrev].address + cu_abbrev_offset; - abbrev_ctx.end_data = module_ctx->sections[section_abbrev].address + module_ctx->sections[section_abbrev].size; - dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool); + abbrev_ctx.data = ctx->module_ctx->sections[section_abbrev].address + cu_abbrev_offset; + abbrev_ctx.end_data = ctx->module_ctx->sections[section_abbrev].address + ctx->module_ctx->sections[section_abbrev].size; + dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx->abbrev_table, &ctx->pool);
- sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128); + sparse_array_init(&ctx->debug_info_table, sizeof(dwarf2_debug_info_t), 128);
- if (dwarf2_read_one_debug_info(&ctx, &cu_ctx, NULL, &di)) + if (dwarf2_read_one_debug_info(ctx, &cu_ctx, NULL, &di)) { if (di->abbrev->tag == DW_TAG_compile_unit) { @@ -2512,37 +2521,35 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_module_context_t* module_ struct attribute stmt_list, low_pc; struct attribute comp_dir;
- if (!dwarf2_find_attribute(&ctx, di, DW_AT_name, &name)) + if (!dwarf2_find_attribute(ctx, 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(ctx, 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(ctx, di, DW_AT_low_pc, &low_pc)) low_pc.u.uvalue = 0; - - ctx.compiland = symt_new_compiland(module_ctx->module, module_ctx->load_offset + low_pc.u.uvalue, - source_new(module_ctx->module, comp_dir.u.string, name.u.string)); - dwarf2_cache_cuhead(module_ctx->module->format_info[DFI_DWARF]->u.dwarf2_info, ctx.compiland, &ctx.head); - - di->symt = &ctx.compiland->symt; - children = dwarf2_get_di_children(&ctx, di); + 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)); + dwarf2_cache_cuhead(ctx->module_ctx->module->format_info[DFI_DWARF]->u.dwarf2_info, ctx->compiland, &ctx->head); + di->symt = &ctx->compiland->symt; + children = dwarf2_get_di_children(ctx, 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(ctx, child); } - if (dwarf2_find_attribute(&ctx, di, DW_AT_stmt_list, &stmt_list)) + if (dwarf2_find_attribute(ctx, di, DW_AT_stmt_list, &stmt_list)) { - if (dwarf2_parse_line_numbers(&ctx, comp_dir.u.string, stmt_list.u.uvalue)) - module_ctx->module->module.LineNumbers = TRUE; + if (dwarf2_parse_line_numbers(ctx, comp_dir.u.string, stmt_list.u.uvalue)) + ctx->module_ctx->module->module.LineNumbers = TRUE; } + ctx->status = UNIT_LOADED; ret = TRUE; } else FIXME("Should have a compilation unit here\n"); } - pool_destroy(&ctx.pool); return ret; }
@@ -3605,6 +3612,7 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, BOOL ret = TRUE; struct module_format* dwarf2_modfmt; dwarf2_parse_module_context_t module_ctx; + unsigned i;
if (!dwarf2_init_section(&eh_frame, fmap, ".eh_frame", NULL, &eh_frame_sect)) /* lld produces .eh_fram to avoid generating a long name */ @@ -3667,10 +3675,14 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR 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);
while (mod_ctx.data < mod_ctx.end_data) { - dwarf2_parse_compilation_unit(&module_ctx, &mod_ctx); + 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(unit_ctx, &mod_ctx); } dwarf2_modfmt->module->module.SymType = SymDia; dwarf2_modfmt->module->module.CVSig = 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24); @@ -3680,6 +3692,13 @@ 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); + } + leave: dwarf2_fini_section(§ion[section_debug]); dwarf2_fini_section(§ion[section_abbrev]);
Now parsing a compilation unit in two phases: - first phase just parse the header and do elementary checks - second phase, actually load all DIEs in CU
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index e64fcbb822e..855168a6085 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -205,6 +205,7 @@ typedef struct dwarf2_parse_context_s char* cpp_name; dwarf2_cuhead_t head; enum unit_status status; + dwarf2_traverse_context_t traverse_DIE; } dwarf2_parse_context_t;
/* stored in the dbghelp's module internal structure for later reuse */ @@ -2449,27 +2450,24 @@ unsigned dwarf2_cache_cuhead(struct dwarf2_module_info_s* module, struct symt_co return TRUE; }
-static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx, - dwarf2_traverse_context_t* mod_ctx) +static BOOL dwarf2_parse_compilation_unit_head(dwarf2_parse_context_t* ctx, + dwarf2_traverse_context_t* mod_ctx) { dwarf2_traverse_context_t abbrev_ctx; - dwarf2_debug_info_t* di; - dwarf2_traverse_context_t cu_ctx; const unsigned char* comp_unit_start = mod_ctx->data; ULONG_PTR cu_length; ULONG_PTR cu_abbrev_offset; - BOOL ret = FALSE; /* FIXME this is a temporary configuration while adding support for dwarf3&4 bits */ static LONG max_supported_dwarf_version = 0;
cu_length = dwarf2_parse_3264(mod_ctx, &ctx->head.offset_size);
- cu_ctx.data = mod_ctx->data; - cu_ctx.end_data = mod_ctx->data + cu_length; + ctx->traverse_DIE.data = mod_ctx->data; + ctx->traverse_DIE.end_data = mod_ctx->data + cu_length; mod_ctx->data += cu_length; - ctx->head.version = dwarf2_parse_u2(&cu_ctx); - cu_abbrev_offset = dwarf2_parse_offset(&cu_ctx, ctx->head.offset_size); - ctx->head.word_size = dwarf2_parse_byte(&cu_ctx); + ctx->head.version = dwarf2_parse_u2(&ctx->traverse_DIE); + cu_abbrev_offset = dwarf2_parse_offset(&ctx->traverse_DIE, ctx->head.offset_size); + ctx->head.word_size = dwarf2_parse_byte(&ctx->traverse_DIE); ctx->status = UNIT_ERROR;
TRACE("Compilation Unit Header found at 0x%x:\n", @@ -2509,6 +2507,16 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx, dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx->abbrev_table, &ctx->pool);
sparse_array_init(&ctx->debug_info_table, sizeof(dwarf2_debug_info_t), 128); + return TRUE; +} + +static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx) +{ + dwarf2_debug_info_t* di; + dwarf2_traverse_context_t cu_ctx = ctx->traverse_DIE; + BOOL ret = FALSE; + + if (ctx->status == UNIT_ERROR) return FALSE;
if (dwarf2_read_one_debug_info(ctx, &cu_ctx, NULL, &di)) { @@ -3642,9 +3650,6 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset,
TRACE("Loading Dwarf2 information for %s\n", debugstr_w(module->modulename));
- mod_ctx.data = section[section_debug].address; - mod_ctx.end_data = mod_ctx.data + section[section_debug].size; - dwarf2_modfmt = HeapAlloc(GetProcessHeap(), 0, sizeof(*dwarf2_modfmt) + sizeof(*dwarf2_modfmt->u.dwarf2_info)); if (!dwarf2_modfmt) @@ -3677,13 +3682,21 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, 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);
+ /* 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(unit_ctx, &mod_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)); + dwarf2_modfmt->module->module.SymType = SymDia; dwarf2_modfmt->module->module.CVSig = 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24); /* FIXME: we could have a finer grain here */
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 855168a6085..a2ee234f79f 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -188,6 +188,8 @@ enum unit_status UNIT_ERROR, UNIT_NOTLOADED, UNIT_LOADED, + UNIT_LOADED_FAIL, + UNIT_BEINGLOADED, };
/* this is the context used for parsing a compilation unit @@ -224,6 +226,8 @@ struct dwarf2_module_info_s
/* forward declarations */ static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, 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);
static unsigned char dwarf2_get_byte(const unsigned char* ptr) { @@ -2450,6 +2454,22 @@ unsigned dwarf2_cache_cuhead(struct dwarf2_module_info_s* module, struct symt_co return TRUE; }
+static inline dwarf2_parse_context_t* dwarf2_locate_cu(dwarf2_parse_module_context_t* module_ctx, ULONG_PTR ref) +{ + unsigned i; + dwarf2_parse_context_t* ctx; + const BYTE* where; + for (i = 0; i < module_ctx->unit_contexts.num_elts; ++i) + { + ctx = vector_at(&module_ctx->unit_contexts, i); + where = module_ctx->sections[ctx->section].address + ref; + if (where >= ctx->traverse_DIE.data && where < ctx->traverse_DIE.end_data) + return ctx; + } + FIXME("Couldn't find ref 0x%lx inside sect\n", ref); + return NULL; +} + static BOOL dwarf2_parse_compilation_unit_head(dwarf2_parse_context_t* ctx, dwarf2_traverse_context_t* mod_ctx) { @@ -2516,8 +2536,19 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx) dwarf2_traverse_context_t cu_ctx = ctx->traverse_DIE; BOOL ret = FALSE;
- if (ctx->status == UNIT_ERROR) return FALSE; + switch (ctx->status) + { + case UNIT_ERROR: return FALSE; + case UNIT_BEINGLOADED: + FIXME("Circular deps on CU\n"); + /* fall through */ + case UNIT_LOADED: + case UNIT_LOADED_FAIL: + return TRUE; + case UNIT_NOTLOADED: break; + }
+ ctx->status = UNIT_BEINGLOADED; if (dwarf2_read_one_debug_info(ctx, &cu_ctx, NULL, &di)) { if (di->abbrev->tag == DW_TAG_compile_unit) @@ -2558,6 +2589,7 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx) } else FIXME("Should have a compilation unit here\n"); } + if (ctx->status == UNIT_BEINGLOADED) ctx->status = UNIT_LOADED_FAIL; return ret; }
(using the new cross-CU DIE mechanisms)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index a2ee234f79f..eb0cfaf2f50 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1044,8 +1044,21 @@ static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx, return ctx->module_ctx->symt_cache[sc_void]; if (!(type = sparse_array_find(&ctx->debug_info_table, attr.u.uvalue))) { - FIXME("Unable to find back reference to type %lx\n", attr.u.uvalue); - return ctx->module_ctx->symt_cache[sc_unknown]; + if (attr.form == DW_FORM_ref_addr) + { + dwarf2_parse_context_t* ref_ctx = dwarf2_locate_cu(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_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 ctx->module_ctx->symt_cache[sc_unknown]; + } } if (type == di) { @@ -2454,7 +2467,7 @@ unsigned dwarf2_cache_cuhead(struct dwarf2_module_info_s* module, struct symt_co return TRUE; }
-static inline dwarf2_parse_context_t* dwarf2_locate_cu(dwarf2_parse_module_context_t* module_ctx, ULONG_PTR ref) +static dwarf2_parse_context_t* dwarf2_locate_cu(dwarf2_parse_module_context_t* module_ctx, ULONG_PTR ref) { unsigned i; dwarf2_parse_context_t* ctx;
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index eb0cfaf2f50..e1702964efa 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1244,6 +1244,12 @@ static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx, if (dwarf2_find_attribute(ctx, 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) + { + 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); + return FALSE; + } WARN("setting cursor for %s to next sibling <0x%lx>\n", dwarf2_debug_traverse_ctx(traverse), sibling.u.uvalue); traverse->data = ctx->module_ctx->sections[ctx->section].address + sibling.u.uvalue;
Dwarf4 (and GNU extensions) support following debug info in a) different CU b) different ELF/PE files So add a field from debug_info into the parent context unit
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 90 +++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index e1702964efa..a9ff9ff2354 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -143,6 +143,7 @@ typedef struct dwarf2_debug_info_s const unsigned char** data; struct vector children; struct dwarf2_debug_info_s* parent; + struct dwarf2_parse_context_s* unit_ctx; } dwarf2_debug_info_t;
typedef struct dwarf2_section_s @@ -1033,20 +1034,19 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx, return TRUE; }
-static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx, - const dwarf2_debug_info_t* di) +static struct symt* dwarf2_lookup_type(const dwarf2_debug_info_t* di) { struct attribute attr; dwarf2_debug_info_t* type;
- if (!dwarf2_find_attribute(ctx, di, DW_AT_type, &attr)) + if (!dwarf2_find_attribute(di->unit_ctx, di, DW_AT_type, &attr)) /* this is only valid if current language of CU is C or C++ */ - return ctx->module_ctx->symt_cache[sc_void]; - if (!(type = sparse_array_find(&ctx->debug_info_table, attr.u.uvalue))) + 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(ctx->module_ctx, attr.u.uvalue); + 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)) { @@ -1057,22 +1057,22 @@ static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx, if (!type) { FIXME("Unable to find back reference to type 0x%lx (form=0x%lx)\n", attr.u.uvalue, attr.form); - return ctx->module_ctx->symt_cache[sc_unknown]; + return di->unit_ctx->module_ctx->symt_cache[sc_unknown]; } } if (type == di) { FIXME("Reference to itself\n"); - return ctx->module_ctx->symt_cache[sc_unknown]; + return di->unit_ctx->module_ctx->symt_cache[sc_unknown]; } if (!type->symt) { /* load the debug info entity */ - dwarf2_load_one_entry(ctx, type); + dwarf2_load_one_entry(di->unit_ctx, type); if (!type->symt) { FIXME("Unable to load forward reference for tag %lx\n", type->abbrev->tag); - return ctx->module_ctx->symt_cache[sc_unknown]; + return di->unit_ctx->module_ctx->symt_cache[sc_unknown]; } } return type->symt; @@ -1218,6 +1218,7 @@ static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx, di->abbrev = abbrev; di->symt = NULL; di->parent = parent_di; + di->unit_ctx = ctx;
if (abbrev->num_attr) { @@ -1258,8 +1259,7 @@ static BOOL dwarf2_read_one_debug_info(dwarf2_parse_context_t* ctx, return TRUE; }
-static struct vector* dwarf2_get_di_children(dwarf2_parse_context_t* ctx, - dwarf2_debug_info_t* di) +static struct vector* dwarf2_get_di_children(dwarf2_debug_info_t* di) { struct attribute spec;
@@ -1267,8 +1267,8 @@ static struct vector* dwarf2_get_di_children(dwarf2_parse_context_t* ctx, { if (di->abbrev->have_child) return &di->children; - if (!dwarf2_find_attribute(ctx, di, DW_AT_specification, &spec)) break; - if (!(di = sparse_array_find(&ctx->debug_info_table, spec.u.uvalue))) + if (!dwarf2_find_attribute(di->unit_ctx, 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"); } return NULL; @@ -1305,7 +1305,7 @@ static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx, } di->symt = &symt_new_basic(ctx->module_ctx->module, bt, name.u.string, size.u.uvalue)->symt;
- if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); return di->symt; }
@@ -1320,11 +1320,11 @@ 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; - ref_type = dwarf2_lookup_type(ctx, di); + 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; - if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); return di->symt; }
@@ -1339,9 +1339,9 @@ 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 *); - ref_type = dwarf2_lookup_type(ctx, di); + 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(ctx, di)) FIXME("Unsupported children\n"); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); return di->symt; }
@@ -1359,9 +1359,9 @@ static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- ref_type = dwarf2_lookup_type(ctx, di); + ref_type = dwarf2_lookup_type(di);
- if (!(children = dwarf2_get_di_children(ctx, di))) + if (!(children = dwarf2_get_di_children(di))) { /* fake an array with unknown size */ /* FIXME: int4 even on 64bit machines??? */ @@ -1376,7 +1376,7 @@ static struct symt* dwarf2_parse_array_type(dwarf2_parse_context_t* ctx, switch (child->abbrev->tag) { case DW_TAG_subrange_type: - idx_type = dwarf2_lookup_type(ctx, child); + idx_type = dwarf2_lookup_type(child); if (!dwarf2_find_attribute(ctx, child, DW_AT_lower_bound, &min)) min.u.uvalue = 0; if (dwarf2_find_attribute(ctx, child, DW_AT_upper_bound, &max)) @@ -1403,8 +1403,8 @@ static struct symt* dwarf2_parse_const_type(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- ref_type = dwarf2_lookup_type(ctx, di); - if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); + ref_type = dwarf2_lookup_type(di); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); di->symt = ref_type;
return ref_type; @@ -1419,8 +1419,8 @@ static struct symt* dwarf2_parse_volatile_type(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- ref_type = dwarf2_lookup_type(ctx, di); - if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); + ref_type = dwarf2_lookup_type(di); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); di->symt = ref_type;
return ref_type; @@ -1444,7 +1444,7 @@ static struct symt* dwarf2_parse_unspecified_type(dwarf2_parse_context_t* ctx, basic = symt_new_basic(ctx->module_ctx->module, btVoid, name.u.string, size.u.uvalue); di->symt = &basic->symt;
- if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); return di->symt; }
@@ -1457,11 +1457,11 @@ static struct symt* dwarf2_parse_reference_type(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- ref_type = dwarf2_lookup_type(ctx, di); + 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;
- if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n");
return di->symt; } @@ -1481,7 +1481,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; - elt_type = dwarf2_lookup_type(ctx, di); + elt_type = dwarf2_lookup_type(di); if (dwarf2_compute_location_attr(ctx, di, DW_AT_data_member_location, &loc, NULL)) { if (loc.kind != loc_absolute) @@ -1516,7 +1516,7 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx, loc.offset, bit_offset.u.uvalue, bit_size.u.uvalue);
- if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); }
static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, @@ -1544,7 +1544,7 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, di->symt = &symt_new_udt(ctx->module_ctx->module, dwarf2_get_cpp_name(ctx, di, name.u.string), size.u.uvalue, udt)->symt;
- children = dwarf2_get_di_children(ctx, di); + 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); @@ -1606,7 +1606,7 @@ static void dwarf2_parse_enumerator(dwarf2_parse_context_t* ctx, if (!dwarf2_find_attribute(ctx, 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(ctx, di)) FIXME("Unsupported children\n"); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); }
static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, @@ -1636,7 +1636,7 @@ static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx,
di->symt = &symt_new_enum(ctx->module_ctx->module, name.u.string, &basetype->symt)->symt;
- children = dwarf2_get_di_children(ctx, di); + children = dwarf2_get_di_children(di); /* FIXME: should we use the sibling stuff ?? */ if (children) for (i = 0; i < vector_length(children); i++) { @@ -1682,7 +1682,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, TRACE("%s, for %s\n", dwarf2_debug_ctx(subpgm->ctx), dwarf2_debug_di(di));
is_pmt = !block && di->abbrev->tag == DW_TAG_formal_parameter; - param_type = dwarf2_lookup_type(subpgm->ctx, di); + param_type = dwarf2_lookup_type(di);
if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_name, &name)) { /* cannot do much without the name, the functions below won't like it. */ @@ -1809,7 +1809,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, (struct symt_function_signature*)subpgm->func->type, param_type);
- if (dwarf2_get_di_children(subpgm->ctx, di)) FIXME("Unsupported children\n"); + if (dwarf2_get_di_children(di)) FIXME("Unsupported children\n"); }
static void dwarf2_parse_subprogram_label(dwarf2_subprogram_t* subpgm, @@ -1860,7 +1860,7 @@ static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm, subpgm->ctx->module_ctx->load_offset + low_pc - subpgm->func->address, high_pc - low_pc);
- children = dwarf2_get_di_children(subpgm->ctx, di); + 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); @@ -1914,7 +1914,7 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, subpgm->ctx->module_ctx->load_offset + low_pc - subpgm->func->address, high_pc - low_pc);
- children = dwarf2_get_di_children(subpgm->ctx, di); + 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); @@ -2025,7 +2025,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, */ if (elf_is_in_thunk_area(ctx->module_ctx->load_offset + low_pc, ctx->module_ctx->thunks) >= 0) return NULL; - ret_type = dwarf2_lookup_type(ctx, di); + 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); @@ -2045,7 +2045,7 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, } subpgm.non_computed_variable = FALSE;
- children = dwarf2_get_di_children(ctx, di); + 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); @@ -2119,12 +2119,12 @@ static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx,
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di));
- ret_type = dwarf2_lookup_type(ctx, di); + 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);
- children = dwarf2_get_di_children(ctx, di); + 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); @@ -2133,7 +2133,7 @@ static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx, { case DW_TAG_formal_parameter: symt_add_function_signature_parameter(ctx->module_ctx->module, sig_type, - dwarf2_lookup_type(ctx, child)); + dwarf2_lookup_type(child)); break; case DW_TAG_unspecified_parameters: WARN("Unsupported unspecified parameters\n"); @@ -2157,7 +2157,7 @@ static void dwarf2_parse_namespace(dwarf2_parse_context_t* ctx,
di->symt = ctx->module_ctx->symt_cache[sc_void];
- children = dwarf2_get_di_children(ctx, di); + 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); @@ -2592,7 +2592,7 @@ static BOOL dwarf2_parse_compilation_unit(dwarf2_parse_context_t* ctx) source_new(ctx->module_ctx->module, comp_dir.u.string, name.u.string)); dwarf2_cache_cuhead(ctx->module_ctx->module->format_info[DFI_DWARF]->u.dwarf2_info, ctx->compiland, &ctx->head); di->symt = &ctx->compiland->symt; - children = dwarf2_get_di_children(ctx, di); + 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);
In details: - dbghelp: add a new hidden report in IMAGEHLP_MODULE(W)64 to detail which dwarf version(s) is (are) used for a module - program/winedbg: display this information in 'info share'
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 10 +++++++++- programs/winedbg/info.c | 13 ++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index a9ff9ff2354..90addb9a6b7 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -182,6 +182,7 @@ 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; + DWORD cu_versions; } dwarf2_parse_module_context_t;
enum unit_status @@ -2517,6 +2518,8 @@ static BOOL dwarf2_parse_compilation_unit_head(dwarf2_parse_context_t* ctx, TRACE("- word_size: %u\n", ctx->head.word_size); TRACE("- offset_size: %u\n", ctx->head.offset_size);
+ if (ctx->head.version >= 2) + ctx->module_ctx->cu_versions |= 1 << (ctx->head.version - 2); if (max_supported_dwarf_version == 0) { char* env = getenv("DBGHELP_DWARF_VERSION"); @@ -3732,6 +3735,7 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, 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; @@ -3749,7 +3753,11 @@ BOOL dwarf2_parse(struct module* module, ULONG_PTR load_offset, dwarf2_parse_compilation_unit((dwarf2_parse_context_t*)vector_at(&module_ctx.unit_contexts, i));
dwarf2_modfmt->module->module.SymType = SymDia; - dwarf2_modfmt->module->module.CVSig = 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24); + /* hide dwarf versions in CVSig + * bits 24-31 will be set according to found dwarf version + * different CU can have different dwarf version, so use a bit per version (version 2 => b24) + */ + dwarf2_modfmt->module->module.CVSig = 'D' | ('W' << 8) | ('F' << 16) | ((module_ctx.cu_versions & 0xFF) << 24); /* FIXME: we could have a finer grain here */ dwarf2_modfmt->module->module.GlobalSymbols = TRUE; dwarf2_modfmt->module->module.TypeInfo = TRUE; diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c index a6335092d84..36da71c4713 100644 --- a/programs/winedbg/info.c +++ b/programs/winedbg/info.c @@ -137,10 +137,21 @@ static const char* get_symtype_str(const IMAGEHLP_MODULE64* mi) case 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24): return "Stabs"; case 'D' | ('W' << 8) | ('A' << 16) | ('R' << 24): + /* previous versions of dbghelp used to report this... */ return "Dwarf"; default: + if ((mi->CVSig & 0x00FFFFFF) == ('D' | ('W' << 8) | ('F' << 16))) + { + static char tmp[64]; + DWORD versbit = mi->CVSig >> 24; + strcpy(tmp, "Dwarf"); + if (versbit & 1) strcat(tmp, "-2"); + if (versbit & 2) strcat(tmp, "-3"); + if (versbit & 4) strcat(tmp, "-4"); + if (versbit & 8) strcat(tmp, "-5"); + return tmp; + } return "DIA"; - } } }