Commit 20fc25bc authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: Use the location info structure thoughout the code to handle the…

dbghelp: Use the location info structure thoughout the code to handle the location of a data variable.
parent d5c4e55d
......@@ -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:
......
......@@ -232,9 +232,8 @@ BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
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->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",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment