diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index 9c6abc01cf9..83c549d59d7 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 a3af4696c92..e8f9d3e0cb5 100644 --- a/dlls/dbghelp/dwarf.c +++ b/dlls/dbghelp/dwarf.c @@ -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, diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c index 6ff13d16d3d..624220c3c3b 100644 --- a/dlls/dbghelp/msc.c +++ b/dlls/dbghelp/msc.c @@ -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; diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index b9e2f2a79c4..44859602331 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -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++;