[PATCH] [DbgHelp]: dwarf & thunk

Eric Pouech eric.pouech at wanadoo.fr
Sat Jun 24 02:50:10 CDT 2006


- added the elf_is_in_thunk_area() function to locate
  an address within the known thunk area of Wine's
  builtin modules
- now passing this thunk information to the dwarf parser
  so that it can drop functions from the thunk areas
  (as dwarf symbols), so that those functions can be 
  later on marked as thunks in dbghelp internals

A+
---

 dlls/dbghelp/dbghelp_private.h |    4 +++-
 dlls/dbghelp/dwarf.c           |   14 +++++++++++++-
 dlls/dbghelp/elf_module.c      |   41 ++++++++++++++++++++++++++--------------
 3 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 6af37ee..50a38a4 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -375,7 +375,8 @@ extern struct module*
                     elf_load_module(struct process* pcs, const char* name, unsigned long);
 extern BOOL         elf_read_wine_loader_dbg_info(struct process* pcs);
 extern BOOL         elf_synchronize_module_list(struct process* pcs);
-
+struct elf_thunk_area;
+extern int          elf_is_in_thunk_area(unsigned long addr, const struct elf_thunk_area* thunks);
 extern DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr);
 
 /* module.c */
@@ -432,6 +433,7 @@ extern BOOL         stabs_parse(struct m
 
 /* dwarf.c */
 extern BOOL         dwarf2_parse(struct module* module, unsigned long load_offset,
+                                 const struct elf_thunk_area* thunks,
 				 const unsigned char* debug, unsigned int debug_size, 
 				 const unsigned char* abbrev, unsigned int abbrev_size, 
 				 const unsigned char* str, unsigned int str_size,
diff --git a/dlls/dbghelp/dwarf.c b/dlls/dbghelp/dwarf.c
index 18bf253..ec3a5e6 100644
--- a/dlls/dbghelp/dwarf.c
+++ b/dlls/dbghelp/dwarf.c
@@ -170,6 +170,7 @@ typedef struct dwarf2_parse_context_s
 {
     struct pool                 pool;
     struct module*              module;
+    const struct elf_thunk_area*thunks;
     struct sparse_array         abbrev_table;
     struct sparse_array         debug_info_table;
     unsigned char               word_size;
@@ -1255,6 +1256,13 @@ static struct symt* dwarf2_parse_subprog
 
     if (!dwarf2_find_attribute(di, DW_AT_low_pc, &low_pc)) low_pc.uvalue = 0;
     if (!dwarf2_find_attribute(di, DW_AT_high_pc, &high_pc)) high_pc.uvalue = 0;
+    /* As functions (defined as inline assembly) get debug info with dwarf
+     * (not the case for stabs), we just drop Wine's thunks here...
+     * Actual thunks will be created in elf_module from the symbol table
+     */
+    if (elf_is_in_thunk_area(ctx->module->module.BaseOfImage + low_pc.uvalue,
+                             ctx->thunks) >= 0)
+        return NULL;
     if (!dwarf2_find_attribute(di, DW_AT_declaration, &is_decl)) is_decl.uvalue = 0;
     if (!dwarf2_find_attribute(di, DW_AT_inline, &inline_flags)) inline_flags.uvalue = 0;
     dwarf2_find_name(ctx, di, &name, "subprogram");
@@ -1558,6 +1566,7 @@ static void dwarf2_parse_line_numbers(co
 static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections,
                                           const dwarf2_comp_unit_t* comp_unit,
                                           struct module* module,
+                                          const struct elf_thunk_area* thunks,
                                           const unsigned char* comp_unit_cursor)
 {
     dwarf2_parse_context_t ctx;
@@ -1583,6 +1592,7 @@ static BOOL dwarf2_parse_compilation_uni
     pool_init(&ctx.pool, 65536);
     ctx.module = module;
     ctx.word_size = comp_unit->word_size;
+    ctx.thunks = thunks;
 
     traverse.sections = sections;
     traverse.section = section_debug;
@@ -1634,6 +1644,7 @@ static BOOL dwarf2_parse_compilation_uni
 }
 
 BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
+                  const struct elf_thunk_area* thunks,
 		  const unsigned char* debug, unsigned int debug_size,
 		  const unsigned char* abbrev, unsigned int abbrev_size,
 		  const unsigned char* str, unsigned int str_size,
@@ -1663,7 +1674,8 @@ BOOL dwarf2_parse(struct module* module,
         comp_unit.abbrev_offset = *(unsigned long*) comp_unit_stream->abbrev_offset;
         comp_unit.word_size = *(unsigned char*) comp_unit_stream->word_size;
 
-        dwarf2_parse_compilation_unit(section, &comp_unit, module, comp_unit_cursor);
+        dwarf2_parse_compilation_unit(section, &comp_unit, module,
+                                      thunks, comp_unit_cursor);
         comp_unit_cursor += comp_unit.length + sizeof(unsigned);
     }
     module->module.SymType = SymDia;
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index b2f584b..495dcba 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -125,7 +125,7 @@ struct symtab_elt
     unsigned                    used;
 };
 
-struct thunk_area
+struct elf_thunk_area
 {
     const char*                 symname;
     THUNK_ORDINAL               ordinal;
@@ -250,13 +250,32 @@ static void elf_unmap_file(struct elf_fi
 }
 
 /******************************************************************
+ *		elf_is_in_thunk_area
+ *
+ * Check whether an address lies within one of the thunk area we
+ * know of.
+ */
+int elf_is_in_thunk_area(unsigned long addr,
+                         const struct elf_thunk_area* thunks)
+{
+    unsigned i;
+
+    for (i = 0; thunks[i].symname; i++)
+    {
+        if (addr >= thunks[i].rva_start && addr < thunks[i].rva_end)
+            return i;
+    }
+    return -1;
+}
+
+/******************************************************************
  *		elf_hash_symtab
  *
  * creating an internal hash table to ease use ELF symtab information lookup
  */
 static void elf_hash_symtab(struct module* module, struct pool* pool, 
                             struct hash_table* ht_symtab, struct elf_file_map* fmap,
-                            int symtab_idx, struct thunk_area* thunks)
+                            int symtab_idx, struct elf_thunk_area* thunks)
 {
     int		                i, j, nsym;
     const char*                 strp;
@@ -503,7 +522,7 @@ static void elf_finish_stabs_info(struct
  * creating the thunk objects for a wine native DLL
  */
 static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symtab,
-                               unsigned num_areas, struct thunk_area* thunks)
+                               const struct elf_thunk_area* thunks)
 {
     int		                j;
     struct hash_table_iter      hti;
@@ -518,13 +537,8 @@ static int elf_new_wine_thunks(struct mo
 
         addr = module->elf_info->elf_addr + ste->symp->st_value;
 
-        for (j = 0; j < num_areas; j++)
-        {
-            if (ste->symp->st_value >= thunks[j].rva_start && 
-                ste->symp->st_value < thunks[j].rva_end)
-                break;
-        }
-        if (j < num_areas) /* thunk found */
+        j = elf_is_in_thunk_area(ste->symp->st_value, thunks);
+        if (j >= 0) /* thunk found */
         {
             symt_new_thunk(module, ste->compiland, ste->ht_elt.name, thunks[j].ordinal,
                            addr, ste->symp->st_size);
@@ -767,7 +781,7 @@ static BOOL elf_load_debug_info_from_map
     int                 symtab_sect, dynsym_sect, stab_sect, stabstr_sect;
     int                 debug_sect, debug_str_sect, debug_abbrev_sect, debug_line_sect;
     int                 debuglink_sect;
-    struct thunk_area   thunks[] = 
+    struct elf_thunk_area thunks[] = 
     {
         {"__wine_spec_import_thunks",           THUNK_ORDINAL_NOTYPE, 0, 0},    /* inter DLL calls */
         {"__wine_spec_delayed_import_loaders",  THUNK_ORDINAL_LOAD,   0, 0},    /* delayed inter DLL calls */
@@ -883,7 +897,7 @@ static BOOL elf_load_debug_info_from_map
             if (dw2_debug != NO_MAP && NO_MAP != dw2_debug_abbrev && dw2_debug_str != NO_MAP)
             {
                 /* OK, now just parse dwarf2 debug infos. */
-                lret = dwarf2_parse(module, module->elf_info->elf_addr,
+                lret = dwarf2_parse(module, module->elf_info->elf_addr, thunks,
                                     dw2_debug, fmap->sect[debug_sect].shdr.sh_size,
                                     dw2_debug_abbrev, fmap->sect[debug_abbrev_sect].shdr.sh_size,
                                     dw2_debug_str, fmap->sect[debug_str_sect].shdr.sh_size,
@@ -930,8 +944,7 @@ static BOOL elf_load_debug_info_from_map
     {
         /* add the thunks for native libraries */
         if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
-            elf_new_wine_thunks(module, ht_symtab, 
-                                sizeof(thunks) / sizeof(thunks[0]), thunks);
+            elf_new_wine_thunks(module, ht_symtab, thunks);
     }
     /* add all the public symbols from symtab */
     if (elf_new_public_symbols(module, ht_symtab) && !ret) ret = TRUE;



More information about the wine-patches mailing list