[PATCH 07/22] [DbgHelp]: location info

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


- now using the location info structure thoughout the
  code to handle the location of a data variable

A+
---

 dlls/dbghelp/dbghelp_private.h |   26 ++++++++++++++------
 dlls/dbghelp/dwarf.c           |    3 +-
 dlls/dbghelp/elf_module.c      |    8 +++---
 dlls/dbghelp/msc.c             |   26 ++++++++++++++++----
 dlls/dbghelp/stabs.c           |   53 +++++++++++++++++++++-------------------
 dlls/dbghelp/symbol.c          |   17 +++++--------
 dlls/dbghelp/type.c            |   31 ++++++++++++-----------
 7 files changed, 95 insertions(+), 69 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 6c80060..d6081bd 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -172,15 +172,25 @@ struct symt_data
     struct symt*                type;
     union                                       /* depends on kind */
     {
-        unsigned long           address;        /* DataIs{Global, FileStatic} */
+        /* DataIs{Global, FileStatic}:
+         *      loc.kind is loc_absolute
+         *      loc.offset is address
+         * DataIs{Local,Param}:
+         *      with loc.kind
+         *              loc_absolute    not supported
+         *              loc_register    location is in register loc.reg
+         *              loc_regrel      location is at address loc.reg + loc.offset
+         *              >= loc_user     ask debug info provider for resolution
+         */
+        struct location         var;
+        /* DataIs{Member} (all values are in bits, not bytes) */
         struct
         {
-            long                        offset; /* DataIs{Member,Local,Param} in bits */
-            unsigned long               length; /* DataIs{Member} in bits */
-            unsigned long               reg_rel : 1, /* DataIs{Local}: 0 in register, 1 deref */
-                                        reg_id; /* DataIs{Local} (0 if frame relative) */
-        } s;
-        VARIANT                 value;          /* DataIsConstant */
+            long                        offset;
+            unsigned long               length;
+        } member;
+        /* DataIsConstant */
+        VARIANT                 value;
     } u;
 };
 
@@ -500,7 +510,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, BOOL regrel, int regno, long offset,
+                                        enum DataKind dt, const struct location* loc,
                                         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 6bd0fff..2a40493 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -1253,8 +1253,7 @@ static void dwarf2_parse_variable(dwarf2
             assert(subpgm->func);
             symt_add_func_local(subpgm->ctx->module, subpgm->func, 
                                 is_pmt ? DataIsParam : DataIsLocal,
-                                loc.reg, loc.kind == loc_regrel,
-                                loc.offset, block, param_type, name.u.string);
+                                &loc, block, param_type, name.u.string);
             break;
         default:
             FIXME("Unsupported\n");
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index 23b3ab3..c7d7e4e 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -502,18 +502,18 @@ static void elf_finish_stabs_info(struct
             {
             case DataIsGlobal:
             case DataIsFileStatic:
-                if (((struct symt_data*)sym)->u.address != module->elf_info->elf_addr)
+                if (((struct symt_data*)sym)->u.var.offset != module->elf_info->elf_addr)
                     break;
                 symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name, 
                                          ((struct symt_data*)sym)->container);
                 if (symp)
                 {
-                if (((struct symt_data*)sym)->u.address != module->elf_info->elf_addr &&
-                    ((struct symt_data*)sym)->u.address != module->elf_info->elf_addr + symp->st_value)
+                if (((struct symt_data*)sym)->u.var.offset != module->elf_info->elf_addr &&
+                    ((struct symt_data*)sym)->u.var.offset != module->elf_info->elf_addr + symp->st_value)
                     FIXME("Changing address for %p/%s!%s from %08lx to %08lx\n", 
                           sym, module->module.ModuleName, sym->hash_elt.name, 
                           ((struct symt_function*)sym)->address, module->elf_info->elf_addr + symp->st_value);
-                    ((struct symt_data*)sym)->u.address = module->elf_info->elf_addr +
+                    ((struct symt_data*)sym)->u.var.offset = module->elf_info->elf_addr +
                                                           symp->st_value;
                     ((struct symt_data*)sym)->kind = (ELF32_ST_BIND(symp->st_info) == STB_LOCAL) ?
                         DataIsFileStatic : DataIsGlobal;
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index b9b3d5a..bc59045 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1244,6 +1244,7 @@ static int codeview_snarf(const struct m
     struct symt*                        symt;
     const char*                         name;
     struct symt_compiland*              compiland = NULL;
+    struct location                     loc;
 
     /*
      * Loop over the different types of records and whenever we
@@ -1378,36 +1379,51 @@ static int codeview_snarf(const struct m
          * Function parameters and stack variables.
          */
 	case S_BPREL_V1:
+            loc.kind = loc_regrel;
+            loc.reg = 0; /* FIXME */
+            loc.offset = sym->stack_v1.offset;
             symt_add_func_local(msc_dbg->module, curr_func, 
                                 sym->stack_v1.offset > 0 ? DataIsParam : DataIsLocal, 
-                                0, TRUE, sym->stack_v1.offset, block,
+                                &loc, block,
                                 codeview_get_type(sym->stack_v1.symtype, FALSE),
                                 terminate_string(&sym->stack_v1.p_name));
             break;
 	case S_BPREL_V2:
+            loc.kind = loc_regrel;
+            loc.reg = 0; /* FIXME */
+            loc.offset = sym->stack_v2.offset;
             symt_add_func_local(msc_dbg->module, curr_func, 
                                 sym->stack_v2.offset > 0 ? DataIsParam : DataIsLocal, 
-                                0, TRUE, sym->stack_v2.offset, block,
+                                &loc, block,
                                 codeview_get_type(sym->stack_v2.symtype, FALSE),
                                 terminate_string(&sym->stack_v2.p_name));
             break;
 	case S_BPREL_V3:
+            loc.kind = loc_regrel;
+            loc.reg = 0; /* FIXME */
+            loc.offset = sym->stack_v3.offset;
             symt_add_func_local(msc_dbg->module, curr_func, 
                                 sym->stack_v3.offset > 0 ? DataIsParam : DataIsLocal, 
-                                0, TRUE, sym->stack_v3.offset, block,
+                                &loc, block,
                                 codeview_get_type(sym->stack_v3.symtype, FALSE),
                                 sym->stack_v3.name);
             break;
 
         case S_REGISTER_V1:
+            loc.kind = loc_register;
+            loc.reg = sym->register_v1.reg;
+            loc.offset = 0;
             symt_add_func_local(msc_dbg->module, curr_func, 
-                                DataIsLocal, sym->register_v1.reg, FALSE, 0,
+                                DataIsLocal, &loc,
                                 block, codeview_get_type(sym->register_v1.type, FALSE),
                                 terminate_string(&sym->register_v1.p_name));
             break;
         case S_REGISTER_V2:
+            loc.kind = loc_register;
+            loc.reg = sym->register_v2.reg;
+            loc.offset = 0;
             symt_add_func_local(msc_dbg->module, curr_func, 
-                                DataIsLocal, sym->register_v2.reg, FALSE, 0,
+                                DataIsLocal, &loc,
                                 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 f90c62a..6f6c851 100644
--- a/dlls/dbghelp/stabs.c
+++ b/dlls/dbghelp/stabs.c
@@ -1095,9 +1095,7 @@ struct pending_loc_var
     char                name[256];
     struct symt*        type;
     enum DataKind       kind;
-    unsigned            offset;
-    unsigned            regrel : 1,
-                        regno;
+    struct location     loc;
 };
 
 struct pending_block
@@ -1108,7 +1106,7 @@ struct pending_block
 };
 
 static inline void pending_add(struct pending_block* pending, const char* name,
-                               enum DataKind dt, int regno, BOOL regrel, long offset)
+                               enum DataKind dt, const struct location* loc)
 {
     if (pending->num == pending->allocated)
     {
@@ -1124,9 +1122,7 @@ static inline void pending_add(struct pe
                 sizeof(pending->vars[pending->num].name), name);
     pending->vars[pending->num].type   = stabs_parse_type(name);
     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->vars[pending->num].loc    = *loc;
     pending->num++;
 }
 
@@ -1138,8 +1134,7 @@ 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].regrel, pending->vars[i].offset,
+                            pending->vars[i].kind, &pending->vars[i].loc,
                             block, pending->vars[i].type, pending->vars[i].name);
     }
     pending->num = 0;
