dbghelp: Use the location info structure thoughout the code to handle the location of a data variable.
This commit is contained in:
parent
d5c4e55d36
commit
20fc25bc55
|
@ -172,15 +172,25 @@ struct symt_data
|
|||
struct symt* type;
|
||||
union /* depends on kind */
|
||||
{
|
||||
unsigned long address; /* DataIs{Global, FileStatic} */
|
||||
/* DataIs{Global, FileStatic}:
|
||||
* loc.kind is loc_absolute
|
||||
* loc.offset is address
|
||||
* DataIs{Local,Param}:
|
||||
* with loc.kind
|
||||
* loc_absolute not supported
|
||||
* loc_register location is in register loc.reg
|
||||
* loc_regrel location is at address loc.reg + loc.offset
|
||||
* >= loc_user ask debug info provider for resolution
|
||||
*/
|
||||
struct location var;
|
||||
/* DataIs{Member} (all values are in bits, not bytes) */
|
||||
struct
|
||||
{
|
||||
long offset; /* DataIs{Member,Local,Param} in bits */
|
||||
unsigned long length; /* DataIs{Member} in bits */
|
||||
unsigned long reg_rel : 1, /* DataIs{Local}: 0 in register, 1 deref */
|
||||
reg_id; /* DataIs{Local} (0 if frame relative) */
|
||||
} s;
|
||||
VARIANT value; /* DataIsConstant */
|
||||
long offset;
|
||||
unsigned long length;
|
||||
} member;
|
||||
/* DataIsConstant */
|
||||
VARIANT value;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -500,7 +510,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, BOOL regrel, int regno, long offset,
|
||||
enum DataKind dt, const struct location* loc,
|
||||
struct symt_block* block,
|
||||
struct symt* type, const char* name);
|
||||
extern struct symt_block*
|
||||
|
|
|
@ -1253,8 +1253,7 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
|
|||
assert(subpgm->func);
|
||||
symt_add_func_local(subpgm->ctx->module, subpgm->func,
|
||||
is_pmt ? DataIsParam : DataIsLocal,
|
||||
loc.reg, loc.kind == loc_regrel,
|
||||
loc.offset, block, param_type, name.u.string);
|
||||
&loc, block, param_type, name.u.string);
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported\n");
|
||||
|
|
|
@ -502,18 +502,18 @@ static void elf_finish_stabs_info(struct module* module, struct hash_table* symt
|
|||
{
|
||||
case DataIsGlobal:
|
||||
case DataIsFileStatic:
|
||||
if (((struct symt_data*)sym)->u.address != module->elf_info->elf_addr)
|
||||
if (((struct symt_data*)sym)->u.var.offset != module->elf_info->elf_addr)
|
||||
break;
|
||||
symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
|
||||
((struct symt_data*)sym)->container);
|
||||
if (symp)
|
||||
{
|
||||
if (((struct symt_data*)sym)->u.address != module->elf_info->elf_addr &&
|
||||
((struct symt_data*)sym)->u.address != module->elf_info->elf_addr + symp->st_value)
|
||||
if (((struct symt_data*)sym)->u.var.offset != module->elf_info->elf_addr &&
|
||||
((struct symt_data*)sym)->u.var.offset != module->elf_info->elf_addr + symp->st_value)
|
||||
FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n",
|
||||
sym, module->module.ModuleName, sym->hash_elt.name,
|
||||
((struct symt_function*)sym)->address, module->elf_info->elf_addr + symp->st_value);
|
||||
((struct symt_data*)sym)->u.address = module->elf_info->elf_addr +
|
||||
((struct symt_data*)sym)->u.var.offset = module->elf_info->elf_addr +
|
||||
symp->st_value;
|
||||
((struct symt_data*)sym)->kind = (ELF32_ST_BIND(symp->st_info) == STB_LOCAL) ?
|
||||
DataIsFileStatic : DataIsGlobal;
|
||||
|
|
|
@ -1239,6 +1239,7 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
struct symt* symt;
|
||||
const char* name;
|
||||
struct symt_compiland* compiland = NULL;
|
||||
struct location loc;
|
||||
|
||||
/*
|
||||
* Loop over the different types of records and whenever we
|
||||
|
@ -1372,36 +1373,51 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
* Function parameters and stack variables.
|
||||
*/
|
||||
case S_BPREL_V1:
|
||||
loc.kind = loc_regrel;
|
||||
loc.reg = 0; /* FIXME */
|
||||
loc.offset = sym->stack_v1.offset;
|
||||
symt_add_func_local(msc_dbg->module, curr_func,
|
||||
sym->stack_v1.offset > 0 ? DataIsParam : DataIsLocal,
|
||||
0, TRUE, sym->stack_v1.offset, block,
|
||||
&loc, block,
|
||||
codeview_get_type(sym->stack_v1.symtype, FALSE),
|
||||
terminate_string(&sym->stack_v1.p_name));
|
||||
break;
|
||||
case S_BPREL_V2:
|
||||
loc.kind = loc_regrel;
|
||||
loc.reg = 0; /* FIXME */
|
||||
loc.offset = sym->stack_v2.offset;
|
||||
symt_add_func_local(msc_dbg->module, curr_func,
|
||||
sym->stack_v2.offset > 0 ? DataIsParam : DataIsLocal,
|
||||
0, TRUE, sym->stack_v2.offset, block,
|
||||
&loc, block,
|
||||
codeview_get_type(sym->stack_v2.symtype, FALSE),
|
||||
terminate_string(&sym->stack_v2.p_name));
|
||||
break;
|
||||
case S_BPREL_V3:
|
||||
loc.kind = loc_regrel;
|
||||
loc.reg = 0; /* FIXME */
|
||||
loc.offset = sym->stack_v3.offset;
|
||||
symt_add_func_local(msc_dbg->module, curr_func,
|
||||
sym->stack_v3.offset > 0 ? DataIsParam : DataIsLocal,
|
||||
0, TRUE, sym->stack_v3.offset, block,
|
||||
&loc, block,
|
||||
codeview_get_type(sym->stack_v3.symtype, FALSE),
|
||||
sym->stack_v3.name);
|
||||
break;
|
||||
|
||||
case S_REGISTER_V1:
|
||||
loc.kind = loc_register;
|
||||
loc.reg = sym->register_v1.reg;
|
||||
loc.offset = 0;
|
||||
symt_add_func_local(msc_dbg->module, curr_func,
|
||||
DataIsLocal, sym->register_v1.reg, FALSE, 0,
|
||||
DataIsLocal, &loc,
|
||||
block, codeview_get_type(sym->register_v1.type, FALSE),
|
||||
terminate_string(&sym->register_v1.p_name));
|
||||
break;
|
||||
case S_REGISTER_V2:
|
||||
loc.kind = loc_register;
|
||||
loc.reg = sym->register_v2.reg;
|
||||
loc.offset = 0;
|
||||
symt_add_func_local(msc_dbg->module, curr_func,
|
||||
DataIsLocal, sym->register_v2.reg, FALSE, 0,
|
||||
DataIsLocal, &loc,
|
||||
block, codeview_get_type(sym->register_v2.type, FALSE),
|
||||
terminate_string(&sym->register_v2.p_name));
|
||||
break;
|
||||
|
|
|
@ -1095,9 +1095,7 @@ struct pending_loc_var
|
|||
char name[256];
|
||||
struct symt* type;
|
||||
enum DataKind kind;
|
||||
unsigned offset;
|
||||
unsigned regrel : 1,
|
||||
regno;
|
||||
struct location loc;
|
||||
};
|
||||
|
||||
struct pending_block
|
||||
|
@ -1108,7 +1106,7 @@ struct pending_block
|
|||
};
|
||||
|
||||
static inline void pending_add(struct pending_block* pending, const char* name,
|
||||
enum DataKind dt, int regno, BOOL regrel, long offset)
|
||||
enum DataKind dt, const struct location* loc)
|
||||
{
|
||||
if (pending->num == pending->allocated)
|
||||
{
|
||||
|
@ -1124,9 +1122,7 @@ static inline void pending_add(struct pending_block* pending, const char* 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->vars[pending->num].regrel = regrel ? 1 : 0;
|
||||
pending->vars[pending->num].loc = *loc;
|
||||
pending->num++;
|
||||
}
|
||||
|
||||
|
@ -1138,8 +1134,7 @@ 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].regrel, pending->vars[i].offset,
|
||||
pending->vars[i].kind, &pending->vars[i].loc,
|
||||
block, pending->vars[i].type, pending->vars[i].name);
|
||||
}
|
||||
pending->num = 0;
|
||||
|
@ -1195,6 +1190,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
|||
int source_idx = -1;
|
||||
struct pending_block pending;
|
||||
BOOL ret = TRUE;
|
||||
struct location loc;
|
||||
|
||||
nstab = stablen / sizeof(struct stab_nlist);
|
||||
strs_end = strs + strtablen;
|
||||
|
@ -1316,9 +1312,12 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
|||
{
|
||||
struct symt* param_type = stabs_parse_type(ptr);
|
||||
stab_strcpy(symname, sizeof(symname), ptr);
|
||||
loc.kind = loc_regrel;
|
||||
loc.reg = 0; /* FIXME */
|
||||
loc.offset = stab_ptr->n_value;
|
||||
symt_add_func_local(module, curr_func,
|
||||
stab_ptr->n_value > 0 ? DataIsParam : DataIsLocal,
|
||||
0, TRUE, stab_ptr->n_value, NULL, param_type, symname);
|
||||
(long)stab_ptr->n_value >= 0 ? DataIsParam : DataIsLocal,
|
||||
&loc, NULL, param_type, symname);
|
||||
symt_add_function_signature_parameter(module,
|
||||
(struct symt_function_signature*)curr_func->type,
|
||||
param_type);
|
||||
|
@ -1328,18 +1327,19 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
|||
/* These are registers (as local variables) */
|
||||
if (curr_func != NULL)
|
||||
{
|
||||
unsigned reg;
|
||||
loc.kind = loc_register;
|
||||
loc.offset = 0;
|
||||
|
||||
switch (stab_ptr->n_value)
|
||||
{
|
||||
case 0: reg = CV_REG_EAX; break;
|
||||
case 1: reg = CV_REG_ECX; break;
|
||||
case 2: reg = CV_REG_EDX; break;
|
||||
case 3: reg = CV_REG_EBX; break;
|
||||
case 4: reg = CV_REG_ESP; break;
|
||||
case 5: reg = CV_REG_EBP; break;
|
||||
case 6: reg = CV_REG_ESI; break;
|
||||
case 7: reg = CV_REG_EDI; break;
|
||||
case 0: loc.reg = CV_REG_EAX; break;
|
||||
case 1: loc.reg = CV_REG_ECX; break;
|
||||
case 2: loc.reg = CV_REG_EDX; break;
|
||||
case 3: loc.reg = CV_REG_EBX; break;
|
||||
case 4: loc.reg = CV_REG_ESP; break;
|
||||
case 5: loc.reg = CV_REG_EBP; break;
|
||||
case 6: loc.reg = CV_REG_ESI; break;
|
||||
case 7: loc.reg = CV_REG_EDI; break;
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
|
@ -1348,10 +1348,10 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
|||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19: reg = CV_REG_ST0 + stab_ptr->n_value - 12; break;
|
||||
case 19: loc.reg = CV_REG_ST0 + stab_ptr->n_value - 12; break;
|
||||
default:
|
||||
FIXME("Unknown register value (%lu)\n", stab_ptr->n_value);
|
||||
reg = CV_REG_NONE;
|
||||
loc.reg = CV_REG_NONE;
|
||||
break;
|
||||
}
|
||||
stab_strcpy(symname, sizeof(symname), ptr);
|
||||
|
@ -1359,19 +1359,22 @@ 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, FALSE, 0,
|
||||
symt_add_func_local(module, curr_func, DataIsParam, &loc,
|
||||
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, FALSE, 0);
|
||||
pending_add(&pending, ptr, DataIsLocal, &loc);
|
||||
}
|
||||
break;
|
||||
case N_LSYM:
|
||||
/* These are local variables */
|
||||
if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, 0, TRUE, stab_ptr->n_value);
|
||||
loc.kind = loc_regrel;
|
||||
loc.reg = 0; /* FIXME */
|
||||
loc.offset = stab_ptr->n_value;
|
||||
if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, &loc);
|
||||
break;
|
||||
case N_SLINE:
|
||||
/*
|
||||
|
|
|
@ -197,7 +197,7 @@ struct symt_data* symt_new_global_variable(struct module* module,
|
|||
sym->kind = is_static ? DataIsFileStatic : DataIsGlobal;
|
||||
sym->container = compiland ? &compiland->symt : NULL;
|
||||
sym->type = type;
|
||||
sym->u.address = addr;
|
||||
sym->u.var.offset = addr;
|
||||
if (type && size && symt_get_info(type, TI_GET_LENGTH, &tsz))
|
||||
{
|
||||
if (tsz != size)
|
||||
|
@ -302,7 +302,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, BOOL regrel, long offset,
|
||||
const struct location* loc,
|
||||
struct symt_block* block,
|
||||
struct symt* type, const char* name)
|
||||
{
|
||||
|
@ -324,10 +324,7 @@ struct symt_data* symt_add_func_local(struct module* module,
|
|||
locsym->kind = dt;
|
||||
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;
|
||||
locsym->u.var = *loc;
|
||||
if (block)
|
||||
p = vector_add(&block->vchildren, &module->pool);
|
||||
else
|
||||
|
@ -481,18 +478,18 @@ 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_rel)
|
||||
if (data->u.var.kind == loc_register)
|
||||
{
|
||||
sym_info->Flags |= SYMFLAG_REGISTER;
|
||||
sym_info->Register = data->u.s.reg_id;
|
||||
sym_info->Register = data->u.var.reg;
|
||||
sym_info->Address = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_REGREL;
|
||||
/* 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;
|
||||
sym_info->Register = data->u.var.reg ? data->u.var.reg : CV_REG_EBP;
|
||||
sym_info->Address = data->u.var.offset;
|
||||
}
|
||||
break;
|
||||
case DataIsGlobal:
|
||||
|
|
|
@ -229,12 +229,11 @@ BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
|
|||
m->hash_elt.name = pool_strdup(&module->pool, name);
|
||||
m->hash_elt.next = NULL;
|
||||
|
||||
m->kind = DataIsMember;
|
||||
m->container = &udt_type->symt;
|
||||
m->type = elt_type;
|
||||
m->u.s.offset = offset;
|
||||
m->u.s.length = ((offset & 7) || (size & 7)) ? size : 0;
|
||||
m->u.s.reg_id = 0;
|
||||
m->kind = DataIsMember;
|
||||
m->container = &udt_type->symt;
|
||||
m->type = elt_type;
|
||||
m->u.member.offset = offset;
|
||||
m->u.member.length = ((offset & 7) || (size & 7)) ? size : 0;
|
||||
p = vector_add(&udt_type->vchildren, &module->pool);
|
||||
*p = &m->symt;
|
||||
|
||||
|
@ -470,7 +469,7 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
{
|
||||
case DataIsGlobal:
|
||||
case DataIsFileStatic:
|
||||
X(ULONG64) = ((const struct symt_data*)type)->u.address;
|
||||
X(ULONG64) = ((const struct symt_data*)type)->u.var.offset;
|
||||
break;
|
||||
default: return FALSE;
|
||||
}
|
||||
|
@ -515,11 +514,11 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
break;
|
||||
|
||||
case TI_GET_BITPOSITION:
|
||||
if (type->tag != SymTagData ||
|
||||
((const struct symt_data*)type)->kind != DataIsMember ||
|
||||
((const struct symt_data*)type)->u.s.length == 0)
|
||||
return FALSE;
|
||||
X(DWORD) = ((const struct symt_data*)type)->u.s.offset & 7;
|
||||
if (type->tag == SymTagData &&
|
||||
((const struct symt_data*)type)->kind == DataIsMember &&
|
||||
((const struct symt_data*)type)->u.member.length != 0)
|
||||
X(DWORD) = ((const struct symt_data*)type)->u.member.offset & 7;
|
||||
else return FALSE;
|
||||
break;
|
||||
|
||||
case TI_GET_CHILDRENCOUNT:
|
||||
|
@ -595,9 +594,9 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
break;
|
||||
case SymTagData:
|
||||
if (((const struct symt_data*)type)->kind != DataIsMember ||
|
||||
!((const struct symt_data*)type)->u.s.length)
|
||||
!((const struct symt_data*)type)->u.member.length)
|
||||
return FALSE;
|
||||
X(DWORD64) = ((const struct symt_data*)type)->u.s.length;
|
||||
X(DWORD64) = ((const struct symt_data*)type)->u.member.length;
|
||||
break;
|
||||
case SymTagArrayType:
|
||||
if (!symt_get_info(((const struct symt_array*)type)->base_type,
|
||||
|
@ -668,8 +667,10 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
{
|
||||
case DataIsParam:
|
||||
case DataIsLocal:
|
||||
X(ULONG) = ((const struct symt_data*)type)->u.var.offset;
|
||||
break;
|
||||
case DataIsMember:
|
||||
X(ULONG) = ((const struct symt_data*)type)->u.s.offset >> 3;
|
||||
X(ULONG) = ((const struct symt_data*)type)->u.member.offset >> 3;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unknown kind (%u) for get-offset\n",
|
||||
|
|
Loading…
Reference in New Issue