[PATCH 2/4] [DbgHelp]: added support for variables in thread storage

Eric Pouech eric.pouech at orange.fr
Sat Jan 29 13:38:04 CST 2011




A+
---

 dlls/dbghelp/coff.c            |    8 ++++++--
 dlls/dbghelp/dbghelp_private.h |    8 +++++---
 dlls/dbghelp/dwarf.c           |    4 ++--
 dlls/dbghelp/elf_module.c      |    9 +++++++--
 dlls/dbghelp/msc.c             |    6 +++++-
 dlls/dbghelp/pe_module.c       |    1 +
 dlls/dbghelp/stabs.c           |   12 ++++++++----
 dlls/dbghelp/symbol.c          |   23 +++++++++++++++++------
 8 files changed, 51 insertions(+), 20 deletions(-)


diff --git a/dlls/dbghelp/coff.c b/dlls/dbghelp/coff.c
index 720f00b..3a9f2a2 100644
--- a/dlls/dbghelp/coff.c
+++ b/dlls/dbghelp/coff.c
@@ -342,6 +342,8 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
             coff_sym->SectionNumber > 0)
 	{
             DWORD base = msc_dbg->sectp[coff_sym->SectionNumber - 1].VirtualAddress;
+            struct location loc;
+
             /*
              * Similar to above, but for the case of data symbols.
              * These aren't treated as entrypoints.
@@ -356,9 +358,11 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
             /*
              * Now we need to figure out which file this guy belongs to.
              */
+            loc.kind = loc_absolute;
+            loc.reg = 0;
+            loc.offset = msc_dbg->module->module.BaseOfImage + base + coff_sym->Value;
             symt_new_global_variable(msc_dbg->module, NULL, nampnt, TRUE /* FIXME */,
-                                     msc_dbg->module->module.BaseOfImage + base + coff_sym->Value,
-                                     0 /* FIXME */, NULL /* FIXME */);
+                                     loc, 0 /* FIXME */, NULL /* FIXME */);
             i += naux;
             continue;
 	}
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index b2b13c0..e6ef594 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -125,6 +125,7 @@ enum location_kind {loc_error,          /* reg is the error code */
                     loc_absolute,       /* offset is the location */
                     loc_register,       /* reg is the location */
                     loc_regrel,         /* [reg+offset] is the location */
+                    loc_tlsrel,         /* offset is the address of the TLS index */
                     loc_user,           /* value is debug information dependent,
                                            reg & offset can be used ad libidem */
 };
