From 20fc25bc552ce8dc905b93a5bccff715e5cf0513 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Fri, 24 Nov 2006 22:17:38 +0100 Subject: [PATCH] dbghelp: Use the location info structure thoughout the code to handle the location of a data variable. --- dlls/dbghelp/dbghelp_private.h | 26 ++++++++++++----- dlls/dbghelp/dwarf.c | 3 +- dlls/dbghelp/elf_module.c | 8 ++--- dlls/dbghelp/msc.c | 26 +++++++++++++---- dlls/dbghelp/stabs.c | 53 ++++++++++++++++++---------------- dlls/dbghelp/symbol.c | 17 +++++------ dlls/dbghelp/type.c | 31 ++++++++++---------- 7 files changed, 95 insertions(+), 69 deletions(-) diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 6c80060dcfd..d6081bd20aa 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -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* diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c index 6bd0fff31dc..2a40493c2b5 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -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"); diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index 2920ace8563..8ba2287343d 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -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; diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index de83b9e6d79..9554d97b56d 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -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; diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c index f90c62a9de1..6f6c851c62a 100644 --- a/dlls/dbghelp/stabs.c +++ b/dlls/dbghelp/stabs.c @@ -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: /* diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index a3cd0c79206..c6a44c954a1 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -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: diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c index a50448b95d2..83db9eb597a 100644 --- a/dlls/dbghelp/type.c +++ b/dlls/dbghelp/type.c @@ -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",