dbghelp: Added support for variables in thread storage.
This commit is contained in:
parent
5b4e192aca
commit
031cce8e77
|
@ -342,6 +342,8 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
|
|||
coff_sym->SectionNumber > 0)
|
||||
{
|
||||
DWORD base = msc_dbg->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
|
||||
struct location loc;
|
||||
|
||||
/*
|
||||
* Similar to above, but for the case of data symbols.
|
||||
* These aren't treated as entrypoints.
|
||||
|
@ -356,9 +358,11 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
|
|||
/*
|
||||
* Now we need to figure out which file this guy belongs to.
|
||||
*/
|
||||
loc.kind = loc_absolute;
|
||||
loc.reg = 0;
|
||||
loc.offset = msc_dbg->module->module.BaseOfImage + base + coff_sym->Value;
|
||||
symt_new_global_variable(msc_dbg->module, NULL, nampnt, TRUE /* FIXME */,
|
||||
msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
|
||||
0 /* FIXME */, NULL /* FIXME */);
|
||||
loc, 0 /* FIXME */, NULL /* FIXME */);
|
||||
i += naux;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ enum location_kind {loc_error, /* reg is the error code */
|
|||
loc_absolute, /* offset is the location */
|
||||
loc_register, /* reg is the location */
|
||||
loc_regrel, /* [reg+offset] is the location */
|
||||
loc_tlsrel, /* offset is the address of the TLS index */
|
||||
loc_user, /* value is debug information dependent,
|
||||
reg & offset can be used ad libidem */
|
||||
};
|
||||
|
@ -182,8 +183,9 @@ struct symt_data
|
|||
union /* depends on kind */
|
||||
{
|
||||
/* DataIs{Global, FileStatic}:
|
||||
* loc.kind is loc_absolute
|
||||
* loc.offset is address
|
||||
* with loc.kind
|
||||
* loc_absolute loc.offset is address
|
||||
* loc_tlsrel loc.offset is TLS index address
|
||||
* DataIs{Local,Param}:
|
||||
* with loc.kind
|
||||
* loc_absolute not supported
|
||||
|
@ -634,7 +636,7 @@ extern struct symt_data*
|
|||
symt_new_global_variable(struct module* module,
|
||||
struct symt_compiland* parent,
|
||||
const char* name, unsigned is_static,
|
||||
unsigned long addr, unsigned long size,
|
||||
struct location loc, unsigned long size,
|
||||
struct symt* type);
|
||||
extern struct symt_function*
|
||||
symt_new_function(struct module* module,
|
||||
|
|
|
@ -1486,10 +1486,10 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
|
|||
/* FIXME: we don't handle its scope yet */
|
||||
if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_external, &ext))
|
||||
ext.u.uvalue = 0;
|
||||
loc.offset += subpgm->ctx->load_offset;
|
||||
symt_new_global_variable(subpgm->ctx->module, subpgm->compiland,
|
||||
name.u.string, !ext.u.uvalue,
|
||||
subpgm->ctx->load_offset + loc.offset,
|
||||
0, param_type);
|
||||
loc, 0, param_type);
|
||||
break;
|
||||
default:
|
||||
subpgm->non_computed_variable = TRUE;
|
||||
|
|
|
@ -668,7 +668,8 @@ static void elf_finish_stabs_info(struct module* module, const struct hash_table
|
|||
{
|
||||
case DataIsGlobal:
|
||||
case DataIsFileStatic:
|
||||
if (((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr)
|
||||
if (((struct symt_data*)sym)->u.var.kind != loc_absolute ||
|
||||
((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr)
|
||||
break;
|
||||
symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
|
||||
((struct symt_data*)sym)->container);
|
||||
|
@ -728,6 +729,7 @@ static int elf_new_wine_thunks(struct module* module, const struct hash_table* h
|
|||
else
|
||||
{
|
||||
ULONG64 ref_addr;
|
||||
struct location loc;
|
||||
|
||||
symt = symt_find_nearest(module, addr);
|
||||
if (symt && !symt_get_info(module, &symt->symt, TI_GET_ADDRESS, &ref_addr))
|
||||
|
@ -745,9 +747,12 @@ static int elf_new_wine_thunks(struct module* module, const struct hash_table* h
|
|||
addr, ste->symp->st_size, NULL);
|
||||
break;
|
||||
case STT_OBJECT:
|
||||
loc.kind = loc_absolute;
|
||||
loc.reg = 0;
|
||||
loc.offset = addr;
|
||||
symt_new_global_variable(module, ste->compiland, ste->ht_elt.name,
|
||||
ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL,
|
||||
addr, ste->symp->st_size, NULL);
|
||||
loc, ste->symp->st_size, NULL);
|
||||
break;
|
||||
default:
|
||||
FIXME("Shouldn't happen\n");
|
||||
|
|
|
@ -818,8 +818,13 @@ static void macho_finish_stabs(struct module* module, struct hash_table* ht_symt
|
|||
}
|
||||
else
|
||||
{
|
||||
struct location loc;
|
||||
|
||||
loc.kind = loc_absolute;
|
||||
loc.reg = 0;
|
||||
loc.offset = ste->addr;
|
||||
symt_new_global_variable(module, ste->compiland, ste->ht_elt.name,
|
||||
!ste->is_global, ste->addr, 0, NULL);
|
||||
!ste->is_global, loc, 0, NULL);
|
||||
}
|
||||
|
||||
ste->used = 1;
|
||||
|
|
|
@ -1528,11 +1528,15 @@ static inline void codeview_add_variable(const struct msc_debug_info* msc_dbg,
|
|||
if (name && *name)
|
||||
{
|
||||
unsigned long address = codeview_get_address(msc_dbg, segment, offset);
|
||||
struct location loc;
|
||||
|
||||
loc.kind = loc_absolute;
|
||||
loc.reg = 0;
|
||||
loc.offset = address;
|
||||
if (force || !symt_find_nearest(msc_dbg->module, address))
|
||||
{
|
||||
symt_new_global_variable(msc_dbg->module, compiland,
|
||||
name, is_local, address, 0,
|
||||
name, is_local, loc, 0,
|
||||
codeview_get_type(symtype, FALSE));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -376,6 +376,7 @@ static BOOL pe_locate_with_coff_symbol_table(struct module* module)
|
|||
sym = GET_ENTRY(ptr, struct symt_data, hash_elt);
|
||||
if (sym->symt.tag == SymTagData &&
|
||||
(sym->kind == DataIsGlobal || sym->kind == DataIsFileStatic) &&
|
||||
sym->u.var.kind == loc_absolute &&
|
||||
!strcmp(sym->hash_elt.name, name))
|
||||
{
|
||||
TRACE("Changing absolute address for %d.%s: %lx -> %s\n",
|
||||
|
|
|
@ -1381,17 +1381,21 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
|||
* With a.out or mingw, they actually do make some amount of sense.
|
||||
*/
|
||||
stab_strcpy(symname, sizeof(symname), ptr);
|
||||
loc.kind = loc_absolute;
|
||||
loc.reg = 0;
|
||||
loc.offset = load_offset + stab_ptr->n_value;
|
||||
symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
|
||||
load_offset + stab_ptr->n_value, 0,
|
||||
stabs_parse_type(ptr));
|
||||
loc, 0, stabs_parse_type(ptr));
|
||||
break;
|
||||
case N_LCSYM:
|
||||
case N_STSYM:
|
||||
/* These are static symbols and BSS symbols. */
|
||||
stab_strcpy(symname, sizeof(symname), ptr);
|
||||
loc.kind = loc_absolute;
|
||||
loc.reg = 0;
|
||||
loc.offset = load_offset + stab_ptr->n_value;
|
||||
symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
|
||||
load_offset + stab_ptr->n_value, 0,
|
||||
stabs_parse_type(ptr));
|
||||
loc, 0, stabs_parse_type(ptr));
|
||||
break;
|
||||
case N_LBRAC:
|
||||
if (curr_func)
|
||||
|
|
|
@ -334,15 +334,15 @@ struct symt_public* symt_new_public(struct module* module,
|
|||
struct symt_data* symt_new_global_variable(struct module* module,
|
||||
struct symt_compiland* compiland,
|
||||
const char* name, unsigned is_static,
|
||||
unsigned long addr, unsigned long size,
|
||||
struct location loc, unsigned long size,
|
||||
struct symt* type)
|
||||
{
|
||||
struct symt_data* sym;
|
||||
struct symt** p;
|
||||
DWORD64 tsz;
|
||||
|
||||
TRACE_(dbghelp_symt)("Adding global symbol %s:%s @%lx %p\n",
|
||||
debugstr_w(module->module.ModuleName), name, addr, type);
|
||||
TRACE_(dbghelp_symt)("Adding global symbol %s:%s %d@%lx %p\n",
|
||||
debugstr_w(module->module.ModuleName), name, loc.kind, loc.offset, type);
|
||||
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
|
||||
{
|
||||
sym->symt.tag = SymTagData;
|
||||
|
@ -350,7 +350,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.var.offset = addr;
|
||||
sym->u.var = loc;
|
||||
if (type && size && symt_get_info(module, type, TI_GET_LENGTH, &tsz))
|
||||
{
|
||||
if (tsz != size)
|
||||
|
@ -736,8 +736,19 @@ static void symt_fill_sym_info(struct module_pair* pair,
|
|||
break;
|
||||
case DataIsGlobal:
|
||||
case DataIsFileStatic:
|
||||
symt_get_info(pair->effective, sym, TI_GET_ADDRESS, &sym_info->Address);
|
||||
sym_info->Register = 0;
|
||||
switch (data->u.var.kind)
|
||||
{
|
||||
case loc_tlsrel:
|
||||
sym_info->Flags |= SYMFLAG_TLSREL;
|
||||
/* fall through */
|
||||
case loc_absolute:
|
||||
symt_get_info(pair->effective, sym, TI_GET_ADDRESS, &sym_info->Address);
|
||||
sym_info->Register = 0;
|
||||
break;
|
||||
default:
|
||||
FIXME("Shouldn't happen (kind=%d), debug reader backend is broken\n", data->u.var.kind);
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
case DataIsConstant:
|
||||
sym_info->Flags |= SYMFLAG_VALUEPRESENT;
|
||||
|
|
Loading…
Reference in New Issue