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:
parent
02baf6c630
commit
6c4c64265d
|
@ -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*
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1131,9 +1133,9 @@ static void pending_flush(struct pending_block* pending, struct module* module,
|
||||||
for (i = 0; i < pending->num; i++)
|
for (i = 0; i < pending->num; i++)
|
||||||
{
|
{
|
||||||
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:
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue