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 */ long offset; /* DataIs{Member,Local,Param} in bits */
unsigned long length; /* DataIs{Member} 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; } s;
VARIANT value; /* DataIsConstant */ VARIANT value; /* DataIsConstant */
} u; } u;
@ -472,7 +473,7 @@ extern void symt_add_func_line(struct module* module,
extern struct symt_data* extern struct symt_data*
symt_add_func_local(struct module* module, symt_add_func_local(struct module* module,
struct symt_function* func, 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_block* block,
struct symt* type, const char* name); struct symt* type, const char* name);
extern struct symt_block* 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*, static void dwarf2_load_one_entry(dwarf2_parse_context_t*, dwarf2_debug_info_t*,
struct symt_compiland*); struct symt_compiland*);
#define Wine_DW_no_register -1 #define Wine_DW_no_register 0x7FFFFFFF
#define Wine_DW_frame_register -2 #define Wine_DW_frame_register 0x7FFFFFFE
#define Wine_DW_register_deref 0x80000000
static unsigned long dwarf2_compute_location(dwarf2_parse_context_t* ctx, static unsigned long dwarf2_compute_location(dwarf2_parse_context_t* ctx,
struct dwarf2_block* block, 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) if (*in_register != Wine_DW_no_register)
FIXME("Only supporting one reg (%d -> -2)\n", *in_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"); else FIXME("Found register, while not expecting it\n");
loc[++stk] = dwarf2_leb128_as_signed(&lctx); 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); offset = dwarf2_compute_location(subpgm->ctx, loc.block, &in_reg);
TRACE("found parameter %s/%ld (reg=%d) at %s\n", TRACE("found parameter %s/%ld (reg=%d) at %s\n",
name.string, offset, in_reg, dwarf2_debug_ctx(subpgm->ctx)); 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: case Wine_DW_no_register:
/* it's a global variable */ /* it's a global variable */
@ -1079,7 +1080,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
0, param_type); 0, param_type);
break; break;
case Wine_DW_frame_register: case Wine_DW_frame_register:
in_reg = subpgm->frame_reg; in_reg = subpgm->frame_reg | Wine_DW_register_deref;
offset += subpgm->frame_offset; offset += subpgm->frame_offset;
/* fall through */ /* fall through */
default: default:
@ -1088,8 +1089,9 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
*/ */
symt_add_func_local(subpgm->ctx->module, subpgm->func, symt_add_func_local(subpgm->ctx->module, subpgm->func,
is_pmt ? DataIsParam : DataIsLocal, is_pmt ? DataIsParam : DataIsLocal,
dwarf2_map_register(in_reg), offset, dwarf2_map_register(in_reg & ~Wine_DW_register_deref),
block, param_type, name.string); in_reg & Wine_DW_register_deref,
offset, block, param_type, name.string);
break; 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: case S_BPREL_V1:
symt_add_func_local(msc_dbg->module, curr_func, symt_add_func_local(msc_dbg->module, curr_func,
sym->stack_v1.offset > 0 ? DataIsParam : DataIsLocal, sym->stack_v1.offset > 0 ? DataIsParam : DataIsLocal,
0, sym->stack_v1.offset, block, 0, TRUE, sym->stack_v1.offset, block,
codeview_get_type(sym->stack_v1.symtype, FALSE), codeview_get_type(sym->stack_v1.symtype, FALSE),
terminate_string(&sym->stack_v1.p_name)); terminate_string(&sym->stack_v1.p_name));
break; break;
case S_BPREL_V2: case S_BPREL_V2:
symt_add_func_local(msc_dbg->module, curr_func, symt_add_func_local(msc_dbg->module, curr_func,
sym->stack_v2.offset > 0 ? DataIsParam : DataIsLocal, 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), codeview_get_type(sym->stack_v2.symtype, FALSE),
terminate_string(&sym->stack_v2.p_name)); terminate_string(&sym->stack_v2.p_name));
break; break;
case S_BPREL_V3: case S_BPREL_V3:
symt_add_func_local(msc_dbg->module, curr_func, symt_add_func_local(msc_dbg->module, curr_func,
sym->stack_v3.offset > 0 ? DataIsParam : DataIsLocal, 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), codeview_get_type(sym->stack_v3.symtype, FALSE),
sym->stack_v3.name); sym->stack_v3.name);
break; break;
case S_REGISTER_V1: case S_REGISTER_V1:
symt_add_func_local(msc_dbg->module, curr_func, 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), block, codeview_get_type(sym->register_v1.type, FALSE),
terminate_string(&sym->register_v1.p_name)); terminate_string(&sym->register_v1.p_name));
break; break;
case S_REGISTER_V2: case S_REGISTER_V2:
symt_add_func_local(msc_dbg->module, curr_func, 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), block, codeview_get_type(sym->register_v2.type, FALSE),
terminate_string(&sym->register_v2.p_name)); terminate_string(&sym->register_v2.p_name));
break; break;

