dbghelp: Added support for variables in thread storage.

This commit is contained in:
Eric Pouech 2011-01-29 20:38:04 +01:00 committed by Alexandre Julliard
parent 5b4e192aca
commit 031cce8e77
9 changed files with 57 additions and 21 deletions

View File

@ -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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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));
}
}

View File

@ -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",

View File

@ -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)

View File

@ -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;