The following serie is the first step toward adding Dwarf3/4 support into dbghelp. It mainly includes: - constant / definition updates - hardening of code regarding error conditions, improper input stream... - a couple of bug fixes
A+ ---
Eric Pouech (13): dbghelp: fix in dwarf2 subprogram handling dbghelp: dwarf support of DW_FORM_ref_udata dbghelp: more traces while parsing dwarf dbghelp: update dwarf definitions dbghelp: fix dwarf constants dbghelp: dwarf's internals adjustement dbghelp: Mostly get rid of symt_cache in dwarf debug information dbghelp: Added an unknown type in symt_cache for handling bad references to types dbghelp: check correctness of type (esp. in case of unknown ones) dbghelp: No longer call assert() on missing subprogram dwarf's information dbghelp: Harden inspection of Dwarf line number information dbghelp: Fix some erroneous string manipulation when said string is empty "" dbghelp: Properly handle errors when reading first DIE in compilation unit
dlls/dbghelp/dbghelp_private.h | 5 + dlls/dbghelp/dwarf.c | 191 ++++++++++++++------------------- dlls/dbghelp/dwarf.h | 44 +++++++- dlls/dbghelp/source.c | 2 +- 4 files changed, 129 insertions(+), 113 deletions(-)
Fix dwarf2_parse_subprogram_block when looking for inner information to use the child's debug_info (not the lexical_block one!)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 93baf10ba44..9d8d2756258 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1833,13 +1833,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, di); + dwarf2_parse_pointer_type(subpgm->ctx, child); break; case DW_TAG_subroutine_type: - dwarf2_parse_subroutine_type(subpgm->ctx, di); + dwarf2_parse_subroutine_type(subpgm->ctx, child); break; case DW_TAG_const_type: - dwarf2_parse_const_type(subpgm->ctx, di); + dwarf2_parse_const_type(subpgm->ctx, child); break; case DW_TAG_lexical_block: dwarf2_parse_subprogram_block(subpgm, block, child);
DW_FORM_ref_udata value is an offset from current unit (as the others DW_FORM_ref[1,2,3,4] are)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 9d8d2756258..b62e1a2cce8 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -544,7 +544,8 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, break;
case DW_FORM_ref_udata: - attr->u.uvalue = dwarf2_get_leb128_as_unsigned(data, NULL); + attr->u.uvalue = ctx->ref_offset + dwarf2_get_leb128_as_unsigned(data, NULL); + TRACE("ref_udata<0x%lx>\n", attr->u.uvalue); break;
case DW_FORM_udata:
Add a couple of more traces when querying an attribute's value
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 b62e1a2cce8..6d2c843fb94 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -550,6 +550,7 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx,
case DW_FORM_udata: attr->u.uvalue = dwarf2_get_leb128_as_unsigned(data, NULL); + TRACE("udata<0x%lx>\n", attr->u.uvalue); break;
case DW_FORM_string: @@ -567,21 +568,25 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx,
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); break;
case DW_FORM_block1: attr->u.block.size = dwarf2_get_byte(data); attr->u.block.ptr = data + 1; + TRACE("block<%p,%u>\n", attr->u.block.ptr, attr->u.block.size); break;
case DW_FORM_block2: attr->u.block.size = dwarf2_get_u2(data); attr->u.block.ptr = data + 2; + TRACE("block<%p,%u>\n", attr->u.block.ptr, attr->u.block.size); break;
case DW_FORM_block4: attr->u.block.size = dwarf2_get_u4(data); attr->u.block.ptr = data + 4; + TRACE("block<%p,%u>\n", attr->u.block.ptr, attr->u.block.size); break;
default:
Update/clarify dwarf definitions for 3/3f/4 standard versions
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.h | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/dwarf.h b/dlls/dbghelp/dwarf.h index 683d4e1e911..33ea9ef40ca 100644 --- a/dlls/dbghelp/dwarf.h +++ b/dlls/dbghelp/dwarf.h @@ -167,8 +167,7 @@ typedef enum dwarf_attribute_e DW_AT_allocated = 0x4e, DW_AT_associated = 0x4f, DW_AT_data_location = 0x50, - DW_AT_byte_stride = 0x51, - DW_AT_stride = 0x51, + DW_AT_byte_stride = 0x51, /* used to be DW_AT_stride in Dwarf3 (not final) */ DW_AT_entry_pc = 0x52, DW_AT_use_UTF8 = 0x53, DW_AT_extension = 0x54, @@ -178,7 +177,7 @@ typedef enum dwarf_attribute_e DW_AT_call_file = 0x58, DW_AT_call_line = 0x59, DW_AT_description = 0x5a, - /** Dwarf3 new values */ + /** Dwarf3 (final) new values */ DW_AT_binary_scale = 0x5b, DW_AT_decimal_scale = 0x5c, DW_AT_small = 0x5d, @@ -283,12 +282,15 @@ typedef enum dwarf_type_e DW_ATE_unsigned_char = 0x8, /* Dwarf3 new values */ DW_ATE_imaginary_float = 0x9, + /* Dwarf3 (final) new values */ DW_ATE_packed_decimal = 0xa, DW_ATE_numeric_string = 0xb, DW_ATE_edited = 0xc, DW_ATE_signed_fixed = 0xd, DW_ATE_unsigned_fixed = 0xe, DW_ATE_decimal_float = 0xf, + /* Dwarf4 new values */ + DW_ATE_UTF = 0x10, } dwarf_type_t;
typedef enum dwarf_operation_e @@ -443,6 +445,7 @@ typedef enum dwarf_operation_e DW_OP_call2 = 0x98, DW_OP_call4 = 0x99, DW_OP_call_ref = 0x9a, + /** Dwarf3 (final) new values */ DW_OP_form_tls_address = 0x9b, DW_OP_call_frame_cfa = 0x9c, DW_OP_bit_piece = 0x9d, @@ -497,6 +500,8 @@ enum dwarf_calling_convention #define DW_LNE_define_file 0x03 /* Dwarf4 new values */ #define DW_LNE_set_discriminator 0x04 +#define DW_LNE_lo_user 0x80 +#define DW_LNE_hi_user 0xff
#define DW_CIE_ID ~(0x0)
@@ -520,11 +525,13 @@ enum dwarf_call_frame_info DW_CFA_def_cfa = 0x0c, DW_CFA_def_cfa_register = 0x0d, DW_CFA_def_cfa_offset = 0x0e, + /* Dwarf3 new values */ DW_CFA_def_cfa_expression = 0x0f, DW_CFA_expression = 0x10, DW_CFA_offset_extended_sf = 0x11, DW_CFA_def_cfa_sf = 0x12, DW_CFA_def_cfa_offset_sf = 0x13, + /* Dwarf3 (final) new values */ DW_CFA_val_offset = 0x14, DW_CFA_val_offset_sf = 0x15, DW_CFA_val_expression = 0x16, @@ -554,3 +561,32 @@ enum dwarf_call_frame_info #define DW_INL_inlined 0x01 #define DW_INL_declared_not_inlined 0x02 #define DW_INL_declared_inlined 0x03 + +/* DWARF languages */ +enum +{ + DW_LANG_C89 = 0x0001, + DW_LANG_C = 0x0002, + DW_LANG_Ada83 = 0x0003, + DW_LANG_C_plus_plus = 0x0004, + DW_LANG_Cobol74 = 0x0005, + DW_LANG_Cobol85 = 0x0006, + DW_LANG_Fortran77 = 0x0007, + DW_LANG_Fortran90 = 0x0008, + DW_LANG_Pascal83 = 0x0009, + DW_LANG_Modula2 = 0x000a, + /* Dwarf3 additions */ + DW_LANG_Java = 0x000b, + DW_LANG_C99 = 0x000c, + DW_LANG_Ada95 = 0x000d, + DW_LANG_Fortran95 = 0x000e, + DW_LANG_PLI = 0x000f, + /* Dwarf3 (final) additions */ + DW_LANG_ObjC = 0x0010, + DW_LANG_ObjC_plus_plus = 0x0011, + DW_LANG_UPC = 0x0012, + DW_LANG_D = 0x0013, + + DW_LANG_lo_user = 0x8000, + DW_LANG_hi_user = 0xffff + };
The 32bit CIE_ID is an unsigned integer (will become important when handling 32 vs 64 bit values)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dbghelp/dwarf.h b/dlls/dbghelp/dwarf.h index 33ea9ef40ca..d4355d72e80 100644 --- a/dlls/dbghelp/dwarf.h +++ b/dlls/dbghelp/dwarf.h @@ -503,7 +503,7 @@ enum dwarf_calling_convention #define DW_LNE_lo_user 0x80 #define DW_LNE_hi_user 0xff
-#define DW_CIE_ID ~(0x0) +#define DW_CIE_ID ~(0x0U)
enum dwarf_call_frame_info {
Always return a type in lookup_type, even in case of errors (should be a no-op)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 6d2c843fb94..335c4a4e4ae 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -949,18 +949,21 @@ static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx, dwarf2_debug_info_t* type;
if (!dwarf2_find_attribute(ctx, di, DW_AT_type, &attr)) - return NULL; + return 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 NULL; + return ctx->symt_cache[sc_void]; } if (!type->symt) { /* load the debug info entity */ dwarf2_load_one_entry(ctx, type); if (!type->symt) + { FIXME("Unable to load forward reference for tag %lx\n", type->abbrev->tag); + return ctx->symt_cache[sc_void]; + } } return type->symt; } @@ -1240,11 +1243,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 (!(ref_type = dwarf2_lookup_type(ctx, di))) - { - ref_type = ctx->symt_cache[sc_void]; - assert(ref_type); - } + ref_type = dwarf2_lookup_type(ctx, di); di->symt = &symt_new_pointer(ctx->module, ref_type, size.u.uvalue)->symt; if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); return di->symt; @@ -1307,11 +1306,7 @@ 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));
- if (!(ref_type = dwarf2_lookup_type(ctx, di))) - { - ref_type = ctx->symt_cache[sc_void]; - assert(ref_type); - } + ref_type = dwarf2_lookup_type(ctx, di); if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); di->symt = ref_type;
@@ -1327,11 +1322,7 @@ 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));
- if (!(ref_type = dwarf2_lookup_type(ctx, di))) - { - ref_type = ctx->symt_cache[sc_void]; - assert(ref_type); - } + ref_type = dwarf2_lookup_type(ctx, di); if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); di->symt = ref_type;
@@ -1936,11 +1927,8 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, */ if (elf_is_in_thunk_area(ctx->load_offset + low_pc, ctx->thunks) >= 0) return NULL; - if (!(ret_type = dwarf2_lookup_type(ctx, di))) - { - ret_type = ctx->symt_cache[sc_void]; - assert(ret_type); - } + 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, @@ -2034,11 +2022,7 @@ 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));
- if (!(ret_type = dwarf2_lookup_type(ctx, di))) - { - ret_type = ctx->symt_cache[sc_void]; - assert(ret_type); - } + 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);
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 335c4a4e4ae..4503e42a227 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -164,10 +164,7 @@ typedef struct dwarf2_traverse_context_s
/* symt_cache indexes */ #define sc_void 0 -#define sc_int1 1 -#define sc_int2 2 -#define sc_int4 3 -#define sc_num 4 +#define sc_num 1
typedef struct dwarf2_parse_context_s { @@ -181,7 +178,7 @@ typedef struct dwarf2_parse_context_s struct sparse_array debug_info_table; ULONG_PTR load_offset; ULONG_PTR ref_offset; - struct symt* symt_cache[sc_num]; /* void, int1, int2, int4 */ + struct symt* symt_cache[sc_num]; /* void */ char* cpp_name; } dwarf2_parse_context_t;
@@ -1166,7 +1163,6 @@ static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx, struct attribute size; struct attribute encoding; enum BasicType bt; - int cache_idx = -1; if (di->symt) return di->symt;
TRACE("%s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_di(di)); @@ -1190,24 +1186,6 @@ static struct symt* dwarf2_parse_base_type(dwarf2_parse_context_t* ctx, default: bt = btNoType; break; } di->symt = &symt_new_basic(ctx->module, bt, name.u.string, size.u.uvalue)->symt; - switch (bt) - { - case btVoid: - assert(size.u.uvalue == 0); - cache_idx = sc_void; - break; - case btInt: - switch (size.u.uvalue) - { - case 1: cache_idx = sc_int1; break; - case 2: cache_idx = sc_int2; break; - case 4: cache_idx = sc_int4; break; - } - break; - default: break; - } - if (cache_idx != -1 && !ctx->symt_cache[cache_idx]) - ctx->symt_cache[cache_idx] = di->symt;
if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); return di->symt; @@ -1269,7 +1247,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 = ctx->symt_cache[sc_int4]; + idx_type = &symt_new_basic(ctx->module, btInt, "int", 4)->symt; min.u.uvalue = 0; cnt.u.uvalue = 0; } @@ -1347,9 +1325,6 @@ static struct symt* dwarf2_parse_unspecified_type(dwarf2_parse_context_t* ctx, basic = symt_new_basic(ctx->module, btVoid, name.u.string, size.u.uvalue); di->symt = &basic->symt;
- if (!ctx->symt_cache[sc_void]) - ctx->symt_cache[sc_void] = di->symt; - if (dwarf2_get_di_children(ctx, di)) FIXME("Unsupported children\n"); return di->symt; }
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 4503e42a227..1876f573cf9 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -163,8 +163,9 @@ typedef struct dwarf2_traverse_context_s } dwarf2_traverse_context_t;
/* symt_cache indexes */ -#define sc_void 0 -#define sc_num 1 +#define sc_void 0 +#define sc_unknown 1 +#define sc_num 2
typedef struct dwarf2_parse_context_s { @@ -178,7 +179,7 @@ typedef struct dwarf2_parse_context_s struct sparse_array debug_info_table; ULONG_PTR load_offset; ULONG_PTR ref_offset; - struct symt* symt_cache[sc_num]; /* void */ + struct symt* symt_cache[sc_num]; /* void, unknown */ char* cpp_name; } dwarf2_parse_context_t;
@@ -946,11 +947,12 @@ static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx, dwarf2_debug_info_t* type;
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]; 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_void]; + return ctx->symt_cache[sc_unknown]; } if (!type->symt) { @@ -959,7 +961,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_void]; + return ctx->symt_cache[sc_unknown]; } } return type->symt; @@ -2373,6 +2375,7 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, ctx.ref_offset = comp_unit_start - 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.cpp_name = NULL;
abbrev_ctx.data = sections[section_abbrev].address + cu_abbrev_offset;
Since with the unknown type entry, we can end up with types which don't match the expected symt->tag, we need to check before the conversions.
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dbghelp_private.h | 5 +++++ dlls/dbghelp/dwarf.c | 22 +++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 2b0365bc386..eb2b53e947a 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -151,6 +151,11 @@ struct symt_ht struct hash_table_elt hash_elt; /* if global symbol or type */ };
+static inline BOOL symt_check_tag(const struct symt* s, enum SymTagEnum tag) +{ + return s && s->tag == tag; +} + /* lexical tree */ struct symt_block { diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 1876f573cf9..ee73abdf378 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1439,7 +1439,8 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, break; case DW_TAG_member: /* FIXME: should I follow the sibling stuff ?? */ - dwarf2_parse_udt_member(ctx, child, (struct symt_udt*)di->symt); + if (symt_check_tag(di->symt, SymTagUDT)) + dwarf2_parse_udt_member(ctx, child, (struct symt_udt*)di->symt); break; case DW_TAG_enumeration_type: dwarf2_parse_enumeration_type(ctx, child); @@ -1527,7 +1528,8 @@ static struct symt* dwarf2_parse_enumeration_type(dwarf2_parse_context_t* ctx, switch (child->abbrev->tag) { case DW_TAG_enumerator: - dwarf2_parse_enumerator(ctx, child, (struct symt_enum*)di->symt); + if (symt_check_tag(di->symt, SymTagEnum)) + dwarf2_parse_enumerator(ctx, child, (struct symt_enum*)di->symt); break; default: FIXME("Unhandled Tag type 0x%lx at %s, for %s\n", @@ -1683,7 +1685,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, WARN("dropping global variable %s which has been optimized away\n", debugstr_a(name.u.string)); } } - if (is_pmt && subpgm->func && subpgm->func->type) + if (is_pmt && subpgm->func && symt_check_tag(subpgm->func->type, SymTagFunctionType)) symt_add_function_signature_parameter(subpgm->ctx->module, (struct symt_function_signature*)subpgm->func->type, param_type); @@ -2129,10 +2131,12 @@ static void dwarf2_set_line_number(struct module* module, ULONG_PTR address,
TRACE("%s %lx %s %u\n", debugstr_w(module->module.ModuleName), address, debugstr_a(source_get(module, *psrc)), line); - if (!(symt = symt_find_nearest(module, address)) || - symt->symt.tag != SymTagFunction) return; - func = (struct symt_function*)symt; - symt_add_func_line(module, func, *psrc, line, address - func->address); + symt = symt_find_nearest(module, address); + if (symt && symt_check_tag(&symt->symt, SymTagFunction)) + { + func = (struct symt_function*)symt; + symt_add_func_line(module, func, *psrc, line, address - func->address); + } }
static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, @@ -2466,7 +2470,7 @@ static enum location_error loc_compute_frame(struct process* pcs, for (i=0; i<vector_length(&func->vchildren); i++) { psym = vector_at(&func->vchildren, i); - if ((*psym)->tag == SymTagCustom) + if (psym && symt_check_tag(*psym, SymTagCustom)) { pframe = &((struct symt_hierarchy_point*)*psym)->loc;
@@ -3279,7 +3283,7 @@ static void dwarf2_location_compute(struct process* pcs, int err; dwarf2_traverse_context_t lctx;
- if (!func->container || func->container->tag != SymTagCompiland) + if (!func || !symt_check_tag(func->container, SymTagCompiland)) { WARN("We'd expect function %s's container to exist and be a compiland\n", debugstr_a(func->hash_elt.name)); err = loc_err_internal;
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index ee73abdf378..2f8a18cae8d 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -1602,10 +1602,10 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, /* either a pmt/variable relative to frame pointer or * pmt/variable in a register */ - assert(subpgm->func); - symt_add_func_local(subpgm->ctx->module, subpgm->func, - is_pmt ? DataIsParam : DataIsLocal, - &loc, block, param_type, name.u.string); + if (subpgm->func) + symt_add_func_local(subpgm->ctx->module, subpgm->func, + is_pmt ? DataIsParam : DataIsLocal, + &loc, block, param_type, name.u.string); break; } }
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 7 ++++--- dlls/dbghelp/source.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 2f8a18cae8d..0479f7c7401 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2190,6 +2190,7 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, p = vector_add(&dirs, &ctx->pool); *p = compile_dir ? compile_dir : "."; while (*traverse.data) + while (traverse.data < traverse.end_data && *traverse.data) { const char* rel = (const char*)traverse.data; unsigned rellen = strlen(rel); @@ -2205,7 +2206,7 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, unsigned baselen = strlen(compile_dir); char* tmp = pool_alloc(&ctx->pool, baselen + 1 + rellen + 1); strcpy(tmp, compile_dir); - if (tmp[baselen - 1] != '/') tmp[baselen++] = '/'; + if (baselen && tmp[baselen - 1] != '/') tmp[baselen++] = '/'; strcpy(&tmp[baselen], rel); *p = tmp; } @@ -2214,7 +2215,7 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, traverse.data++;
vector_init(&files, sizeof(unsigned), 16); - while (*traverse.data) + while (traverse.data < traverse.end_data && *traverse.data) { unsigned int dir_index, mod_time; const char* name; @@ -2233,7 +2234,7 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, } traverse.data++;
- while (traverse.data < traverse.end_data) + while (traverse.data < traverse.end_data && *traverse.data) { ULONG_PTR address = 0; unsigned file = 1; diff --git a/dlls/dbghelp/source.c b/dlls/dbghelp/source.c index 1844eec7838..a78e62a8661 100644 --- a/dlls/dbghelp/source.c +++ b/dlls/dbghelp/source.c @@ -78,7 +78,7 @@ unsigned source_new(struct module* module, const char* base, const char* name) if (!tmp) return ret; full = tmp; strcpy(tmp, base); - if (tmp[bsz - 1] != '/') tmp[bsz++] = '/'; + if (bsz && tmp[bsz - 1] != '/') tmp[bsz++] = '/'; strcpy(&tmp[bsz], name); } rb_module = module;
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 0479f7c7401..6b4eb90c05a 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2198,7 +2198,7 @@ static BOOL dwarf2_parse_line_numbers(const dwarf2_section_t* sections, traverse.data += rellen + 1; p = vector_add(&dirs, &ctx->pool);
- if (*rel == '/' || !compile_dir) + if (*rel == '/' || !compile_dir || !*compile_dir) *p = rel; else {
(dwarf format)
Signed-off-by: Eric Pouech eric.pouech@gmail.com
--- dlls/dbghelp/dwarf.c | 70 ++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 34 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 6b4eb90c05a..e514a4fde3b 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -2389,43 +2389,45 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, dwarf2_parse_abbrev_set(&abbrev_ctx, &ctx.abbrev_table, &ctx.pool);
sparse_array_init(&ctx.debug_info_table, sizeof(dwarf2_debug_info_t), 128); - dwarf2_read_one_debug_info(&ctx, &cu_ctx, NULL, &di); - - if (di->abbrev->tag == DW_TAG_compile_unit) - { - struct attribute name; - struct vector* children; - dwarf2_debug_info_t* child = NULL; - unsigned int i; - struct attribute stmt_list, low_pc; - struct attribute comp_dir; - - 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)) - comp_dir.u.string = NULL; - - 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)); - 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); - } - if (dwarf2_find_attribute(&ctx, di, DW_AT_stmt_list, &stmt_list)) + + if (dwarf2_read_one_debug_info(&ctx, &cu_ctx, NULL, &di)) + { + if (di->abbrev->tag == DW_TAG_compile_unit) { - if (dwarf2_parse_line_numbers(sections, &ctx, comp_dir.u.string, stmt_list.u.uvalue)) - module->module.LineNumbers = TRUE; + struct attribute name; + struct vector* children; + dwarf2_debug_info_t* child = NULL; + unsigned int i; + struct attribute stmt_list, low_pc; + struct attribute comp_dir; + + 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)) + comp_dir.u.string = NULL; + + 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)); + 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); + } + 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; + } + ret = TRUE; } - ret = TRUE; + else FIXME("Should have a compilation unit here\n"); } - else FIXME("Should have a compilation unit here\n"); pool_destroy(&ctx.pool); return ret; }