[PATCH 1/6] [DbgHelp]: variables & registers

Eric Pouech eric.pouech at wanadoo.fr
Mon Sep 25 15:40:41 CDT 2006


- more strickling differentiation variable location between 
  a register, and the dereferenced address defined by a
  register (and possibly an offset)
- added a parameter to symt_add_func_local (and internal symbol
  data struct) to help differentiate
- fix all debug parsers to confer to this new scheme

A+
---

 dlls/dbghelp/dbghelp_private.h |    5 +++--
 dlls/dbghelp/dwarf.c           |   16 +++++++++-------
 dlls/dbghelp/msc.c             |   14 +++++++-------
 dlls/dbghelp/stabs.c           |   20 +++++++++++---------
 dlls/dbghelp/symbol.c          |    9 +++++----
 5 files changed, 35 insertions(+), 29 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 72930ba..2dff1f0 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -155,7 +155,8 @@ struct symt_data
         {
             long                        offset; /* DataIs{Member,Local,Param} in bits */
             unsigned long               length; /* DataIs{Member} in bits */
-            unsigned long               reg_id; /* DataIs{Local} (0 if frame relative) */
+            unsigned long               reg_rel : 1, /* DataIs{Local}: 0 in register, 1 deref */
+                                        reg_id; /* DataIs{Local} (0 if frame relative) */
         } s;
         VARIANT                 value;          /* DataIsConstant */
     } u;
