From d812f8b42ccd319615c9961595cf756449bd1288 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Fri, 24 Nov 2006 22:17:47 +0100 Subject: [PATCH] dbghelp: Added infrastructure to compute variable location at runtime (as opposed to debug info parse time). Use it to send the variables depending on not known frame register at parse time. Made just a stub for the location computation function for dwarf2. --- dlls/dbghelp/dbghelp_private.h | 8 +++++- dlls/dbghelp/dwarf.c | 51 +++++++++++++++++++++------------- dlls/dbghelp/symbol.c | 39 ++++++++++++++++++-------- 3 files changed, 65 insertions(+), 33 deletions(-) diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index d6081bd20aa..fbf98796ba4 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -305,6 +305,8 @@ enum module_type DMT_PDB, /* PDB file */ }; +struct process; + struct module { IMAGEHLP_MODULE64 module; @@ -317,10 +319,14 @@ struct module /* memory allocation pool */ struct pool pool; - /* symbol tables */ + /* symbols & symbol tables */ int sortlist_valid; struct symt_ht** addr_sorttab; struct hash_table ht_symbols; + void (*loc_compute)(struct process* pcs, + const struct module* module, + const struct symt_function* func, + struct location* loc); /* types */ struct hash_table ht_types; diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 2a40493c2b5..55834139227 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -721,7 +721,6 @@ static BOOL compute_location(dwarf2_traverse_context_t* ctx, struct location* lo break; default: FIXME("Unhandled attr op: %x\n", op); - loc->offset = 0; return FALSE; } } @@ -764,7 +763,19 @@ static BOOL dwarf2_compute_location_attr(dwarf2_parse_context_t* ctx, lctx.end_data = xloc.u.block.ptr + xloc.u.block.size; lctx.word_size = ctx->word_size; - compute_location(&lctx, loc, frame); + if (!compute_location(&lctx, loc, frame)) + { + loc->kind = loc_error; + loc->reg = loc_err_too_complex; + } + else if (loc->kind == loc_dwarf2_block) + { + unsigned* ptr = pool_alloc(&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); + loc->offset = (unsigned long)ptr; + } } return TRUE; } @@ -1216,23 +1227,10 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, { struct attribute ext; - if (loc.kind >= loc_user) - { - FIXME("Unsupported yet location list in %s on variable %s\n", - subpgm->func->hash_elt.name, name.u.string); - return; - } - - if (subpgm->frame.kind >= loc_user) - { - FIXME("Unsupported yet location list in %s on frame for var %s\n", - subpgm->func->hash_elt.name, name.u.string); - return; - } - - TRACE("found parameter %s/%ld (reg=%d) at %s\n", - name.u.string, loc.offset, loc.reg, + TRACE("found parameter %s (kind=%d, offset=%ld, reg=%d) at %s\n", + name.u.string, loc.kind, loc.offset, loc.reg, dwarf2_debug_ctx(subpgm->ctx)); + switch (loc.kind) { case loc_absolute: @@ -1245,6 +1243,8 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, subpgm->ctx->module->module.BaseOfImage + loc.offset, 0, param_type); break; + default: + /* fall through */ case loc_register: case loc_regrel: /* either a pmt/variable relative to frame pointer or @@ -1255,8 +1255,6 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, is_pmt ? DataIsParam : DataIsLocal, &loc, block, param_type, name.u.string); break; - default: - FIXME("Unsupported\n"); } } if (dwarf2_find_attribute(subpgm->ctx, di, DW_AT_const_value, &value)) @@ -1893,6 +1891,17 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections, return ret; } +static void dwarf2_location_compute(struct process* pcs, + const struct module* module, + const struct symt_function* func, + struct location* loc) +{ + FIXME("Not implemented yet\n"); + loc->kind = loc_register; + loc->reg = -1; + loc->offset = 0; +} + BOOL dwarf2_parse(struct module* module, unsigned long load_offset, const struct elf_thunk_area* thunks, const unsigned char* debug, unsigned int debug_size, @@ -1906,6 +1915,8 @@ BOOL dwarf2_parse(struct module* module, unsigned long load_offset, const unsigned char*comp_unit_cursor = debug; const unsigned char*end_debug = debug + debug_size; + module->loc_compute = dwarf2_location_compute; + section[section_debug].address = debug; section[section_debug].size = debug_size; section[section_abbrev].address = abbrev; diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index c6a44c954a1..8e1cdf4a61a 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -477,19 +477,34 @@ static void symt_fill_sym_info(const struct module_pair* pair, case DataIsParam: sym_info->Flags |= SYMFLAG_PARAMETER; /* fall through */ - case DataIsLocal: - if (data->u.var.kind == loc_register) + case DataIsLocal: { - sym_info->Flags |= SYMFLAG_REGISTER; - sym_info->Register = data->u.var.reg; - sym_info->Address = 0; - } - else - { - sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_REGREL; - /* FIXME: it's i386 dependent !!! */ - sym_info->Register = data->u.var.reg ? data->u.var.reg : CV_REG_EBP; - sym_info->Address = data->u.var.offset; + struct location loc = data->u.var; + + if (loc.kind >= loc_user) + pair->effective->loc_compute(pair->pcs, pair->effective, func, &loc); + + switch (loc.kind) + { + case loc_error: + /* for now we report error cases as a negative register number */ + sym_info->Flags |= SYMFLAG_LOCAL; + /* fall through */ + case loc_register: + sym_info->Flags |= SYMFLAG_REGISTER; + sym_info->Register = loc.reg; + sym_info->Address = 0; + break; + case loc_regrel: + sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_REGREL; + /* FIXME: it's i386 dependent !!! */ + sym_info->Register = loc.reg ? loc.reg : CV_REG_EBP; + sym_info->Address = loc.offset; + break; + default: + FIXME("Shouldn't happen (kind=%d), debug reader backend is broken\n", loc.kind); + assert(0); + } } break; case DataIsGlobal: