[PATCH] [DbgHelp]: added support for loading dwarf debug information out of PE images

Eric Pouech eric.pouech at orange.fr
Wed Dec 23 15:05:25 CST 2009




A+
---

 dlls/dbghelp/elf_module.c |    2 -
 dlls/dbghelp/pe_module.c  |  102 +++++++++++++++++++++++++++++++++++----------
 2 files changed, 81 insertions(+), 23 deletions(-)


diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index 702bca2..3399aeb 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -369,7 +369,7 @@ int elf_is_in_thunk_area(unsigned long addr,
 {
     unsigned i;
 
-    for (i = 0; thunks[i].symname; i++)
+    if (thunks) for (i = 0; thunks[i].symname; i++)
     {
         if (addr >= thunks[i].rva_start && addr < thunks[i].rva_end)
             return i;
diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c
index 03e9c86..5cce6a3 100644
--- a/dlls/dbghelp/pe_module.c
+++ b/dlls/dbghelp/pe_module.c
@@ -98,6 +98,17 @@ static BOOL pe_load_symbol_table(struct module* module, IMAGE_NT_HEADERS* nth, v
     return TRUE;
 }
 
+static inline void* pe_get_sect(IMAGE_NT_HEADERS* nth, void* mapping,
+                                IMAGE_SECTION_HEADER* sect)
+{
+    return (sect) ? RtlImageRvaToVa(nth, mapping, sect->VirtualAddress, NULL) : NULL;
+}
+
+static inline DWORD pe_get_sect_size(IMAGE_SECTION_HEADER* sect)
+{
+    return (sect) ? sect->SizeOfRawData : 0;
+}
+
 /******************************************************************
  *		pe_load_stabs
  *
@@ -108,39 +119,85 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module,
                           void* mapping, IMAGE_NT_HEADERS* nth)
 {
     IMAGE_SECTION_HEADER*       section;
-    int                         i, stabsize = 0, stabstrsize = 0;
-    unsigned int                stabs = 0, stabstr = 0;
-    BOOL                        ret = FALSE;
+    IMAGE_SECTION_HEADER*       sect_stabs = NULL;
+    IMAGE_SECTION_HEADER*       sect_stabstr = NULL;
+    int                         i;
+    BOOL                        ret;
 
     section = (IMAGE_SECTION_HEADER*)
         ((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
     for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++)
     {
-        if (!strcasecmp((const char*)section->Name, ".stab"))
-        {
-            stabs = section->VirtualAddress;
-            stabsize = section->SizeOfRawData;
-        }
-        else if (!strncasecmp((const char*)section->Name, ".stabstr", 8))
-        {
-            stabstr = section->VirtualAddress;
-            stabstrsize = section->SizeOfRawData;
-        }
+        if (!strcasecmp((const char*)section->Name, ".stab"))              sect_stabs = section;
+        else if (!strncasecmp((const char*)section->Name, ".stabstr", 8))  sect_stabstr = section;
     }
-
-    if (stabstrsize && stabsize)
+    if (sect_stabs && sect_stabstr)
     {
-        ret = stabs_parse(module, 
-                          module->module.BaseOfImage - nth->OptionalHeader.ImageBase, 
-                          RtlImageRvaToVa(nth, mapping, stabs, NULL),
-                          stabsize,
-                          RtlImageRvaToVa(nth, mapping, stabstr, NULL),
-                          stabstrsize,
+        ret = stabs_parse(module,
+                          module->module.BaseOfImage - nth->OptionalHeader.ImageBase,
+                          pe_get_sect(nth, mapping, sect_stabs),   pe_get_sect_size(sect_stabs),
+                          pe_get_sect(nth, mapping, sect_stabstr), pe_get_sect_size(sect_stabstr),
                           NULL, NULL);
         if (ret) pe_load_symbol_table(module, nth, mapping);
     }
-
     TRACE("%s the STABS debug info\n", ret ? "successfully loaded" : "failed to load");
+
+    return ret;
+}
+
+/******************************************************************
+ *		pe_load_dwarf
+ *
+ * look for dwarf information in PE header (it's also a way for the mingw compiler
+ * to provide its debugging information)
+ */
+static BOOL pe_load_dwarf(const struct process* pcs, struct module* module,
+                          void* mapping, IMAGE_NT_HEADERS* nth)
+{
+    IMAGE_SECTION_HEADER*       section;
+    IMAGE_SECTION_HEADER*       sect_debuginfo = NULL;
+    IMAGE_SECTION_HEADER*       sect_debugstr = NULL;
+    IMAGE_SECTION_HEADER*       sect_debugabbrev = NULL;
+    IMAGE_SECTION_HEADER*       sect_debugline = NULL;
+    IMAGE_SECTION_HEADER*       sect_debugloc = NULL;
+    int                         i;
+    const char*                 strtable;
+    const char*                 sectname;
+    BOOL                        ret;
+
+    if (nth->FileHeader.PointerToSymbolTable && nth->FileHeader.NumberOfSymbols)
+        /* FIXME: no way to get strtable size */
+        strtable = (const char*)mapping + nth->FileHeader.PointerToSymbolTable +
+             nth->FileHeader.NumberOfSymbols * sizeof(IMAGE_SYMBOL);
+    else strtable = NULL;
+
+    section = (IMAGE_SECTION_HEADER*)
+        ((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
+    for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++)
+    {
+        sectname = (const char*)section->Name;
+        /* long section names start with a '/' (at least on MinGW32) */
+        if (*sectname == '/' && strtable)
+            sectname = strtable + atoi(sectname + 1);
+        if (!strcasecmp(sectname, ".debug_info"))        sect_debuginfo = section;
+        else if (!strcasecmp(sectname, ".debug_str"))    sect_debugstr = section;
+        else if (!strcasecmp(sectname, ".debug_abbrev")) sect_debugabbrev = section;
+        else if (!strcasecmp(sectname, ".debug_line"))   sect_debugline = section;
+        else if (!strcasecmp(sectname, ".debug_loc"))    sect_debugloc = section;
+    }
+    if (sect_debuginfo)
+    {
+        ret = dwarf2_parse(module,
+                           module->module.BaseOfImage - nth->OptionalHeader.ImageBase,
+                           NULL, /* FIXME: some thunks to deal with ? */
+                           pe_get_sect(nth, mapping, sect_debuginfo),   pe_get_sect_size(sect_debuginfo),
+                           pe_get_sect(nth, mapping, sect_debugabbrev), pe_get_sect_size(sect_debugabbrev),
+                           pe_get_sect(nth, mapping, sect_debugstr),    pe_get_sect_size(sect_debugstr),
+                           pe_get_sect(nth, mapping, sect_debugline),   pe_get_sect_size(sect_debugline),
+                           pe_get_sect(nth, mapping, sect_debugloc),    pe_get_sect_size(sect_debugloc));
+    }
+    TRACE("%s the DWARF debug info\n", ret ? "successfully loaded" : "failed to load");
+
     return ret;
 }
 
@@ -349,6 +406,7 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
             if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
             {
                 ret = pe_load_stabs(pcs, module, mapping, nth) ||
+                    pe_load_dwarf(pcs, module, mapping, nth) ||
                     pe_load_msc_debug_info(pcs, module, mapping, nth);
                 /* if we still have no debug info (we could only get SymExport at this
                  * point), then do the SymExport except if we have an ELF container, 






More information about the wine-patches mailing list