@@ -472,7 +473,7 @@ extern void         symt_add_func_line(s
 extern struct symt_data*
                     symt_add_func_local(struct module* module, 
                                         struct symt_function* func, 
-                                        enum DataKind dt, int regno, long offset,
+                                        enum DataKind dt, BOOL regrel, int regno, long offset,
                                         struct symt_block* block,
                                         struct symt* type, const char* name);
 extern struct symt_block*
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index e129d99..114f781 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -499,8 +499,9 @@ static void dwarf2_find_name(dwarf2_pars
 static void dwarf2_load_one_entry(dwarf2_parse_context_t*, dwarf2_debug_info_t*,
                                   struct symt_compiland*);
 
-#define Wine_DW_no_register     -1
-#define Wine_DW_frame_register  -2
+#define Wine_DW_no_register     0x7FFFFFFF
+#define Wine_DW_frame_register  0x7FFFFFFE
+#define Wine_DW_register_deref  0x80000000
 
 static unsigned long dwarf2_compute_location(dwarf2_parse_context_t* ctx,
                                              struct dwarf2_block* block,
@@ -567,7 +568,7 @@ static unsigned long dwarf2_compute_loca
                 {
                     if (*in_register != Wine_DW_no_register)
                         FIXME("Only supporting one reg (%d -> -2)\n", *in_register);
-                    *in_register = Wine_DW_frame_register;
+                    *in_register = Wine_DW_frame_register | Wine_DW_register_deref;
                 }
                 else FIXME("Found register, while not expecting it\n");
                 loc[++stk] = dwarf2_leb128_as_signed(&lctx);
@@ -1066,7 +1067,7 @@ static void dwarf2_parse_variable(dwarf2
         offset = dwarf2_compute_location(subpgm->ctx, loc.block, &in_reg);
 	TRACE("found parameter %s/%ld (reg=%d) at %s\n",
               name.string, offset, in_reg, dwarf2_debug_ctx(subpgm->ctx));
-        switch (in_reg)
+        switch (in_reg & ~Wine_DW_register_deref)
         {
         case Wine_DW_no_register:
             /* it's a global variable */
@@ -1079,7 +1080,7 @@ static void dwarf2_parse_variable(dwarf2
                                      0, param_type);
             break;
         case Wine_DW_frame_register:
-            in_reg = subpgm->frame_reg;
+            in_reg = subpgm->frame_reg | Wine_DW_register_deref;
             offset += subpgm->frame_offset;
             /* fall through */
         default:
@@ -1088,8 +1089,9 @@ static void dwarf2_parse_variable(dwarf2
              */
             symt_add_func_local(subpgm->ctx->module, subpgm->func, 
                                 is_pmt ? DataIsParam : DataIsLocal,
-                                dwarf2_map_register(in_reg), offset,
-                                block, param_type, name.string);
+                                dwarf2_map_register(in_reg & ~Wine_DW_register_deref),
+                                in_reg & Wine_DW_register_deref,
+                                offset, block, param_type, name.string);
             break;
         }
     }
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 85d191f..544a5f3 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1380,34 +1380,34 @@ static int codeview_snarf(const struct m
 	case S_BPREL_V1:
             symt_add_func_local(msc_dbg->module, curr_func, 
                                 sym->stack_v1.offset > 0 ? DataIsParam : DataIsLocal, 
-                                0, sym->stack_v1.offset, block,
-                                         codeview_get_type(sym->stack_v1.symtype, FALSE),
-                                         terminate_string(&sym->stack_v1.p_name));
+                                0, TRUE, sym->stack_v1.offset, block,
+                                codeview_get_type(sym->stack_v1.symtype, FALSE),
+                                terminate_string(&sym->stack_v1.p_name));
             break;
 	case S_BPREL_V2:
             symt_add_func_local(msc_dbg->module, curr_func, 
                                 sym->stack_v2.offset > 0 ? DataIsParam : DataIsLocal, 
-                                0, sym->stack_v2.offset, block,
+                                0, TRUE, sym->stack_v2.offset, block,
                                 codeview_get_type(sym->stack_v2.symtype, FALSE),
                                 terminate_string(&sym->stack_v2.p_name));
             break;
 	case S_BPREL_V3:
             symt_add_func_local(msc_dbg->module, curr_func, 
                                 sym->stack_v3.offset > 0 ? DataIsParam : DataIsLocal, 
-                                0, sym->stack_v3.offset, block,
+                                0, TRUE, sym->stack_v3.offset, block,
                                 codeview_get_type(sym->stack_v3.symtype, FALSE),
                                 sym->stack_v3.name);
             break;
 
         case S_REGISTER_V1:
             symt_add_func_local(msc_dbg->module, curr_func, 
-                                DataIsLocal, sym->register_v1.reg, 0,
+                                DataIsLocal, sym->register_v1.reg, FALSE, 0,
                                 block, codeview_get_type(sym->register_v1.type, FALSE),
                                 terminate_string(&sym->register_v1.p_name));
             break;
         case S_REGISTER_V2:
             symt_add_func_local(msc_dbg->module, curr_func, 
-                                DataIsLocal, sym->register_v2.reg, 0,
+                                DataIsLocal, sym->register_v2.reg, FALSE, 0,
                                 block, codeview_get_type(sym->register_v2.type, FALSE),
                                 terminate_string(&sym->register_v2.p_name));
             break;
diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c
index 534e1b0..57aa82f 100644
--- a/dlls/dbghelp/stabs.c
+++ b/dlls/dbghelp/stabs.c
@@ -1091,7 +1091,8 @@ struct pending_loc_var
     struct symt*        type;
     enum DataKind       kind;
     unsigned            offset;
-    unsigned            regno;
+    unsigned            regrel : 1,
+                        regno;
 };
 
 struct pending_block
@@ -1102,7 +1103,7 @@ struct pending_block
 };
 
 static inline void pending_add(struct pending_block* pending, const char* name,
-                               enum DataKind dt, int regno, long offset)
+                               enum DataKind dt, int regno, BOOL regrel, long offset)
 {
     if (pending->num == pending->allocated)
     {
@@ -1120,6 +1121,7 @@ static inline void pending_add(struct pe
     pending->vars[pending->num].kind   = dt;
     pending->vars[pending->num].offset = offset;
     pending->vars[pending->num].regno  = regno;
+    pending->vars[pending->num].regrel = regrel ? 1 : 0;
     pending->num++;
 }
 
@@ -1131,9 +1133,9 @@ static void pending_flush(struct pending
     for (i = 0; i < pending->num; i++)
     {
         symt_add_func_local(module, func, 
-                            pending->vars[i].kind, pending->vars[i].regno, 
-                            pending->vars[i].offset, block,
-                            pending->vars[i].type, pending->vars[i].name);
+                            pending->vars[i].kind, pending->vars[i].regno,
+                            pending->vars[i].regrel, pending->vars[i].offset,
+                            block, pending->vars[i].type, pending->vars[i].name);
     }
     pending->num = 0;
 }
@@ -1311,7 +1313,7 @@ BOOL stabs_parse(struct module* module, 
                 stab_strcpy(symname, sizeof(symname), ptr);
                 symt_add_func_local(module, curr_func,
                                     stab_ptr->n_value > 0 ? DataIsParam : DataIsLocal,
-                                    0, stab_ptr->n_value, NULL, param_type, symname);
+                                    0, TRUE, stab_ptr->n_value, NULL, param_type, symname);
                 symt_add_function_signature_parameter(module, 
                                                       (struct symt_function_signature*)curr_func->type, 
                                                       param_type);
@@ -1352,19 +1354,19 @@ BOOL stabs_parse(struct module* module, 
                 {
                     struct symt*    param_type = stabs_parse_type(ptr);
                     stab_strcpy(symname, sizeof(symname), ptr);
-                    symt_add_func_local(module, curr_func, DataIsParam, reg, 0,
+                    symt_add_func_local(module, curr_func, DataIsParam, reg, FALSE, 0,
                                         NULL, param_type, symname);
                     symt_add_function_signature_parameter(module, 
                                                           (struct symt_function_signature*)curr_func->type, 
                                                           param_type);
                 }
                 else
-                    pending_add(&pending, ptr, DataIsLocal, reg, 0);
+                    pending_add(&pending, ptr, DataIsLocal, reg, FALSE, 0);
             }
             break;
         case N_LSYM:
             /* These are local variables */
-            if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, 0, stab_ptr->n_value);
+            if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, 0, TRUE, stab_ptr->n_value);
             break;
         case N_SLINE:
             /*
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index 2c7904b..1e66a32 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -300,7 +300,7 @@ void symt_add_func_line(struct module* m
 struct symt_data* symt_add_func_local(struct module* module, 
                                       struct symt_function* func, 
                                       enum DataKind dt,
-                                      int regno, long offset,
+                                      int regno, BOOL regrel, long offset,
                                       struct symt_block* block, 
                                       struct symt* type, const char* name)
 {
@@ -323,6 +323,7 @@ struct symt_data* symt_add_func_local(st
     locsym->container     = &block->symt;
     locsym->type          = type;
     locsym->u.s.reg_id    = regno;
+    locsym->u.s.reg_rel   = regrel ? TRUE : FALSE;
     locsym->u.s.offset    = offset * 8;
     locsym->u.s.length    = 0;
     if (block)
@@ -477,7 +478,7 @@ static void symt_fill_sym_info(const str
                 sym_info->Flags |= SYMFLAG_PARAMETER;
                 /* fall through */
             case DataIsLocal: 
-                if (data->u.s.reg_id)
+                if (!data->u.s.reg_rel)
                 {
                     sym_info->Flags |= SYMFLAG_REGISTER;
                     sym_info->Register = data->u.s.reg_id;
@@ -486,8 +487,8 @@ static void symt_fill_sym_info(const str
                 else
                 {
                     sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_REGREL;
-                    /* FIXME: needed ? moreover, it's i386 dependent !!! */
-                    sym_info->Register = CV_REG_EBP;
+                    /* FIXME: it's i386 dependent !!! */
+                    sym_info->Register = data->u.s.reg_id ? data->u.s.reg_id : CV_REG_EBP;
                     sym_info->Address = data->u.s.offset / 8;
                 }
                 break;



More information about the wine-patches mailing list