[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