@@ -1195,6 +1190,7 @@ BOOL stabs_parse(struct module* module, 
     int                         source_idx = -1;
     struct pending_block        pending;
     BOOL                        ret = TRUE;
+    struct location             loc;
 
     nstab = stablen / sizeof(struct stab_nlist);
     strs_end = strs + strtablen;
@@ -1316,9 +1312,12 @@ BOOL stabs_parse(struct module* module, 
             {
                 struct symt*    param_type = stabs_parse_type(ptr);
                 stab_strcpy(symname, sizeof(symname), ptr);
+                loc.kind = loc_regrel;
+                loc.reg = 0; /* FIXME */
+                loc.offset = stab_ptr->n_value;
                 symt_add_func_local(module, curr_func,
-                                    stab_ptr->n_value > 0 ? DataIsParam : DataIsLocal,
-                                    0, TRUE, stab_ptr->n_value, NULL, param_type, symname);
+                                    (long)stab_ptr->n_value >= 0 ? DataIsParam : DataIsLocal,
+                                    &loc, NULL, param_type, symname);
                 symt_add_function_signature_parameter(module, 
                                                       (struct symt_function_signature*)curr_func->type, 
                                                       param_type);
@@ -1328,18 +1327,19 @@ BOOL stabs_parse(struct module* module, 
             /* These are registers (as local variables) */
             if (curr_func != NULL)
             {
-                unsigned reg;
+                loc.kind = loc_register;
+                loc.offset = 0;
 
                 switch (stab_ptr->n_value)
                 {
-                case  0: reg = CV_REG_EAX; break;
-                case  1: reg = CV_REG_ECX; break;
-                case  2: reg = CV_REG_EDX; break;
-                case  3: reg = CV_REG_EBX; break;
-                case  4: reg = CV_REG_ESP; break;
-                case  5: reg = CV_REG_EBP; break;
-                case  6: reg = CV_REG_ESI; break;
-                case  7: reg = CV_REG_EDI; break;
+                case  0: loc.reg = CV_REG_EAX; break;
+                case  1: loc.reg = CV_REG_ECX; break;
+                case  2: loc.reg = CV_REG_EDX; break;
+                case  3: loc.reg = CV_REG_EBX; break;
+                case  4: loc.reg = CV_REG_ESP; break;
+                case  5: loc.reg = CV_REG_EBP; break;
+                case  6: loc.reg = CV_REG_ESI; break;
+                case  7: loc.reg = CV_REG_EDI; break;
                 case 11:
                 case 12:
                 case 13:
@@ -1348,10 +1348,10 @@ BOOL stabs_parse(struct module* module, 
                 case 16:
                 case 17:
                 case 18:
-                case 19: reg = CV_REG_ST0 + stab_ptr->n_value - 12; break;
+                case 19: loc.reg = CV_REG_ST0 + stab_ptr->n_value - 12; break;
                 default:
                     FIXME("Unknown register value (%lu)\n", stab_ptr->n_value);
-                    reg = CV_REG_NONE;
+                    loc.reg = CV_REG_NONE;
                     break;
                 }
                 stab_strcpy(symname, sizeof(symname), ptr);
@@ -1359,19 +1359,22 @@ 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, FALSE, 0,
+                    symt_add_func_local(module, curr_func, DataIsParam, &loc,
                                         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, FALSE, 0);
+                    pending_add(&pending, ptr, DataIsLocal, &loc);
             }
             break;
         case N_LSYM:
             /* These are local variables */
-            if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, 0, TRUE, stab_ptr->n_value);
+            loc.kind = loc_regrel;
+            loc.reg = 0; /* FIXME */
+            loc.offset = stab_ptr->n_value;
+            if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, &loc);
             break;
         case N_SLINE:
             /*
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index a3cd0c7..c6a44c9 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -197,7 +197,7 @@ struct symt_data* symt_new_global_variab
         sym->kind          = is_static ? DataIsFileStatic : DataIsGlobal;
         sym->container     = compiland ? &compiland->symt : NULL;
         sym->type          = type;
-        sym->u.address     = addr;
+        sym->u.var.offset  = addr;
         if (type && size && symt_get_info(type, TI_GET_LENGTH, &tsz))
         {
             if (tsz != size)
@@ -302,7 +302,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, BOOL regrel, long offset,
+                                      const struct location* loc,
                                       struct symt_block* block, 
                                       struct symt* type, const char* name)
 {
@@ -324,10 +324,7 @@ struct symt_data* symt_add_func_local(st
     locsym->kind          = dt;
     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;
+    locsym->u.var         = *loc;
     if (block)
         p = vector_add(&block->vchildren, &module->pool);
     else
@@ -481,18 +478,18 @@ static void symt_fill_sym_info(const str
                 sym_info->Flags |= SYMFLAG_PARAMETER;
                 /* fall through */
             case DataIsLocal: 
-                if (!data->u.s.reg_rel)
+                if (data->u.var.kind == loc_register)
                 {
                     sym_info->Flags |= SYMFLAG_REGISTER;
-                    sym_info->Register = data->u.s.reg_id;
+                    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.s.reg_id ? data->u.s.reg_id : CV_REG_EBP;
-                    sym_info->Address = data->u.s.offset / 8;
+                    sym_info->Register = data->u.var.reg ? data->u.var.reg : CV_REG_EBP;
+                    sym_info->Address = data->u.var.offset;
                 }
                 break;
             case DataIsGlobal:
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c
index a50448b..83db9eb 100644
--- a/dlls/dbghelp/type.c
+++ b/dlls/dbghelp/type.c
@@ -229,12 +229,11 @@ BOOL symt_add_udt_element(struct module*
     m->hash_elt.name = pool_strdup(&module->pool, name);
     m->hash_elt.next = NULL;
 
-    m->kind          = DataIsMember;
-    m->container     = &udt_type->symt;
-    m->type          = elt_type;
-    m->u.s.offset    = offset;
-    m->u.s.length    = ((offset & 7) || (size & 7)) ? size : 0;
-    m->u.s.reg_id    = 0;
+    m->kind            = DataIsMember;
+    m->container       = &udt_type->symt;
+    m->type            = elt_type;
+    m->u.member.offset = offset;
+    m->u.member.length = ((offset & 7) || (size & 7)) ? size : 0;
     p = vector_add(&udt_type->vchildren, &module->pool);
     *p = &m->symt;
 
@@ -470,7 +469,7 @@ #define X(_t) (*((_t*)pInfo))
             {
             case DataIsGlobal:
             case DataIsFileStatic:
-                X(ULONG64) = ((const struct symt_data*)type)->u.address;
+                X(ULONG64) = ((const struct symt_data*)type)->u.var.offset;
                 break;
             default: return FALSE;
             }
@@ -515,11 +514,11 @@ #define X(_t) (*((_t*)pInfo))
         break;
 
     case TI_GET_BITPOSITION:
-        if (type->tag != SymTagData || 
-            ((const struct symt_data*)type)->kind != DataIsMember ||
-            ((const struct symt_data*)type)->u.s.length == 0)
-            return FALSE;
-        X(DWORD) = ((const struct symt_data*)type)->u.s.offset & 7;
+        if (type->tag == SymTagData &&
+            ((const struct symt_data*)type)->kind == DataIsMember &&
+            ((const struct symt_data*)type)->u.member.length != 0)
+            X(DWORD) = ((const struct symt_data*)type)->u.member.offset & 7;
+        else return FALSE;
         break;
 
     case TI_GET_CHILDRENCOUNT:
@@ -595,9 +594,9 @@ #define X(_t) (*((_t*)pInfo))
             break;
         case SymTagData:
             if (((const struct symt_data*)type)->kind != DataIsMember ||
-                !((const struct symt_data*)type)->u.s.length)
+                !((const struct symt_data*)type)->u.member.length)
                 return FALSE;
-            X(DWORD64) = ((const struct symt_data*)type)->u.s.length;
+            X(DWORD64) = ((const struct symt_data*)type)->u.member.length;
             break;
         case SymTagArrayType:   
             if (!symt_get_info(((const struct symt_array*)type)->base_type, 
@@ -668,8 +667,10 @@ #define X(_t) (*((_t*)pInfo))
             {
             case DataIsParam:
             case DataIsLocal:
+                X(ULONG) = ((const struct symt_data*)type)->u.var.offset; 
+                break;
             case DataIsMember:
-                X(ULONG) = ((const struct symt_data*)type)->u.s.offset >> 3; 
+                X(ULONG) = ((const struct symt_data*)type)->u.member.offset >> 3; 
                 break;
             default:
                 FIXME("Unknown kind (%u) for get-offset\n",     



More information about the wine-patches mailing list