View File

@ -1091,7 +1091,8 @@ struct pending_loc_var
struct symt* type; struct symt* type;
enum DataKind kind; enum DataKind kind;
unsigned offset; unsigned offset;
unsigned regno; unsigned regrel : 1,
regno;
}; };
struct pending_block struct pending_block
@ -1102,7 +1103,7 @@ struct pending_block
}; };
static inline void pending_add(struct pending_block* pending, const char* name, 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) 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].kind = dt;
pending->vars[pending->num].offset = offset; pending->vars[pending->num].offset = offset;
pending->vars[pending->num].regno = regno; pending->vars[pending->num].regno = regno;
pending->vars[pending->num].regrel = regrel ? 1 : 0;
pending->num++; pending->num++;
} }
@ -1132,8 +1134,8 @@ static void pending_flush(struct pending_block* pending, struct module* module,
{ {
symt_add_func_local(module, func, symt_add_func_local(module, func,
pending->vars[i].kind, pending->vars[i].regno, pending->vars[i].kind, pending->vars[i].regno,
pending->vars[i].offset, block, pending->vars[i].regrel, pending->vars[i].offset,
pending->vars[i].type, pending->vars[i].name); block, pending->vars[i].type, pending->vars[i].name);
} }
pending->num = 0; pending->num = 0;
} }
@ -1311,7 +1313,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
stab_strcpy(symname, sizeof(symname), ptr); stab_strcpy(symname, sizeof(symname), ptr);
symt_add_func_local(module, curr_func, symt_add_func_local(module, curr_func,
stab_ptr->n_value > 0 ? DataIsParam : DataIsLocal, 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, symt_add_function_signature_parameter(module,
(struct symt_function_signature*)curr_func->type, (struct symt_function_signature*)curr_func->type,
param_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); struct symt* param_type = stabs_parse_type(ptr);
stab_strcpy(symname, sizeof(symname), 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); NULL, param_type, symname);
symt_add_function_signature_parameter(module, symt_add_function_signature_parameter(module,
(struct symt_function_signature*)curr_func->type, (struct symt_function_signature*)curr_func->type,
param_type); param_type);
} }
else else
pending_add(&pending, ptr, DataIsLocal, reg, 0); pending_add(&pending, ptr, DataIsLocal, reg, FALSE, 0);
} }
break; break;
case N_LSYM: case N_LSYM:
/* These are local variables */ /* 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; break;
case N_SLINE: 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_data* symt_add_func_local(struct module* module,
struct symt_function* func, struct symt_function* func,
enum DataKind dt, enum DataKind dt,
int regno, long offset, int regno, BOOL regrel, long offset,
struct symt_block* block, struct symt_block* block,
struct symt* type, const char* name) 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->container = &block->symt;
locsym->type = type; locsym->type = type;
locsym->u.s.reg_id = regno; locsym->u.s.reg_id = regno;
locsym->u.s.reg_rel = regrel ? TRUE : FALSE;
locsym->u.s.offset = offset * 8; locsym->u.s.offset = offset * 8;
locsym->u.s.length = 0; locsym->u.s.length = 0;
if (block) if (block)
@ -477,7 +478,7 @@ static void symt_fill_sym_info(const struct module_pair* pair,
sym_info->Flags |= SYMFLAG_PARAMETER; sym_info->Flags |= SYMFLAG_PARAMETER;
/* fall through */ /* fall through */
case DataIsLocal: case DataIsLocal:
if (data->u.s.reg_id) if (!data->u.s.reg_rel)
{ {
sym_info->Flags |= SYMFLAG_REGISTER; sym_info->Flags |= SYMFLAG_REGISTER;
sym_info->Register = data->u.s.reg_id; sym_info->Register = data->u.s.reg_id;
@ -486,8 +487,8 @@ static void symt_fill_sym_info(const struct module_pair* pair,
else else
{ {
sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_REGREL; sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_REGREL;
/* FIXME: needed ? moreover, it's i386 dependent !!! */ /* FIXME: it's i386 dependent !!! */
sym_info->Register = CV_REG_EBP; sym_info->Register = data->u.s.reg_id ? data->u.s.reg_id : CV_REG_EBP;
sym_info->Address = data->u.s.offset / 8; sym_info->Address = data->u.s.offset / 8;
} }
break; break;