[PATCH 08/22] [DbgHelp]: variable location computation at runtime

Eric Pouech eric.pouech at wanadoo.fr
Fri Nov 24 15:17:47 CST 2006


- added infrastructure to compute variable location
  at runtime (as opposed to debug info parse time)
- use it to send the variables depending on not
  known frame register at parse time
- made just a stub for the location computation function
  for dwarf2

A+
---

 dlls/dbghelp/dbghelp_private.h |    8 +++++-
 dlls/dbghelp/dwarf.c           |   52 +++++++++++++++++++++++++---------------
 dlls/dbghelp/symbol.c          |   39 +++++++++++++++++++++---------
 3 files changed, 66 insertions(+), 33 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index d6081bd..fbf9879 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -305,6 +305,8 @@ enum module_type
     DMT_PDB,            /* PDB file */
 };
 
+struct process;
+
 struct module
 {
     IMAGEHLP_MODULE64           module;
@@ -317,10 +319,14 @@ struct module
     /* memory allocation pool */
     struct pool                 pool;
 
-    /* symbol tables */
+    /* symbols & symbol tables */
     int                         sortlist_valid;
     struct symt_ht**            addr_sorttab;
     struct hash_table           ht_symbols;
+    void                        (*loc_compute)(struct process* pcs,
+                                               const struct module* module,
+                                               const struct symt_function* func,
+                                               struct location* loc);
 
     /* types */
     struct hash_table           ht_types;
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 2a40493..80d5272 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -721,7 +721,6 @@ static BOOL compute_location(dwarf2_trav
             break;
         default:
             FIXME("Unhandled attr op: %x\n", op);
-            loc->offset = 0;
             return FALSE;
         }
     }
@@ -764,7 +763,19 @@ static BOOL dwarf2_compute_location_attr
         lctx.end_data = xloc.u.block.ptr + xloc.u.block.size;
         lctx.word_size = ctx->word_size;
 
-        compute_location(&lctx, loc, frame);
+        if (!compute_location(&lctx, loc, frame))
+        {
+            loc->kind = loc_error;
+            loc->reg = loc_err_too_complex;
+        }
+        else if (loc->kind == loc_dwarf2_block)
+        {
+            unsigned*   ptr = pool_alloc(&ctx->module->pool,
+                                         sizeof(unsigned) + xloc.u.block.size);
+            *ptr = xloc.u.block.size;
+            memcpy(ptr + 1, xloc.u.block.ptr, xloc.u.block.size);
+            loc->offset = (unsigned long)ptr;
+        }
     }
     return TRUE;
 }
@@ -1216,23 +1227,10 @@ static void dwarf2_parse_variable(dwarf2
     {
         struct attribute ext;
 
-        if (loc.kind >= loc_user)
-        {
-            FIXME("Unsupported yet location list in %s on variable %s\n",
-                  subpgm->func->hash_elt.name, name.u.string);
-            return;
-        }
-
-        if (subpgm->frame.kind >= loc_user)
-        {
-            FIXME("Unsupported yet location list in %s on frame for var %s\n",
-                  subpgm->func->hash_elt.name, name.u.string);
-            return;
-        }
-
-	TRACE("found parameter %s/%ld (reg=%d) at %s\n",
-              name.u.string, loc.offset, loc.reg,
+	TRACE("found parameter %s (kind=%d, offset=%ld, reg=%d) at %s\n",
+              name.u.string, loc.kind, loc.offset, loc.reg,
               dwarf2_debug_ctx(subpgm->ctx));
+
         switch (loc.kind)
         {
         case loc_absolute:
@@ -1245,6 +1243,8 @@ static void dwarf2_parse_variable(dwarf2
                                      subpgm->ctx->module->module.BaseOfImage + loc.offset,
                                      0, param_type);
             break;
+        default:
+            /* fall through */
         case loc_register:
         case loc_regrel:
             /* either a pmt/variable relative to frame pointer or
@@ -1255,8 +1255,6 @@ static void dwarf2_parse_variable(dwarf2
                                 is_pmt ? DataIsParam : DataIsLocal,
                                 &loc, block, param_type, name.u.string);
             break;
-        default:
-            FIXME("Unsupported\n");
         }
     }
     if (dwarf2_find_attribute(subpgm->ctx, di, DW_AT_const_value, &value))
@@ -1893,6 +1891,17 @@ static BOOL dwarf2_parse_compilation_uni
     return ret;
 }
 
+static void dwarf2_location_compute(struct process* pcs,
+                                    const struct module* module,
+                                    const struct symt_function* func,
+                                    struct location* loc)
+{
+    FIXME("Not implemented yet\n");
+    loc->kind = loc_register;
+    loc->reg = -1;
+    loc->offset = 0;
+}
+
 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
                   const struct elf_thunk_area* thunks,
 		  const unsigned char* debug, unsigned int debug_size,
@@ -1906,6 +1915,8 @@ BOOL dwarf2_parse(struct module* module,
     const unsigned char*comp_unit_cursor = debug;
     const unsigned char*end_debug = debug + debug_size;
 
+    module->loc_compute = dwarf2_location_compute;
+
     section[section_debug].address = debug;
     section[section_debug].size = debug_size;
     section[section_abbrev].address = abbrev;
@@ -1953,3 +1964,4 @@ BOOL dwarf2_parse(struct module* module,
     module->module.Publics = TRUE;
     return TRUE;
 }
+
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index c6a44c9..8e1cdf4 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -477,19 +477,34 @@ static void symt_fill_sym_info(const str
             case DataIsParam:
                 sym_info->Flags |= SYMFLAG_PARAMETER;
                 /* fall through */
-            case DataIsLocal: 
-                if (data->u.var.kind == loc_register)
+            case DataIsLocal:
                 {
-                    sym_info->Flags |= SYMFLAG_REGISTER;
-                    sym_info->Register = data->u.var.reg;
-                    sym_info->Address = 0;
-                }
-                else
-                {
-                    sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_REGREL;
-                    /* FIXME: it's i386 dependent !!! */
-                    sym_info->Register = data->u.var.reg ? data->u.var.reg : CV_REG_EBP;
-                    sym_info->Address = data->u.var.offset;
+                    struct location loc = data->u.var;
+
+                    if (loc.kind >= loc_user)
+                        pair->effective->loc_compute(pair->pcs, pair->effective, func, &loc);
+
+                    switch (loc.kind)
+                    {
+                    case loc_error:
+                        /* for now we report error cases as a negative register number */
+                        sym_info->Flags |= SYMFLAG_LOCAL;
+                        /* fall through */
+                    case loc_register:
+                        sym_info->Flags |= SYMFLAG_REGISTER;
+                        sym_info->Register = loc.reg;
+                        sym_info->Address = 0;
+                        break;
+                    case loc_regrel:
+                        sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_REGREL;
+                        /* FIXME: it's i386 dependent !!! */
+                        sym_info->Register = loc.reg ? loc.reg : CV_REG_EBP;
+                        sym_info->Address = loc.offset;
+                        break;
+                    default:
+                        FIXME("Shouldn't happen (kind=%d), debug reader backend is broken\n", loc.kind);
+                        assert(0);
+                    }
                 }
                 break;
             case DataIsGlobal:



More information about the wine-patches mailing list