@@ -182,8 +183,9 @@ struct symt_data
     union                                       /* depends on kind */
     {
         /* DataIs{Global, FileStatic}:
-         *      loc.kind is loc_absolute
-         *      loc.offset is address
+         *      with loc.kind
+         *              loc_absolute    loc.offset is address
+         *              loc_tlsrel      loc.offset is TLS index address
          * DataIs{Local,Param}:
          *      with loc.kind
          *              loc_absolute    not supported
@@ -634,7 +636,7 @@ extern struct symt_data*
                     symt_new_global_variable(struct module* module, 
                                              struct symt_compiland* parent,
                                              const char* name, unsigned is_static,
-                                             unsigned long addr, unsigned long size, 
+                                             struct location loc, unsigned long size,
                                              struct symt* type);
 extern struct symt_function*
                     symt_new_function(struct module* module,
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 17d4719..d5e3a88 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -1486,10 +1486,10 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
             /* FIXME: we don't handle its scope yet */
             if (!dwarf2_find_attribute(subpgm->ctx, di, DW_AT_external, &ext))
                 ext.u.uvalue = 0;
+            loc.offset += subpgm->ctx->load_offset;
             symt_new_global_variable(subpgm->ctx->module, subpgm->compiland,
                                      name.u.string, !ext.u.uvalue,
-                                     subpgm->ctx->load_offset + loc.offset,
-                                     0, param_type);
+                                     loc, 0, param_type);
             break;
         default:
             subpgm->non_computed_variable = TRUE;
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index e2391bd..de61fc1 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -668,7 +668,8 @@ static void elf_finish_stabs_info(struct module* module, const struct hash_table
             {
             case DataIsGlobal:
             case DataIsFileStatic:
-                if (((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr)
+                if (((struct symt_data*)sym)->u.var.kind != loc_absolute ||
+                    ((struct symt_data*)sym)->u.var.offset != elf_info->elf_addr)
                     break;
                 symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name, 
                                          ((struct symt_data*)sym)->container);
@@ -728,6 +729,7 @@ static int elf_new_wine_thunks(struct module* module, const struct hash_table* h
         else
         {
             ULONG64     ref_addr;
+            struct location loc;
 
             symt = symt_find_nearest(module, addr);
             if (symt && !symt_get_info(module, &symt->symt, TI_GET_ADDRESS, &ref_addr))
@@ -745,9 +747,12 @@ static int elf_new_wine_thunks(struct module* module, const struct hash_table* h
                                       addr, ste->symp->st_size, NULL);
                     break;
                 case STT_OBJECT:
+                    loc.kind = loc_absolute;
+                    loc.reg = 0;
+                    loc.offset = addr;
                     symt_new_global_variable(module, ste->compiland, ste->ht_elt.name,
                                              ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL,
-                                             addr, ste->symp->st_size, NULL);
+                                             loc, ste->symp->st_size, NULL);
                     break;
                 default:
                     FIXME("Shouldn't happen\n");
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index 0c90b00..7bd9fc4 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -1528,11 +1528,15 @@ static inline void codeview_add_variable(const struct msc_debug_info* msc_dbg,
     if (name && *name)
     {
         unsigned long   address = codeview_get_address(msc_dbg, segment, offset);
+        struct location loc;
 
+        loc.kind = loc_absolute;
+        loc.reg = 0;
+        loc.offset = address;
         if (force || !symt_find_nearest(msc_dbg->module, address))
         {
             symt_new_global_variable(msc_dbg->module, compiland,
-                                     name, is_local, address, 0,
+                                     name, is_local, loc, 0,
                                      codeview_get_type(symtype, FALSE));
         }
     }
diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c
index 2d8d16c..028eac7 100644
--- a/dlls/dbghelp/pe_module.c
+++ b/dlls/dbghelp/pe_module.c
@@ -376,6 +376,7 @@ static BOOL pe_locate_with_coff_symbol_table(struct module* module)
                 sym = GET_ENTRY(ptr, struct symt_data, hash_elt);
                 if (sym->symt.tag == SymTagData &&
                     (sym->kind == DataIsGlobal || sym->kind == DataIsFileStatic) &&
+                    sym->u.var.kind == loc_absolute &&
                     !strcmp(sym->hash_elt.name, name))
                 {
                     TRACE("Changing absolute address for %d.%s: %lx -> %s\n",
diff --git a/dlls/dbghelp/stabs.c b/dlls/dbghelp/stabs.c
index 895a059..721d5e7 100644
--- a/dlls/dbghelp/stabs.c
+++ b/dlls/dbghelp/stabs.c
@@ -1381,17 +1381,21 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
              * With a.out or mingw, they actually do make some amount of sense.
              */
             stab_strcpy(symname, sizeof(symname), ptr);
+            loc.kind = loc_absolute;
+            loc.reg = 0;
+            loc.offset = load_offset + stab_ptr->n_value;
             symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
-                                     load_offset + stab_ptr->n_value, 0,
-                                     stabs_parse_type(ptr));
+                                     loc, 0, stabs_parse_type(ptr));
             break;
         case N_LCSYM:
         case N_STSYM:
             /* These are static symbols and BSS symbols. */
             stab_strcpy(symname, sizeof(symname), ptr);
+            loc.kind = loc_absolute;
+            loc.reg = 0;
+            loc.offset = load_offset + stab_ptr->n_value;
             symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
-                                     load_offset + stab_ptr->n_value, 0,
-                                     stabs_parse_type(ptr));
+                                     loc, 0, stabs_parse_type(ptr));
             break;
         case N_LBRAC:
             if (curr_func)
diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c
index b399b66..07e62e2 100644
--- a/dlls/dbghelp/symbol.c
+++ b/dlls/dbghelp/symbol.c
@@ -334,15 +334,15 @@ struct symt_public* symt_new_public(struct module* module,
 struct symt_data* symt_new_global_variable(struct module* module, 
                                            struct symt_compiland* compiland, 
                                            const char* name, unsigned is_static,
-                                           unsigned long addr, unsigned long size,
+                                           struct location loc, unsigned long size,
                                            struct symt* type)
 {
     struct symt_data*   sym;
     struct symt**       p;
     DWORD64             tsz;
 
-    TRACE_(dbghelp_symt)("Adding global symbol %s:%s @%lx %p\n",
-                         debugstr_w(module->module.ModuleName), name, addr, type);
+    TRACE_(dbghelp_symt)("Adding global symbol %s:%s %d@%lx %p\n",
+                         debugstr_w(module->module.ModuleName), name, loc.kind, loc.offset, type);
     if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
     {
         sym->symt.tag      = SymTagData;
@@ -350,7 +350,7 @@ struct symt_data* symt_new_global_variable(struct module* module,
         sym->kind          = is_static ? DataIsFileStatic : DataIsGlobal;
         sym->container     = compiland ? &compiland->symt : NULL;
         sym->type          = type;
-        sym->u.var.offset  = addr;
+        sym->u.var         = loc;
         if (type && size && symt_get_info(module, type, TI_GET_LENGTH, &tsz))
         {
             if (tsz != size)
@@ -736,8 +736,19 @@ static void symt_fill_sym_info(struct module_pair* pair,
                 break;
             case DataIsGlobal:
             case DataIsFileStatic:
-                symt_get_info(pair->effective, sym, TI_GET_ADDRESS, &sym_info->Address);
-                sym_info->Register = 0;
+                switch (data->u.var.kind)
+                {
+                case loc_tlsrel:
+                    sym_info->Flags |= SYMFLAG_TLSREL;
+                    /* fall through */
+                case loc_absolute:
+                    symt_get_info(pair->effective, sym, TI_GET_ADDRESS, &sym_info->Address);
+                    sym_info->Register = 0;
+                    break;
+                default:
+                    FIXME("Shouldn't happen (kind=%d), debug reader backend is broken\n", data->u.var.kind);
+                    assert(0);
+                }
                 break;
             case DataIsConstant:
                 sym_info->Flags |= SYMFLAG_VALUEPRESENT;




More information about the wine-patches mailing list