diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 72930bafb3a..2dff1f06b90 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -155,7 +155,8 @@ struct symt_data { long offset; /* DataIs{Member,Local,Param} in bits */ unsigned long length; /* DataIs{Member} in bits */ - unsigned long reg_id; /* DataIs{Local} (0 if frame relative) */ + unsigned long reg_rel : 1, /* DataIs{Local}: 0 in register, 1 deref */ + reg_id; /* DataIs{Local} (0 if frame relative) */ } s; VARIANT value; /* DataIsConstant */ } u; @@ -472,7 +473,7 @@ extern void symt_add_func_line(struct module* module, extern struct symt_data* symt_add_func_local(struct module* module, struct symt_function* func, - enum DataKind dt, int regno, long offset, + enum DataKind dt, BOOL regrel, int regno, long offset, struct symt_block* block, struct symt* type, const char* name); extern struct symt_block* diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index e129d99738b..114f781c059 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -499,8 +499,9 @@ static void dwarf2_find_name(dwarf2_parse_context_t* ctx, 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 +#define Wine_DW_no_register 0x7FFFFFFF +#define Wine_DW_frame_register 0x7FFFFFFE +#define Wine_DW_register_deref 0x80000000 static unsigned long dwarf2_compute_location(dwarf2_parse_context_t* ctx, struct dwarf2_block* block, @@ -567,7 +568,7 @@ static unsigned long dwarf2_compute_location(dwarf2_parse_context_t* ctx, { if (*in_register != Wine_DW_no_register) FIXME("Only supporting one reg (%d -> -2)\n", *in_register); - *in_register = Wine_DW_frame_register; + *in_register = Wine_DW_frame_register | Wine_DW_register_deref; } else FIXME("Found register, while not expecting it\n"); loc[++stk] = dwarf2_leb128_as_signed(&lctx); @@ -1066,7 +1067,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, offset = dwarf2_compute_location(subpgm->ctx, loc.block, &in_reg); TRACE("found parameter %s/%ld (reg=%d) at %s\n", name.string, offset, in_reg, dwarf2_debug_ctx(subpgm->ctx)); - switch (in_reg) + switch (in_reg & ~Wine_DW_register_deref) { case Wine_DW_no_register: /* it's a global variable */ @@ -1079,7 +1080,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, 0, param_type); break; case Wine_DW_frame_register: - in_reg = subpgm->frame_reg; + in_reg = subpgm->frame_reg | Wine_DW_register_deref; offset += subpgm->frame_offset; /* fall through */ default: @@ -1088,8 +1089,9 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm, */ symt_add_func_local(subpgm->ctx->module, subpgm->func, is_pmt ? DataIsParam : DataIsLocal, - dwarf2_map_register(in_reg), offset, - block, param_type, name.string); + dwarf2_map_register(in_reg & ~Wine_DW_register_deref), + in_reg & Wine_DW_register_deref, + offset, block, param_type, name.string); break; } } diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 748f46bc433..46bb70b37d6 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -1374,34 +1374,34 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root case S_BPREL_V1: symt_add_func_local(msc_dbg->module, curr_func, sym->stack_v1.offset > 0 ? DataIsParam : DataIsLocal, - 0, sym->stack_v1.offset, block, - codeview_get_type(sym->stack_v1.symtype, FALSE), - terminate_string(&sym->stack_v1.p_name)); + 0, TRUE, sym->stack_v1.offset, block, + codeview_get_type(sym->stack_v1.symtype, FALSE), + terminate_string(&sym->stack_v1.p_name)); break; case S_BPREL_V2: symt_add_func_local(msc_dbg->module, curr_func, sym->stack_v2.offset > 0 ? DataIsParam : DataIsLocal, - 0, sym->stack_v2.offset, block, + 0, TRUE, sym->stack_v2.offset, block, codeview_get_type(sym->stack_v2.symtype, FALSE), terminate_string(&sym->stack_v2.p_name)); break; case S_BPREL_V3: symt_add_func_local(msc_dbg->module, curr_func, sym->stack_v3.offset > 0 ? DataIsParam : DataIsLocal, - 0, sym->stack_v3.offset, block, + 0, TRUE, sym->stack_v3.offset, block, codeview_get_type(sym->stack_v3.symtype, FALSE), sym->stack_v3.name); break; case S_REGISTER_V1: symt_add_func_local(msc_dbg->module, curr_func, - DataIsLocal, sym->register_v1.reg, 0, + DataIsLocal, sym->register_v1.reg, FALSE, 0, block, codeview_get_type(sym->register_v1.type, FALSE), terminate_string(&sym->register_v1.p_name)); break; case S_REGISTER_V2: symt_add_func_local(msc_dbg->module, curr_func, - DataIsLocal, sym->register_v2.reg, 0, + DataIsLocal, sym->register_v2.reg, FALSE, 0, block, codeview_get_type(sym->register_v2.type, FALSE), terminate_string(&sym->register_v2.p_name)); break; diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c index 534e1b0ad9d..57aa82f5f2d 100644 --- a/dlls/dbghelp/stabs.c +++ b/dlls/dbghelp/stabs.c @@ -1091,7 +1091,8 @@ struct pending_loc_var struct symt* type; enum DataKind kind; unsigned offset; - unsigned regno; + unsigned regrel : 1, + regno; }; struct pending_block @@ -1102,7 +1103,7 @@ struct pending_block }; static inline void pending_add(struct pending_block* pending, const char* name, - enum DataKind dt, int regno, long offset) + enum DataKind dt, int regno, BOOL regrel, long offset) { if (pending->num == pending->allocated) { @@ -1120,6 +1121,7 @@ static inline void pending_add(struct pending_block* pending, const char* name, pending->vars[pending->num].kind = dt; pending->vars[pending->num].offset = offset; pending->vars[pending->num].regno = regno; + pending->vars[pending->num].regrel = regrel ? 1 : 0; pending->num++; } @@ -1131,9 +1133,9 @@ static void pending_flush(struct pending_block* pending, struct module* module, for (i = 0; i < pending->num; i++) { symt_add_func_local(module, func, - pending->vars[i].kind, pending->vars[i].regno, - pending->vars[i].offset, block, - pending->vars[i].type, pending->vars[i].name); + pending->vars[i].kind, pending->vars[i].regno, + pending->vars[i].regrel, pending->vars[i].offset, + block, pending->vars[i].type, pending->vars[i].name); } pending->num = 0; } @@ -1311,7 +1313,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, stab_strcpy(symname, sizeof(symname), ptr); symt_add_func_local(module, curr_func, stab_ptr->n_value > 0 ? DataIsParam : DataIsLocal, - 0, stab_ptr->n_value, NULL, param_type, symname); + 0, TRUE, stab_ptr->n_value, NULL, param_type, symname); symt_add_function_signature_parameter(module, (struct symt_function_signature*)curr_func->type, param_type); @@ -1352,19 +1354,19 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset, { struct symt* param_type = stabs_parse_type(ptr); stab_strcpy(symname, sizeof(symname), ptr); - symt_add_func_local(module, curr_func, DataIsParam, reg, 0, + symt_add_func_local(module, curr_func, DataIsParam, reg, FALSE, 0, NULL, param_type, symname); symt_add_function_signature_parameter(module, (struct symt_function_signature*)curr_func->type, param_type); } else - pending_add(&pending, ptr, DataIsLocal, reg, 0); + pending_add(&pending, ptr, DataIsLocal, reg, FALSE, 0); } break; case N_LSYM: /* These are local variables */ - if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, 0, stab_ptr->n_value); + if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, 0, TRUE, stab_ptr->n_value); break; case N_SLINE: /* diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 2c7904b6ded..1e66a32b748 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -300,7 +300,7 @@ void symt_add_func_line(struct module* module, struct symt_function* func, struct symt_data* symt_add_func_local(struct module* module, struct symt_function* func, enum DataKind dt, - int regno, long offset, + int regno, BOOL regrel, long offset, struct symt_block* block, struct symt* type, const char* name) { @@ -323,6 +323,7 @@ struct symt_data* symt_add_func_local(struct module* module, locsym->container = &block->symt; locsym->type = type; locsym->u.s.reg_id = regno; + locsym->u.s.reg_rel = regrel ? TRUE : FALSE; locsym->u.s.offset = offset * 8; locsym->u.s.length = 0; if (block) @@ -477,7 +478,7 @@ static void symt_fill_sym_info(const struct module_pair* pair, sym_info->Flags |= SYMFLAG_PARAMETER; /* fall through */ case DataIsLocal: - if (data->u.s.reg_id) + if (!data->u.s.reg_rel) { sym_info->Flags |= SYMFLAG_REGISTER; sym_info->Register = data->u.s.reg_id; @@ -486,8 +487,8 @@ static void symt_fill_sym_info(const struct module_pair* pair, else { sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_REGREL; - /* FIXME: needed ? moreover, it's i386 dependent !!! */ - sym_info->Register = CV_REG_EBP; + /* FIXME: it's i386 dependent !!! */ + sym_info->Register = data->u.s.reg_id ? data->u.s.reg_id : CV_REG_EBP; sym_info->Address = data->u.s.offset / 8; } break;