Eric Pouech : dbghelp: Added infrastructure to compute variable location at runtime ( as opposed to debug info parse time).

Alexandre Julliard julliard at wine.codeweavers.com
Mon Nov 27 12:51:50 CST 2006


Module: wine
Branch: master
Commit: d812f8b42ccd319615c9961595cf756449bd1288
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d812f8b42ccd319615c9961595cf756449bd1288

Author: Eric Pouech <eric.pouech at wanadoo.fr>
Date:   Fri Nov 24 22:17:47 2006 +0100

dbghelp: 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.

---

 dlls/dbghelp/dbghelp_private.h |    8 +++++-
 dlls/dbghelp/dwarf.c           |   51 ++++++++++++++++++++++++---------------
 dlls/dbghelp/symbol.c          |   39 +++++++++++++++++++++---------
 3 files changed, 65 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..5583413 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;
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-cvs mailing list