dbghelp: Added support for variables in thread storage.
authorEric Pouech <eric.pouech@orange.fr>
Sat, 29 Jan 2011 19:38:04 +0000 (20:38 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Mon, 31 Jan 2011 13:30:13 +0000 (14:30 +0100)
dlls/dbghelp/coff.c
dlls/dbghelp/dbghelp_private.h
dlls/dbghelp/dwarf.c
dlls/dbghelp/elf_module.c
dlls/dbghelp/macho_module.c
dlls/dbghelp/msc.c
dlls/dbghelp/pe_module.c
dlls/dbghelp/stabs.c
dlls/dbghelp/symbol.c

index 720f00b58afe3615567d7df36b68b7b01cd2e615..3a9f2a26b8566b8fbb9882e684fe1193b49e7b8d 100644 (file)
@@ -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;
        }
index b2b13c0f88a98ed509456a25aa336526618ef7c8..e6ef5943301a15061b24070194860f1d7cdb60ba 100644 (file)
@@ -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,
index e02e654c4e774e421b3e73acb6f6adb43836c44d..585ea6c09d9dc21525cf6c9c6640d4f33ed00b10 100644 (file)
@@ -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;
index e2391bd193e782016a9a6a99f608423f85714a13..de61fc10095a719092934face293803959bd5665 100644 (file)
@@ -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");
index 6b03fee958858e9f17e97be900902fa444255243..f45e63c2b632832e5611179bf3aad8913d78e89e 100644 (file)
@@ -818,8 +818,13 @@ static void macho_finish_stabs(struct module* module, struct hash_table* ht_symt
             }
             else
             {
+                struct location loc;
+
+                loc.kind = loc_absolute;
+                loc.reg = 0;
+                loc.offset = ste->addr;
                 symt_new_global_variable(module, ste->compiland, ste->ht_elt.name,
-                    !ste->is_global, ste->addr, 0, NULL);
+                                         !ste->is_global, loc, 0, NULL);
             }
 
             ste->used = 1;
index 0c90b000235eccc2bec605e6ae34b6027157fcfc..7bd9fc44a0375da73809a2b93ca4c609ffb3b31c 100644 (file)
@@ -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));
         }
     }
index 2d8d16cf5918ae724be665446031232f222950e0..028eac7140f150eb53cb76819da143638cb1dcdf 100644 (file)
@@ -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",
index 895a0598f8c1db006f4c35a9834d5f234338c82a..721d5e70183d3b6150245945221af3cda601cf09 100644 (file)
@@ -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)
index b399b667c850253301af97c0e868df19d9b1e961..07e62e29b8f99a29b9697a8afcfa64f14e98fd78 100644 (file)
@@ -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;