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