[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