dbghelp: Added ability to internal store / reload a symbol with a constant value.

Let dwarf and msc use this new feature.
As we also add global symbol without addresses, don't take those
constant symbols into account for searches by address.
This commit is contained in:
Eric Pouech 2006-12-05 22:13:30 +01:00 committed by Alexandre Julliard
parent a1a879363d
commit 75033503e8
4 changed files with 123 additions and 41 deletions

View File

@ -322,6 +322,7 @@ struct module
/* symbols & symbol tables */
int sortlist_valid;
unsigned num_sorttab; /* number of symbols with addresses */
struct symt_ht** addr_sorttab;
struct hash_table ht_symbols;
void (*loc_compute)(struct process* pcs,
@ -544,6 +545,11 @@ extern struct symt_thunk*
struct symt_compiland* parent,
const char* name, THUNK_ORDINAL ord,
unsigned long addr, unsigned long size);
extern struct symt_data*
symt_new_constant(struct module* module,
struct symt_compiland* parent,
const char* name, struct symt* type,
const VARIANT* v);
/* type.c */
extern void symt_init_basic(struct module* module);

View File

@ -46,6 +46,9 @@
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "winuser.h"
#include "ole2.h"
#include "oleauto.h"
#include "dbghelp_private.h"
@ -1313,9 +1316,48 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
break;
}
}
if (dwarf2_find_attribute(subpgm->ctx, di, DW_AT_const_value, &value))
else if (dwarf2_find_attribute(subpgm->ctx, di, DW_AT_const_value, &value))
{
FIXME("NIY: const value %08lx for %s\n", value.u.uvalue, name.u.string);
VARIANT v;
if (subpgm->func) FIXME("Unsupported constant %s in function\n", name.u.string);
if (is_pmt) FIXME("Unsupported constant (parameter) %s in function\n", name.u.string);
switch (value.form)
{
case DW_FORM_data1:
case DW_FORM_data2:
case DW_FORM_data4:
case DW_FORM_udata:
v.n1.n2.vt = VT_UI4;
v.n1.n2.n3.lVal = value.u.uvalue;
break;
case DW_FORM_sdata:
v.n1.n2.vt = VT_I4;
v.n1.n2.n3.lVal = value.u.svalue;
break;
case DW_FORM_strp:
case DW_FORM_string:
/* FIXME: native doesn't report const strings from here !!
* however, the value of the string is in the code somewhere
*/
v.n1.n2.vt = VT_I1 | VT_BYREF;
v.n1.n2.n3.byref = pool_strdup(&subpgm->ctx->module->pool, value.u.string);
break;
case DW_FORM_data8:
case DW_FORM_block:
case DW_FORM_block1:
case DW_FORM_block2:
case DW_FORM_block4:
default:
FIXME("Unsupported form for const value %s (%lx)\n",
name.u.string, value.form);
v.n1.n2.vt = VT_EMPTY;
}
di->symt = &symt_new_constant(subpgm->ctx->module, subpgm->compiland,
name.u.string, param_type, &v)->symt;
}
if (is_pmt && subpgm->func && subpgm->func->type)
symt_add_function_signature_parameter(subpgm->ctx->module,

View File

@ -1521,58 +1521,54 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
case S_CONSTANT_V1:
{
int val, vlen;
int vlen;
const struct p_string* name;
const char* x;
struct symt* se;
VARIANT v;
vlen = numeric_leaf(&val, &sym->constant_v1.cvalue);
v.n1.n2.vt = VT_I4;
vlen = numeric_leaf(&v.n1.n2.n3.intVal, &sym->constant_v1.cvalue);
name = (const struct p_string*)((const char*)&sym->constant_v1.cvalue + vlen);
se = codeview_get_type(sym->constant_v1.type, FALSE);
if (!se) x = "---";
else if (se->tag == SymTagEnum) x = ((struct symt_enum*)se)->name;
else x = "###";
TRACE("S-Constant-V1 %u %s %x (%s)\n",
val, terminate_string(name), sym->constant_v1.type, x);
/* FIXME: we should add this as a constant value */
TRACE("S-Constant-V1 %u %s %x\n",
v.n1.n2.n3.intVal, terminate_string(name), sym->constant_v1.type);
symt_new_constant(msc_dbg->module, compiland, terminate_string(name),
se, &v);
}
break;
case S_CONSTANT_V2:
{
int val, vlen;
int vlen;
const struct p_string* name;
const char* x;
struct symt* se;
VARIANT v;
vlen = numeric_leaf(&val, &sym->constant_v2.cvalue);
v.n1.n2.vt = VT_I4;
vlen = numeric_leaf(&v.n1.n2.n3.intVal, &sym->constant_v2.cvalue);
name = (const struct p_string*)((const char*)&sym->constant_v2.cvalue + vlen);
se = codeview_get_type(sym->constant_v2.type, FALSE);
if (!se) x = "---";
else if (se->tag == SymTagEnum) x = ((struct symt_enum*)se)->name;
else x = "###";
TRACE("S-Constant-V2 %u %s %x (%s)\n",
val, terminate_string(name), sym->constant_v2.type, x);
/* FIXME: we should add this as a constant value */
TRACE("S-Constant-V2 %u %s %x\n",
v.n1.n2.n3.intVal, terminate_string(name), sym->constant_v2.type);
symt_new_constant(msc_dbg->module, compiland, terminate_string(name),
se, &v);
}
break;
case S_CONSTANT_V3:
{
int val, vlen;
int vlen;
const char* name;
const char* x;
struct symt* se;
VARIANT v;
vlen = numeric_leaf(&val, &sym->constant_v3.cvalue);
v.n1.n2.vt = VT_I4;
vlen = numeric_leaf(&v.n1.n2.n3.intVal, &sym->constant_v3.cvalue);
name = (const char*)&sym->constant_v3.cvalue + vlen;
se = codeview_get_type(sym->constant_v3.type, FALSE);
if (!se) x = "---";
else if (se->tag == SymTagEnum) x = ((struct symt_enum*)se)->name;
else x = "###";
TRACE("S-Constant-V3 %u %s %x (%s)\n",
val, name, sym->constant_v3.type, x);
TRACE("S-Constant-V3 %u %s %x\n",
v.n1.n2.n3.intVal, name, sym->constant_v3.type);
/* FIXME: we should add this as a constant value */
}
break;

View File

@ -447,8 +447,38 @@ struct symt_thunk* symt_new_thunk(struct module* module,
return sym;
}
struct symt_data* symt_new_constant(struct module* module,
struct symt_compiland* compiland,
const char* name, struct symt* type,
const VARIANT* v)
{
struct symt_data* sym;
TRACE_(dbghelp_symt)("Adding constant value %s:%s\n",
module->module.ModuleName, name);
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
{
sym->symt.tag = SymTagData;
sym->hash_elt.name = pool_strdup(&module->pool, name);
hash_table_add(&module->ht_symbols, &sym->hash_elt);
module->sortlist_valid = FALSE;
sym->kind = DataIsConstant;
sym->container = compiland ? &compiland->symt : NULL;
sym->type = type;
sym->u.value = *v;
if (compiland)
{
struct symt** p;
p = vector_add(&compiland->vchildren, &module->pool);
*p = &sym->symt;
}
}
return sym;
}
/* expect sym_info->MaxNameLen to be set before being called */
static void symt_fill_sym_info(const struct module_pair* pair,
static void symt_fill_sym_info(const struct module_pair* pair,
const struct symt_function* func,
const struct symt* sym, SYMBOL_INFO* sym_info)
{
@ -523,8 +553,11 @@ static void symt_fill_sym_info(const struct module_pair* pair,
case VT_UI4: sym_info->Value = (ULONG)data->u.value.n1.n2.n3.ulVal; break;
case VT_UI2: sym_info->Value = (ULONG)data->u.value.n1.n2.n3.uiVal; break;
case VT_UI1: sym_info->Value = (ULONG)data->u.value.n1.n2.n3.bVal; break;
default:
case VT_I1 | VT_BYREF: sym_info->Value = (ULONG)data->u.value.n1.n2.n3.byref; break;
default:
FIXME("Unsupported variant type (%u)\n", data->u.value.n1.n2.vt);
sym_info->Value = 0;
break;
}
break;
default:
@ -618,10 +651,10 @@ static BOOL symt_enum_module(struct module_pair* pair, regex_t* regex,
*/
static BOOL resort_symbols(struct module* module)
{
int nsym;
void* ptr;
struct symt_ht* sym;
struct hash_table_iter hti;
ULONG64 addr;
if (!(module->module.NumSyms = module->ht_symbols.num_elts))
return FALSE;
@ -635,16 +668,21 @@ static BOOL resort_symbols(struct module* module)
module->module.NumSyms * sizeof(struct symt_ht*));
if (!module->addr_sorttab) return FALSE;
nsym = 0;
module->num_sorttab = 0;
hash_table_iter_init(&module->ht_symbols, &hti, NULL);
while ((ptr = hash_table_iter_up(&hti)))
{
sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
assert(sym);
module->addr_sorttab[nsym++] = sym;
/* Don't store in sorttab symbol without address, they are of
* no use here (e.g. constant values)
* As the number of those symbols is very couple (a couple per module)
* we don't bother for the unused spots at the end of addr_sorttab
*/
if (symt_get_info(&sym->symt, TI_GET_ADDRESS, &addr))
module->addr_sorttab[module->num_sorttab++] = sym;
}
qsort(module->addr_sorttab, nsym, sizeof(struct symt_ht*), symt_cmp_addr);
qsort(module->addr_sorttab, module->num_sorttab, sizeof(struct symt_ht*), symt_cmp_addr);
return module->sortlist_valid = TRUE;
}
@ -663,7 +701,7 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD addr)
* Binary search to find closest symbol.
*/
low = 0;
high = module->module.NumSyms;
high = module->num_sorttab;
symt_get_info(&module->addr_sorttab[0]->symt, TI_GET_ADDRESS, &ref_addr);
if (addr < ref_addr) return NULL;
@ -683,7 +721,7 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD addr)
else
high = mid;
}
if (low != high && high != module->module.NumSyms &&
if (low != high && high != module->num_sorttab &&
cmp_sorttab_addr(module, high, addr) <= 0)
low = high;
@ -697,7 +735,7 @@ struct symt_ht* symt_find_nearest(struct module* module, DWORD addr)
module->addr_sorttab[low - 1]->symt.tag != SymTagPublicSymbol &&
!cmp_sorttab_addr(module, low - 1, ref_addr))
low--;
else if (low < module->module.NumSyms - 1 &&
else if (low < module->num_sorttab - 1 &&
module->addr_sorttab[low + 1]->symt.tag != SymTagPublicSymbol &&
!cmp_sorttab_addr(module, low + 1, ref_addr))
low++;