[PATCH 3/4] [DbgHelp]: const values
Eric Pouech
eric.pouech at wanadoo.fr
Tue Dec 5 15:13:30 CST 2006
- 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
A+
---
dlls/dbghelp/dbghelp_private.h | 6 ++++
dlls/dbghelp/dwarf.c | 46 +++++++++++++++++++++++++++++++++-
dlls/dbghelp/msc.c | 48 ++++++++++++++++--------------------
dlls/dbghelp/symbol.c | 54 ++++++++++++++++++++++++++++++++++------
4 files changed, 118 insertions(+), 36 deletions(-)
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 9c6abc0..83c549d 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -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);
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index a3af469..556518f 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -46,6 +46,9 @@ #include "windef.h"
#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
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,
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index b284695..f2636b3 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1527,58 +1527,54 @@ static int codeview_snarf(const struct m
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;
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index b9e2f2a..0122fb1 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -447,6 +447,36 @@ struct symt_thunk* symt_new_thunk(struct
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,
const struct symt_function* func,
@@ -523,8 +553,11 @@ static void symt_fill_sym_info(const str
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;
+ 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 modu
*/
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.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
* 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
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->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++;
More information about the wine-patches
mailing list