Module: wine Branch: refs/heads/master Commit: ae67326863246fc19e30cb3e8a3c4bd4562a9eae URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=ae67326863246fc19e30cb3e...
Author: Eric Pouech eric.pouech@wanadoo.fr Date: Sun Jun 18 21:31:39 2006 +0200
dbghelp: Dwarf & locations.
- put back the block attribute parsing - added dwarf2_compute_location to properly decode a location (at least starting it)
---
dlls/dbghelp/dwarf.c | 146 ++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 118 insertions(+), 28 deletions(-)
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 6c354b7..60c86f2 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -113,11 +113,18 @@ typedef struct dwarf2_abbrev_entry_s dwarf2_abbrev_entry_attr_t* attrs; } dwarf2_abbrev_entry_t;
+struct dwarf2_block +{ + unsigned size; + const unsigned char* ptr; +}; + union attribute { unsigned long uvalue; long svalue; const char* string; + struct dwarf2_block* block; };
typedef struct dwarf2_debug_info_s @@ -391,23 +398,31 @@ static void dwarf2_parse_attr_into_di(dw TRACE("strp<%s>\n", attr->string); break; case DW_FORM_block: - attr->uvalue = dwarf2_leb128_as_unsigned(ctx); - ctx->data += attr->uvalue; + attr->block = pool_alloc(&ctx->pool, sizeof(struct dwarf2_block)); + attr->block->size = dwarf2_leb128_as_unsigned(ctx); + attr->block->ptr = ctx->data; + ctx->data += attr->block->size; break;
case DW_FORM_block1: - attr->uvalue = dwarf2_parse_byte(ctx); - ctx->data += attr->uvalue; + attr->block = pool_alloc(&ctx->pool, sizeof(struct dwarf2_block)); + attr->block->size = dwarf2_parse_byte(ctx); + attr->block->ptr = ctx->data; + ctx->data += attr->block->size; break;
case DW_FORM_block2: - attr->uvalue = dwarf2_parse_u2(ctx); - ctx->data += attr->uvalue; + attr->block = pool_alloc(&ctx->pool, sizeof(struct dwarf2_block)); + attr->block->size = dwarf2_parse_u2(ctx); + attr->block->ptr = ctx->data; + ctx->data += attr->block->size; break;
case DW_FORM_block4: - attr->uvalue = dwarf2_parse_u4(ctx); - ctx->data += attr->uvalue; + attr->block = pool_alloc(&ctx->pool, sizeof(struct dwarf2_block)); + attr->block->size = dwarf2_parse_u4(ctx); + attr->block->ptr = ctx->data; + ctx->data += attr->block->size; break;
default: @@ -450,6 +465,96 @@ static void dwarf2_find_name(dwarf2_pars static void dwarf2_load_one_entry(dwarf2_parse_context_t*, dwarf2_debug_info_t*, struct symt_compiland*);
+#define Wine_DW_no_register -1 +#define Wine_DW_frame_register -2 + +static unsigned long dwarf2_compute_location(dwarf2_parse_context_t* ctx, + struct dwarf2_block* block, + int* in_register) +{ + unsigned long loc[64]; + unsigned stk; + + if (in_register) *in_register = Wine_DW_no_register; + loc[stk = 0] = 0; + + if (block->size) + { + /* FIXME: would require better definition of contexts */ + dwarf2_parse_context_t lctx; + unsigned char op; + BOOL piece_found = FALSE; + + lctx.data = block->ptr; + lctx.end_data = block->ptr + block->size; + lctx.word_size = ctx->word_size; + + while (lctx.data < lctx.end_data) + { + op = dwarf2_parse_byte(&lctx); + switch (op) + { + case DW_OP_addr: loc[++stk] = dwarf2_parse_addr(&lctx); break; + case DW_OP_const1u: loc[++stk] = dwarf2_parse_byte(&lctx); break; + case DW_OP_const1s: loc[++stk] = (long)(char)dwarf2_parse_byte(&lctx); break; + case DW_OP_const2u: loc[++stk] = dwarf2_parse_u2(&lctx); break; + case DW_OP_const2s: loc[++stk] = (long)(short)dwarf2_parse_u2(&lctx); break; + case DW_OP_const4u: loc[++stk] = dwarf2_parse_u4(&lctx); break; + case DW_OP_const4s: loc[++stk] = dwarf2_parse_u4(&lctx); break; + case DW_OP_constu: loc[++stk] = dwarf2_leb128_as_unsigned(&lctx); break; + case DW_OP_consts: loc[++stk] = dwarf2_leb128_as_signed(&lctx); break; + case DW_OP_plus_uconst: + loc[stk] += dwarf2_leb128_as_unsigned(&lctx); break; + case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: + case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: + case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: + case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: + case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: + case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: + case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: + case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: + if (in_register) + { + /* dbghelp APIs don't know how to cope with this anyway + * (for example 'long long' stored in two registers) + * FIXME: We should tell winedbg how to deal with it (sigh) + */ + if (!piece_found || (op - DW_OP_reg0 != *in_register + 1)) + { + if (*in_register != Wine_DW_no_register) + FIXME("Only supporting one reg (%d -> %d)\n", + *in_register, op - DW_OP_reg0); + *in_register = op - DW_OP_reg0; + } + } + else FIXME("Found register, while not expecting it\n"); + break; + case DW_OP_fbreg: + if (in_register) + { + if (*in_register != Wine_DW_no_register) + FIXME("Only supporting one reg (%d -> -2)\n", *in_register); + *in_register = Wine_DW_frame_register; + } + else FIXME("Found register, while not expecting it\n"); + loc[++stk] = dwarf2_leb128_as_signed(&lctx); + break; + case DW_OP_piece: + { + unsigned sz = dwarf2_leb128_as_unsigned(&lctx); + WARN("Not handling OP_piece directly (size=%d)\n", sz); + piece_found = TRUE; + } + break; + default: + FIXME("Unhandled attr op: %x\n", op); + return loc[stk]; + } + } + } + return loc[stk]; +} + static struct symt* dwarf2_lookup_type(dwarf2_parse_context_t* ctx, const dwarf2_debug_info_t* di) { @@ -699,8 +804,8 @@ static void dwarf2_parse_udt_member(dwar { struct symt* elt_type; union attribute name; -/* union attribute loc; */ - unsigned long offset; + union attribute loc; + unsigned long offset = 0;
assert(parent);
@@ -708,27 +813,12 @@ static void dwarf2_parse_udt_member(dwar
dwarf2_find_name(ctx, di, &name, "udt_member"); elt_type = dwarf2_lookup_type(ctx, di); -#if 0 if (dwarf2_find_attribute(di, DW_AT_data_member_location, &loc)) { - TRACE("found member_location at %s, for %s\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr)); - if (loc.uvalue) { - unsigned char op = dwarf2_parse_byte(ctx); - --uvalue; - switch (op) { - case DW_OP_plus_uconst: - offset = dwarf2_leb128_as_unsigned(ctx); - break; - default: - WARN("Unhandled attr op at %s, for %s, op:%u\n", dwarf2_debug_ctx(ctx), dwarf2_debug_attr(attr), op); - ctx->data += uvalue; - } - TRACE("found offset:%lu\n", offset); - } + TRACE("found member_location at %s\n", dwarf2_debug_ctx(ctx)); + offset = dwarf2_compute_location(ctx, loc.block, NULL); + TRACE("found offset:%lu\n", offset); } -#endif - FIXME("still to be implemented proper member location\n"); - offset = 0;
symt_add_udt_element(ctx->module, parent, name.string, elt_type, offset, 0);