dbghelp: Search for .gnu_debuglink file

Frank Richter frank.richter at gmail.com
Mon Jan 1 13:28:10 CST 2007


The .gnu_debuglink section contains only a bare filename, however, the 
debug file can be in a number of locations. These are stated in the GDB 
manual and are now searched when a .gnu_debuglink is encountered.

-------------- next part --------------
>From da060d988fb0cc4b825135a10cf1fba170f609ff Mon Sep 17 00:00:00 2001
From: Frank Richter frank.richter at gmail.com <frank.richter at gmail.com>
Date: Mon, 1 Jan 2007 20:25:11 +0100
Subject: [PATCH] dbghelp: Search for .gnu_debuglink file

---
 dlls/dbghelp/elf_module.c |   61 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index 9a90d43..38cfee5 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -193,7 +193,6 @@ static BOOL elf_map_file(const char* fil
     Elf32_Phdr          phdr;
     unsigned            tmp, page_mask = getpagesize() - 1;
 
-
     fmap->fd = -1;
     fmap->with_crc = 0;
 
@@ -772,6 +771,48 @@ #undef UPDC32
 }
 
 /******************************************************************
+ *		locate_debug_link
+ *
+ * Locate a filename from a .gnu_debuglink section, using the same
+ * strategy as gdb:
+ * "If the full name of the directory containing the executable is
+ * execdir, and the executable has a debug link that specifies the
+ * name debugfile, then GDB will automatically search for the
+ * debugging information file in three places:
+ *  - the directory containing the executable file (that is, it
+ *    will look for a file named `execdir/debugfile',
+ *  - a subdirectory of that directory named `.debug' (that is, the
+ *    file `execdir/.debug/debugfile', and
+ *  - a subdirectory of the global debug file directory that includes 
+ *    the executable's full path, and the name from the link (that is,
+ *    the file `globaldebugdir/execdir/debugfile', where globaldebugdir
+ *    is the global debug file directory, and execdir has been turned
+ *    into a relative path)." (from GDB manual)
+ */
+static char* locate_debug_link (const char* filename, const char* moduleDir)
+{
+    static const char globalDebugDir[] = "/usr/lib/debug";
+    const size_t moduleDirLen = strlen (moduleDir);
+    const size_t globalDebugDirLen = strlen (globalDebugDir);
+    struct stat statbuf;
+
+    char* p = HeapAlloc (GetProcessHeap(), 0, 
+        moduleDirLen + 1 + max (6, globalDebugDirLen) + 1 + strlen (filename)+1);
+
+    sprintf (p, "%s/%s", moduleDir, filename);
+    if (stat(p, &statbuf) != -1 && !S_ISDIR(statbuf.st_mode)) return p;
+
+    sprintf (p, "%s/.debug/%s", moduleDir, filename);
+    if (stat(p, &statbuf) != -1 && !S_ISDIR(statbuf.st_mode)) return p;
+
+    sprintf (p, "%s/%s/%s", globalDebugDir, moduleDir, filename);
+    if (stat(p, &statbuf) != -1 && !S_ISDIR(statbuf.st_mode)) return p;
+
+    strcpy (p, filename);
+    return p;
+}
+
+/******************************************************************
  *		elf_load_debug_info_from_map
  *
  * Loads the symbolic information from ELF module which mapping is described
@@ -937,7 +978,15 @@ static BOOL elf_load_debug_info_from_map
         if (debuglink_sect != -1)
         {
             const char* dbg_link;
+            char* link_file;
             struct elf_file_map fmap_link;
+            char* moduleDir;
+            char* slash;
+
+            moduleDir = HeapAlloc (GetProcessHeap(), 0, strlen (module->module.LoadedImageName) + 1);
+            strcpy (moduleDir, module->module.LoadedImageName);
+            slash = strrchr (moduleDir, '/');
+            if (slash != 0) *slash = 0;
 
             dbg_link = elf_map_section(fmap, debuglink_sect);
             /* The content of a debug link section is:
@@ -946,22 +995,26 @@ static BOOL elf_load_debug_info_from_map
              * 2/ padding on 4 byte boundary
              * 3/ CRC of the linked ELF file
              */
-            if (dbg_link != ELF_NO_MAP && elf_map_file(dbg_link, &fmap_link))
+            if (dbg_link != ELF_NO_MAP 
+                && elf_map_file((link_file = locate_debug_link (dbg_link, moduleDir)), &fmap_link))
             {
+                TRACE("Located debug information file %s at %s\n", dbg_link, link_file);
                 fmap_link.crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3));
                 fmap_link.with_crc = 1;
                 lret = elf_load_debug_info_from_map(module, &fmap_link, pool,
                                                     ht_symtab);
                 if (lret)
-                    strcpy(module->module.LoadedPdbName, dbg_link);
+                    strcpy(module->module.LoadedPdbName, link_file);
                 else
-                    WARN("Couldn't load debug information from %s\n", dbg_link);
+                    WARN("Couldn't load debug information from %s\n", link_file);
                 ret = ret || lret;
+                HeapFree (GetProcessHeap(), 0, link_file);
             }
             else
                 WARN("Couldn't load linked debug file for %s\n",
                      module->module.ModuleName);
             elf_unmap_file(&fmap_link);
+            HeapFree (GetProcessHeap(), 0, moduleDir);
         }
     }
     if (strstr(module->module.ModuleName, "<elf>") ||
-- 
1.4.2.4



More information about the wine-patches mailing list