Module: wine Branch: master Commit: 867ebe4da0442214b1a514c5e33973d986d9c9a3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=867ebe4da0442214b1a514c5e3...
Author: Frank Richter frank.richter@gmail.com Date: Wed Jan 17 00:26:27 2007 +0100
dbghelp: Search for .gnu_debuglink file.
---
dlls/dbghelp/elf_module.c | 62 ++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 59 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c index 9b6b458..79feca5 100644 --- a/dlls/dbghelp/elf_module.c +++ b/dlls/dbghelp/elf_module.c @@ -784,6 +784,48 @@ static BOOL elf_load_debug_info_from_map struct hash_table* ht_symtab);
/****************************************************************** + * elf_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* elf_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_debuglink_parse * * Parses a .gnu_debuglink section and loads the debug info from @@ -803,22 +845,36 @@ static BOOL elf_debuglink_parse (struct BOOL ret = FALSE; const char* dbg_link = (char*)debuglink; struct elf_file_map fmap_link; + char* moduleDir; + char* link_file; + char* slash;
- if (elf_map_file(dbg_link, &fmap_link)) + moduleDir = HeapAlloc (GetProcessHeap(), 0, strlen (module->module.LoadedImageName) + 1); + strcpy (moduleDir, module->module.LoadedImageName); + slash = strrchr (moduleDir, '/'); + if (slash != 0) *slash = 0; + + link_file = elf_locate_debug_link (dbg_link, moduleDir); + TRACE("Located debug information file %s at %s\n", dbg_link, link_file); + + if (elf_map_file(link_file, &fmap_link)) { fmap_link.crc = *(const DWORD*)(dbg_link + ((DWORD_PTR)(strlen(dbg_link) + 4) & ~3)); fmap_link.with_crc = 1; ret = elf_load_debug_info_from_map(module, &fmap_link, pool, ht_symtab); if (ret) - 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); elf_unmap_file(&fmap_link); } else WARN("Couldn't map %s\n", dbg_link);
+ HeapFree (GetProcessHeap(), 0, link_file); + HeapFree (GetProcessHeap(), 0, moduleDir); + return ret; }