Commit 031cce8e authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: Added support for variables in thread storage.

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