dbghelp: Variables & registers.

- more strickling differentiation variable location between 
  a register, and the dereferenced address defined by a
  register (and possibly an offset)
- added a parameter to symt_add_func_local (and internal symbol
  data struct) to help differentiate
- fix all debug parsers to confer to this new scheme
This commit is contained in:
Eric Pouech 2006-09-25 22:40:41 +02:00 committed by Alexandre Julliard
parent 02baf6c630
commit 6c4c64265d
5 changed files with 35 additions and 29 deletions

View File

@ -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*

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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:
/*

View File

@ -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;