dbghelp: Storage of func locals & parameters.
- added the ability to tell to add_func_local whether we're adding a local variable or a parameter (and removed the black magic we were using) - we can now address variables defined as an offset to a register
This commit is contained in:
parent
df179e9bf1
commit
cff41cf9f2
|
@ -470,7 +470,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,
|
||||
int regno, int offset,
|
||||
enum DataKind dt, int regno, long offset,
|
||||
struct symt_block* block,
|
||||
struct symt* type, const char* name);
|
||||
extern struct symt_block*
|
||||
|
|
|
@ -1372,28 +1372,36 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
* Function parameters and stack variables.
|
||||
*/
|
||||
case S_BPREL_V1:
|
||||
symt_add_func_local(msc_dbg->module, curr_func, 0, sym->stack_v1.offset,
|
||||
block, codeview_get_type(sym->stack_v1.symtype, FALSE),
|
||||
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));
|
||||
break;
|
||||
case S_BPREL_V2:
|
||||
symt_add_func_local(msc_dbg->module, curr_func, 0, sym->stack_v2.offset,
|
||||
block, codeview_get_type(sym->stack_v2.symtype, FALSE),
|
||||
symt_add_func_local(msc_dbg->module, curr_func,
|
||||
sym->stack_v2.offset > 0 ? DataIsParam : DataIsLocal,
|
||||
0, 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, 0, sym->stack_v3.offset,
|
||||
block, codeview_get_type(sym->stack_v3.symtype, FALSE),
|
||||
symt_add_func_local(msc_dbg->module, curr_func,
|
||||
sym->stack_v3.offset > 0 ? DataIsParam : DataIsLocal,
|
||||
0, 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, 0, sym->register_v1.reg,
|
||||
symt_add_func_local(msc_dbg->module, curr_func,
|
||||
DataIsLocal, sym->register_v1.reg, 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, 0, sym->register_v2.reg,
|
||||
symt_add_func_local(msc_dbg->module, curr_func,
|
||||
DataIsLocal, sym->register_v2.reg, 0,
|
||||
block, codeview_get_type(sym->register_v2.type, FALSE),
|
||||
terminate_string(&sym->register_v2.p_name));
|
||||
break;
|
||||
|
|
|
@ -1089,6 +1089,7 @@ struct pending_loc_var
|
|||
{
|
||||
char name[256];
|
||||
struct symt* type;
|
||||
enum DataKind kind;
|
||||
unsigned offset;
|
||||
unsigned regno;
|
||||
};
|
||||
|
@ -1101,7 +1102,7 @@ struct pending_block
|
|||
};
|
||||
|
||||
static inline void pending_add(struct pending_block* pending, const char* name,
|
||||
int regno, int offset)
|
||||
enum DataKind dt, int regno, long offset)
|
||||
{
|
||||
if (pending->num == pending->allocated)
|
||||
{
|
||||
|
@ -1116,6 +1117,7 @@ static inline void pending_add(struct pending_block* pending, const char* name,
|
|||
stab_strcpy(pending->vars[pending->num].name,
|
||||
sizeof(pending->vars[pending->num].name), name);
|
||||
pending->vars[pending->num].type = stabs_parse_type(name);
|
||||
pending->vars[pending->num].kind = dt;
|
||||
pending->vars[pending->num].offset = offset;
|
||||
pending->vars[pending->num].regno = regno;
|
||||
pending->num++;
|
||||
|
@ -1128,7 +1130,8 @@ 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].regno,
|
||||
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);
|
||||
}
|
||||
|
@ -1339,8 +1342,9 @@ 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, 0, stab_ptr->n_value,
|
||||
NULL, param_type, symname);
|
||||
symt_add_func_local(module, curr_func,
|
||||
stab_ptr->n_value > 0 ? DataIsParam : DataIsLocal,
|
||||
0, stab_ptr->n_value, NULL, param_type, symname);
|
||||
symt_add_function_signature_parameter(module,
|
||||
(struct symt_function_signature*)curr_func->type,
|
||||
param_type);
|
||||
|
@ -1381,19 +1385,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, reg, 1,
|
||||
symt_add_func_local(module, curr_func, DataIsParam, reg, 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, reg, 0);
|
||||
pending_add(&pending, ptr, DataIsLocal, reg, 0);
|
||||
}
|
||||
break;
|
||||
case N_LSYM:
|
||||
/* These are local variables */
|
||||
if (curr_func != NULL) pending_add(&pending, ptr, 0, stab_ptr->n_value);
|
||||
if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, 0, stab_ptr->n_value);
|
||||
break;
|
||||
case N_SLINE:
|
||||
/*
|
||||
|
|
|
@ -290,49 +290,41 @@ void symt_add_func_line(struct module* module, struct symt_function* func,
|
|||
* symt_add_func_local
|
||||
*
|
||||
* Adds a new local/parameter to a given function:
|
||||
* In any cases, dt tells whether it's a local variable or a parameter
|
||||
* If regno it's not 0:
|
||||
* - then variable is stored in a register
|
||||
* - if offset is > 0, then it's a parameter to the function (in a register)
|
||||
* - if offset is = 0, then it's a local variable (in a register)
|
||||
* - otherwise, value is referenced by register + offset
|
||||
* Otherwise, the variable is stored on the stack:
|
||||
* - if offset is > 0, then it's a parameter to the function
|
||||
* - otherwise, it's a local variable
|
||||
* FIXME: this is too i386 centric
|
||||
* - offset is then the offset from the frame register
|
||||
*/
|
||||
struct symt_data* symt_add_func_local(struct module* module,
|
||||
struct symt_function* func,
|
||||
int regno, int offset,
|
||||
enum DataKind dt,
|
||||
int regno, long offset,
|
||||
struct symt_block* block,
|
||||
struct symt* type, const char* name)
|
||||
{
|
||||
struct symt_data* locsym;
|
||||
struct symt** p;
|
||||
|
||||
assert(func);
|
||||
assert(func->symt.tag == SymTagFunction);
|
||||
|
||||
TRACE_(dbghelp_symt)("Adding local symbol (%s:%s): %s %p\n",
|
||||
module->module.ModuleName, func->hash_elt.name,
|
||||
name, type);
|
||||
|
||||
assert(func);
|
||||
assert(func->symt.tag == SymTagFunction);
|
||||
assert(dt == DataIsParam || dt == DataIsLocal);
|
||||
|
||||
locsym = pool_alloc(&module->pool, sizeof(*locsym));
|
||||
locsym->symt.tag = SymTagData;
|
||||
locsym->hash_elt.name = pool_strdup(&module->pool, name);
|
||||
locsym->hash_elt.next = NULL;
|
||||
locsym->kind = (offset > 0) ? DataIsParam : DataIsLocal;
|
||||
locsym->kind = dt;
|
||||
locsym->container = &block->symt;
|
||||
locsym->type = type;
|
||||
if (regno)
|
||||
{
|
||||
locsym->u.s.reg_id = regno;
|
||||
locsym->u.s.offset = 0;
|
||||
locsym->u.s.length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
locsym->u.s.reg_id = 0;
|
||||
locsym->u.s.offset = offset * 8;
|
||||
locsym->u.s.length = 0;
|
||||
}
|
||||
if (block)
|
||||
p = vector_add(&block->vchildren, &module->pool);
|
||||
else
|
||||
|
@ -341,6 +333,7 @@ struct symt_data* symt_add_func_local(struct module* module,
|
|||
return locsym;
|
||||
}
|
||||
|
||||
|
||||
struct symt_block* symt_open_func_block(struct module* module,
|
||||
struct symt_function* func,
|
||||
struct symt_block* parent_block,
|
||||
|
|
Loading…
Reference in New Issue