Dwarf3/4 adds a couple of structural modifications: - either 32bit or 64bit internal offsets - some attributes size have been changed across version - some section headers evolution (one more field in line section header) - GCC added some FORM extensions
This serie adds support for those, and some more code hardening.
This serie should finish covering the structural changes in dwarf3/4, and the loading of dwarf4 modules should (shriek) be possible, even it lots of new features of dwarf4 are not supported yet. Expect though lots of FIXME:s and potential non functional stuff.
When this serie is committed, I'd appreciate feeback of running debugging stuff with DBGHELP_DWARF_VERSION env variable set to 4.
As wine's modules are still compiled with dwarf2, and distros are moving to dwarf5, the loadable dwarf4 modules are a scarse resource ;-)
A+
---
Eric Pouech (10): dbghelp{dwarf}: don't recompute location when said location is complex dbghelp{dwarf}: properly parse 32 vs bit 64bit entities dbghelp{dwarf}: correctly handle attributes according to 32bit or 64bit format dbghelp{dwarf}: Added support for FORM_loc_offset, FORM_sec_offset dbghelp{dwarf}: Added support for FORM_exprloc dbghelp{dwarf}: handle errors in dwarf2_fill_attr by returning a boolean dbghelp{dwarf}: added definitions of some GNU extenstions for FORM:s. dbghelp{dwarf}: Validate that a string is in the section boundary before using it dbghelp{dwarf}: Detect auto reference between a dwarf's DIE and its type dbghelp: Properly parse line number header for DWARF4 debug info
dlls/dbghelp/dwarf.c | 148 +++++++++++++++++++++++++++++++++---------- dlls/dbghelp/dwarf.h | 5 ++ 2 files changed, 118 insertions(+), 35 deletions(-)
this was generating a global symbol instead of a local symbol
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 13f1c0e7d9c..476061a62a5 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -947,7 +947,6 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx, *ptr = xloc.u.block.size; memcpy(ptr + 1, xloc.u.block.ptr, xloc.u.block.size); loc->offset = (ULONG_PTR)ptr; - compute_location(ctx->module, &ctx->head, &lctx, loc, NULL, frame); } } return TRUE;
- store the offset_size in dwarf2_cuhead_t
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 64 +++++++++++++++++++++++++++++++++++++------------- dlls/dbghelp/dwarf.h | 1 + 2 files changed, 48 insertions(+), 17 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 476061a62a5..fce15299ebb 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -170,6 +170,7 @@ typedef struct dwarf2_cuhead_s { unsigned char word_size; /* size of a word on target machine */ unsigned char version; + unsigned char offset_size; /* size of offset inside DWARF */ } dwarf2_cuhead_t;
typedef struct dwarf2_parse_context_s @@ -362,6 +363,25 @@ static inline ULONG_PTR dwarf2_parse_addr_head(dwarf2_traverse_context_t* ctx, c return dwarf2_parse_addr(ctx, head->word_size); }
+static ULONG_PTR dwarf2_parse_offset(dwarf2_traverse_context_t* ctx, unsigned char offset_size) +{ + ULONG_PTR ret = dwarf2_get_addr(ctx->data, offset_size); + ctx->data += offset_size; + return ret; +} + +static ULONG_PTR dwarf2_parse_3264(dwarf2_traverse_context_t* ctx, unsigned char* ofsz) +{ + ULONG_PTR ret = dwarf2_parse_u4(ctx); + if (ret == 0xffffffff) + { + ret = dwarf2_parse_u8(ctx); + *ofsz = 8; + } + else *ofsz = 4; + return ret; +} + static const char* dwarf2_debug_traverse_ctx(const dwarf2_traverse_context_t* ctx) { return wine_dbg_sprintf("ctx(%p)", ctx->data); @@ -2159,6 +2179,7 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, unsigned insn_size, default_stmt; unsigned line_range, opcode_base; int line_base; + unsigned char offset_size; const unsigned char* opcode_len; struct vector dirs; struct vector files; @@ -2174,18 +2195,23 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, return FALSE; } traverse.data = sections[section_line].address + offset; - traverse.end_data = traverse.data + 4; + traverse.end_data = sections[section_line].address + sections[section_line].size;
- length = dwarf2_parse_u4(&traverse); - traverse.end_data = sections[section_line].address + offset + length; + length = dwarf2_parse_3264(&traverse, &offset_size); + if (offset_size != ctx->head.offset_size) + { + WARN("Mismatch in 32/64 bit format\n"); + return FALSE; + } + traverse.end_data = traverse.data + length;
- if (offset + 4 + length > sections[section_line].size) + if (traverse.end_data > sections[section_line].address + sections[section_line].size) { WARN("out of bounds header\n"); return FALSE; } dwarf2_parse_u2(&traverse); /* version */ - dwarf2_parse_u4(&traverse); /* header_len */ + dwarf2_parse_offset(&traverse, offset_size); /* header_len */ insn_size = dwarf2_parse_byte(&traverse); default_stmt = dwarf2_parse_byte(&traverse); line_base = (signed char)dwarf2_parse_byte(&traverse); @@ -2375,12 +2401,13 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, /* FIXME this is a temporary configuration while adding support for dwarf3&4 bits */ static LONG max_supported_dwarf_version = 0;
- cu_length = dwarf2_parse_u4(mod_ctx); + 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_u4(&cu_ctx); + cu_abbrev_offset = dwarf2_parse_offset(&cu_ctx, ctx.head.offset_size); ctx.head.word_size = dwarf2_parse_byte(&cu_ctx);
TRACE("Compilation Unit Header found at 0x%x:\n", @@ -2389,6 +2416,7 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, 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);
if (max_supported_dwarf_version == 0) { @@ -2727,13 +2755,13 @@ static BOOL dwarf2_get_cie(ULONG_PTR addr, struct module* module, DWORD_PTR delt const unsigned char* ptr_blk; const unsigned char* cie_ptr; const unsigned char* last_cie_ptr = (const unsigned char*)~0; - unsigned len, id; + ULONG_PTR len, id; ULONG_PTR start, range; - unsigned cie_id; + ULONG_PTR cie_id; const BYTE* start_data = fde_ctx->data; unsigned char word_size = module->format_info[DFI_DWARF]->u.dwarf2_info->word_size; + unsigned char offset_size;
- cie_id = in_eh_frame ? 0 : DW_CIE_ID; /* skip 0-padding at beginning of section (alignment) */ while (fde_ctx->data + 2 * 4 < fde_ctx->end_data) { @@ -2745,14 +2773,15 @@ static BOOL dwarf2_get_cie(ULONG_PTR addr, struct module* module, DWORD_PTR delt } for (; fde_ctx->data + 2 * 4 < fde_ctx->end_data; fde_ctx->data = ptr_blk) { + const unsigned char* st = fde_ctx->data; /* find the FDE for address addr (skip CIE) */ - len = dwarf2_parse_u4(fde_ctx); - if (len == 0xffffffff) FIXME("Unsupported yet 64-bit CIEs\n"); + len = dwarf2_parse_3264(fde_ctx, &offset_size); + cie_id = in_eh_frame ? 0 : (offset_size == 4 ? DW_CIE_ID : DW64_CIE_ID); ptr_blk = fde_ctx->data + len; - id = dwarf2_parse_u4(fde_ctx); + id = dwarf2_parse_offset(fde_ctx, offset_size); if (id == cie_id) { - last_cie_ptr = fde_ctx->data - 8; + last_cie_ptr = st; /* we need some bits out of the CIE in order to parse all contents */ if (!parse_cie_details(fde_ctx, info, word_size)) return FALSE; cie_ctx->data = fde_ctx->data; @@ -2764,9 +2793,10 @@ static BOOL dwarf2_get_cie(ULONG_PTR addr, struct module* module, DWORD_PTR delt { last_cie_ptr = cie_ptr; cie_ctx->data = cie_ptr; - cie_ctx->end_data = cie_ptr + 4; - cie_ctx->end_data = cie_ptr + 4 + dwarf2_parse_u4(cie_ctx); - if (dwarf2_parse_u4(cie_ctx) != cie_id) + cie_ctx->end_data = cie_ptr + (offset_size == 4 ? 4 : 4 + 8); + cie_ctx->end_data += dwarf2_parse_3264(cie_ctx, &offset_size); + + if (dwarf2_parse_offset(cie_ctx, in_eh_frame ? word_size : offset_size) != cie_id) { FIXME("wrong CIE pointer at %x from FDE %x\n", (unsigned)(cie_ptr - start_data), diff --git a/dlls/dbghelp/dwarf.h b/dlls/dbghelp/dwarf.h index d4355d72e80..603c302d136 100644 --- a/dlls/dbghelp/dwarf.h +++ b/dlls/dbghelp/dwarf.h @@ -504,6 +504,7 @@ enum dwarf_calling_convention #define DW_LNE_hi_user 0xff
#define DW_CIE_ID ~(0x0U) +#define DW64_CIE_ID ~((ULONG64)0x0)
enum dwarf_call_frame_info {
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index fce15299ebb..431f00c121d 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -480,7 +480,7 @@ static void dwarf2_swallow_attribute(dwarf2_traverse_context_t* ctx, switch (abbrev_attr->form) { case DW_FORM_flag_present: step = 0; break; - case DW_FORM_ref_addr: + case DW_FORM_ref_addr: step = (head->version >= 3) ? head->offset_size : head->word_size; break; case DW_FORM_addr: step = head->word_size; break; case DW_FORM_flag: case DW_FORM_data1: @@ -488,8 +488,8 @@ static void dwarf2_swallow_attribute(dwarf2_traverse_context_t* ctx, case DW_FORM_data2: case DW_FORM_ref2: step = 2; break; case DW_FORM_data4: - case DW_FORM_ref4: - case DW_FORM_strp: step = 4; break; + case DW_FORM_ref4: step = 4; break; + case DW_FORM_strp: step = head->offset_size; break; case DW_FORM_data8: case DW_FORM_ref8: step = 8; break; case DW_FORM_sdata: @@ -516,6 +516,13 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, switch (attr->form) { case DW_FORM_ref_addr: + if (ctx->head.version >= 3) + attr->u.uvalue = dwarf2_get_addr(data, ctx->head.offset_size); + else + attr->u.uvalue = dwarf2_get_addr(data, ctx->head.word_size); + TRACE("addr<0x%lx>\n", attr->u.uvalue); + break; + case DW_FORM_addr: attr->u.uvalue = dwarf2_get_addr(data, ctx->head.word_size); TRACE("addr<0x%lx>\n", attr->u.uvalue); @@ -590,13 +597,11 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, break;
case DW_FORM_strp: - { - ULONG_PTR offset = dwarf2_get_u4(data); - attr->u.string = (const char*)ctx->sections[section_string].address + offset; - } - TRACE("strp<%s>\n", debugstr_a(attr->u.string)); - break; - + attr->u.string = (const char*)ctx->sections[section_string].address + + dwarf2_get_addr(data, ctx->head.offset_size); + TRACE("strp<%s>\n", debugstr_a(attr->u.string)); + break; + case DW_FORM_block: attr->u.block.size = dwarf2_get_leb128_as_unsigned(data, &attr->u.block.ptr); TRACE("block<%p,%u>\n", attr->u.block.ptr, attr->u.block.size);
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 431f00c121d..9581bb43bf5 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -489,7 +489,6 @@ static void dwarf2_swallow_attribute(dwarf2_traverse_context_t* ctx, case DW_FORM_ref2: step = 2; break; case DW_FORM_data4: case DW_FORM_ref4: step = 4; break; - case DW_FORM_strp: step = head->offset_size; break; case DW_FORM_data8: case DW_FORM_ref8: step = 8; break; case DW_FORM_sdata: @@ -500,6 +499,8 @@ static void dwarf2_swallow_attribute(dwarf2_traverse_context_t* ctx, case DW_FORM_block1: step = dwarf2_parse_byte(ctx); break; case DW_FORM_block2: step = dwarf2_parse_u2(ctx); break; case DW_FORM_block4: step = dwarf2_parse_u4(ctx); break; + case DW_FORM_sec_offset: + case DW_FORM_strp: step = head->offset_size; break; default: FIXME("Unhandled attribute form %lx\n", abbrev_attr->form); return; @@ -625,6 +626,11 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, TRACE("block<%p,%u>\n", attr->u.block.ptr, attr->u.block.size); break;
+ case DW_FORM_sec_offset: + attr->u.lluvalue = dwarf2_get_addr(data, ctx->head.offset_size); + TRACE("sec_offset<%s>\n", wine_dbgstr_longlong(attr->u.lluvalue)); + break; + default: FIXME("Unhandled attribute form %lx\n", abbrev_attr->form); break; @@ -935,11 +941,16 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx, loc->reg = 0; loc->offset = xloc.u.uvalue; return TRUE; - case DW_FORM_data4: case DW_FORM_data8: + case DW_FORM_data4: loc->kind = loc_dwarf2_location_list; loc->reg = Wine_DW_no_register; loc->offset = xloc.u.uvalue; return TRUE; + case DW_FORM_data8: case DW_FORM_sec_offset: + loc->kind = loc_dwarf2_location_list; + loc->reg = Wine_DW_no_register; + loc->offset = xloc.u.lluvalue; + return TRUE; case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: @@ -1662,6 +1673,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, break;
case DW_FORM_data8: + case DW_FORM_sec_offset: v.n1.n2.vt = VT_UI8; v.n1.n2.n3.llVal = value.u.lluvalue; break;
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 9581bb43bf5..0de8e2116ae 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -495,6 +495,7 @@ static void dwarf2_swallow_attribute(dwarf2_traverse_context_t* ctx, case DW_FORM_ref_udata: case DW_FORM_udata: step = dwarf2_leb128_length(ctx); break; case DW_FORM_string: step = strlen((const char*)ctx->data) + 1; break; + case DW_FORM_exprloc: case DW_FORM_block: step = dwarf2_leb128_as_unsigned(ctx); break; case DW_FORM_block1: step = dwarf2_parse_byte(ctx); break; case DW_FORM_block2: step = dwarf2_parse_u2(ctx); break; @@ -604,6 +605,7 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, break;
case DW_FORM_block: + case DW_FORM_exprloc: attr->u.block.size = dwarf2_get_leb128_as_unsigned(data, &attr->u.block.ptr); TRACE("block<%p,%u>\n", attr->u.block.ptr, attr->u.block.size); break; @@ -955,6 +957,7 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx, case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: + case DW_FORM_exprloc: break; default: FIXME("Unsupported yet form %lx\n", xloc.form); return FALSE; @@ -1696,6 +1699,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: + case DW_FORM_exprloc: v.n1.n2.vt = VT_I4; switch (value.u.block.size) {
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 0de8e2116ae..14c1861b85a 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -509,7 +509,7 @@ static void dwarf2_swallow_attribute(dwarf2_traverse_context_t* ctx, ctx->data += step; }
-static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, +static BOOL dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, const dwarf2_abbrev_entry_attr_t* abbrev_attr, const unsigned char* data, struct attribute* attr) @@ -637,6 +637,7 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, FIXME("Unhandled attribute form %lx\n", abbrev_attr->form); break; } + return TRUE; }
static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx, @@ -655,8 +656,7 @@ static BOOL dwarf2_find_attribute(const dwarf2_parse_context_t* ctx, { if (abbrev_attr->attribute == at) { - dwarf2_fill_attr(ctx, abbrev_attr, di->data[i], attr); - return TRUE; + return dwarf2_fill_attr(ctx, abbrev_attr, di->data[i], attr); } if ((abbrev_attr->attribute == DW_AT_abstract_origin || abbrev_attr->attribute == DW_AT_specification) && @@ -671,8 +671,8 @@ 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) break; - dwarf2_fill_attr(ctx, ref_abbrev_attr, di->data[refidx], attr); + if (!ref_abbrev_attr || !dwarf2_fill_attr(ctx, ref_abbrev_attr, di->data[refidx], attr)) + break; if (!(di = sparse_array_find(&ctx->debug_info_table, attr->u.uvalue))) FIXME("Should have found the debug info entry\n"); }
And returning failure when encoutering them, as they are not supported yet
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 10 ++++++++++ dlls/dbghelp/dwarf.h | 4 ++++ 2 files changed, 14 insertions(+)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 14c1861b85a..3988f2b3d44 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -501,6 +501,8 @@ static void dwarf2_swallow_attribute(dwarf2_traverse_context_t* ctx, case DW_FORM_block2: step = dwarf2_parse_u2(ctx); break; case DW_FORM_block4: step = dwarf2_parse_u4(ctx); break; case DW_FORM_sec_offset: + case DW_FORM_GNU_ref_alt: + case DW_FORM_GNU_strp_alt: case DW_FORM_strp: step = head->offset_size; break; default: FIXME("Unhandled attribute form %lx\n", abbrev_attr->form); @@ -633,6 +635,14 @@ static BOOL dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, TRACE("sec_offset<%s>\n", wine_dbgstr_longlong(attr->u.lluvalue)); break;
+ case DW_FORM_GNU_ref_alt: + FIXME("Unhandled FORM_GNU_ref_alt\n"); + 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; default: FIXME("Unhandled attribute form %lx\n", abbrev_attr->form); break; diff --git a/dlls/dbghelp/dwarf.h b/dlls/dbghelp/dwarf.h index 603c302d136..a50a7251876 100644 --- a/dlls/dbghelp/dwarf.h +++ b/dlls/dbghelp/dwarf.h @@ -266,6 +266,10 @@ typedef enum dwarf_form_e DW_FORM_exprloc = 0x18, DW_FORM_flag_present = 0x19, DW_FORM_ref_sig8 = 0x20, + + /** GNU extensions */ + DW_FORM_GNU_ref_alt = 0x1f20, + DW_FORM_GNU_strp_alt = 0x1f21, } dwarf_form_t;
/** type encoding */
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 3988f2b3d44..1483bd282cb 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -601,9 +601,19 @@ static BOOL dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, break;
case DW_FORM_strp: - attr->u.string = (const char*)ctx->sections[section_string].address + - dwarf2_get_addr(data, ctx->head.offset_size); - TRACE("strp<%s>\n", debugstr_a(attr->u.string)); + { + ULONG_PTR ofs = dwarf2_get_addr(data, ctx->head.offset_size); + if (ofs >= 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; + TRACE("strp<%s>\n", debugstr_a(attr->u.string)); + } + } break;
case DW_FORM_block:
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 1483bd282cb..1f9c50a161f 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1025,6 +1025,11 @@ static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx, FIXME("Unable to find back reference to type %lx\n", attr.u.uvalue); return ctx->symt_cache[sc_unknown]; } + if (type == di) + { + FIXME("Reference to itself\n"); + return ctx->symt_cache[sc_unknown]; + } if (!type->symt) { /* load the debug info entity */
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 1f9c50a161f..902a1d227b9 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2222,7 +2222,7 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, { dwarf2_traverse_context_t traverse; ULONG_PTR length; - unsigned insn_size, default_stmt; + unsigned insn_size, version, default_stmt; unsigned line_range, opcode_base; int line_base; unsigned char offset_size; @@ -2256,9 +2256,11 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, WARN("out of bounds header\n"); return FALSE; } - dwarf2_parse_u2(&traverse); /* version */ + version = dwarf2_parse_u2(&traverse); dwarf2_parse_offset(&traverse, offset_size); /* header_len */ insn_size = dwarf2_parse_byte(&traverse); + if (version >= 4) + dwarf2_parse_byte(&traverse); /* max_operations_per_instructions */ default_stmt = dwarf2_parse_byte(&traverse); line_base = (signed char)dwarf2_parse_byte(&traverse); line_range = dwarf2_parse_byte(&traverse);