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: