[llvm] r188386 - llvm-symbolizer: add support for .gnu_debuglink section

Alexey Samsonov samsonov at google.com
Wed Aug 14 10:09:30 PDT 2013


Author: samsonov
Date: Wed Aug 14 12:09:30 2013
New Revision: 188386

URL: http://llvm.org/viewvc/llvm-project?rev=188386&view=rev
Log:
llvm-symbolizer: add support for .gnu_debuglink section

Added:
    llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test.elf-x86-64.debuglink   (with props)
Modified:
    llvm/trunk/test/DebugInfo/llvm-symbolizer.test
    llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp

Added: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test.elf-x86-64.debuglink
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test.elf-x86-64.debuglink?rev=188386&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test.elf-x86-64.debuglink
------------------------------------------------------------------------------
    svn:executable = *

Propchange: llvm/trunk/test/DebugInfo/Inputs/dwarfdump-test.elf-x86-64.debuglink
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: llvm/trunk/test/DebugInfo/llvm-symbolizer.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/llvm-symbolizer.test?rev=188386&r1=188385&r2=188386&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/llvm-symbolizer.test (original)
+++ llvm/trunk/test/DebugInfo/llvm-symbolizer.test Wed Aug 14 12:09:30 2013
@@ -1,4 +1,5 @@
 RUN: echo "%p/Inputs/dwarfdump-test.elf-x86-64 0x400559" > %t.input
+RUN: echo "%p/Inputs/dwarfdump-test.elf-x86-64.debuglink 0x400559" >> %t.input
 RUN: echo "%p/Inputs/dwarfdump-test.elf-x86-64 0x400436" >> %t.input
 RUN: echo "%p/Inputs/dwarfdump-test4.elf-x86-64 0x62c" >> %t.input
 RUN: echo "%p/Inputs/dwarfdump-inl-test.elf-x86-64 0x710" >> %t.input
@@ -12,6 +13,9 @@ RUN:    --default-arch=i386 < %t.input |
 
 CHECK:       main
 CHECK-NEXT: /tmp/dbginfo{{[/\\]}}dwarfdump-test.cc:16
+
+CHECK:       main
+CHECK-NEXT: /tmp/dbginfo{{[/\\]}}dwarfdump-test.cc:16
 
 CHECK:      _start
 

Modified: llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp?rev=188386&r1=188385&r2=188386&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp (original)
+++ llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp Wed Aug 14 12:09:30 2013
@@ -15,7 +15,10 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Object/MachO.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/Compression.h"
+#include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 
 #include <sstream>
@@ -215,6 +218,74 @@ static std::string getDarwinDWARFResourc
   return ResourceName.str();
 }
 
+static bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
+  OwningPtr<MemoryBuffer> MB;
+  if (MemoryBuffer::getFileOrSTDIN(Path, MB))
+    return false;
+  return !zlib::isAvailable() || CRCHash == zlib::crc32(MB->getBuffer());
+}
+
+static bool findDebugBinary(const std::string &OrigPath,
+                            const std::string &DebuglinkName, uint32_t CRCHash,
+                            std::string &Result) {
+  SmallString<16> OrigDir(OrigPath);
+  llvm::sys::path::remove_filename(OrigDir);
+  SmallString<16> DebugPath = OrigDir;
+  // Try /path/to/original_binary/debuglink_name
+  llvm::sys::path::append(DebugPath, DebuglinkName);
+  if (checkFileCRC(DebugPath, CRCHash)) {
+    Result = DebugPath.str();
+    return true;
+  }
+  // Try /path/to/original_binary/.debug/debuglink_name
+  DebugPath = OrigPath;
+  llvm::sys::path::append(DebugPath, ".debug", DebuglinkName);
+  if (checkFileCRC(DebugPath, CRCHash)) {
+    Result = DebugPath.str();
+    return true;
+  }
+  // Try /usr/lib/debug/path/to/original_binary/debuglink_name
+  DebugPath = "/usr/lib/debug";
+  llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir),
+                          DebuglinkName);
+  if (checkFileCRC(DebugPath, CRCHash)) {
+    Result = DebugPath.str();
+    return true;
+  }
+  return false;
+}
+
+static bool getGNUDebuglinkContents(const Binary *Bin, std::string &DebugName,
+                                    uint32_t &CRCHash) {
+  const ObjectFile *Obj = dyn_cast<ObjectFile>(Bin);
+  if (!Obj)
+    return false;
+  error_code EC;
+  for (section_iterator I = Obj->begin_sections(), E = Obj->end_sections();
+       I != E; I.increment(EC)) {
+    StringRef Name;
+    I->getName(Name);
+    Name = Name.substr(Name.find_first_not_of("._"));
+    if (Name == "gnu_debuglink") {
+      StringRef Data;
+      I->getContents(Data);
+      DataExtractor DE(Data, Obj->isLittleEndian(), 0);
+      uint32_t Offset = 0;
+      if (const char *DebugNameStr = DE.getCStr(&Offset)) {
+        // 4-byte align the offset.
+        Offset = (Offset + 3) & ~0x3;
+        if (DE.isValidOffsetForDataOfSize(Offset, 4)) {
+          DebugName = DebugNameStr;
+          CRCHash = DE.getU32(&Offset);
+          return true;
+        }
+      }
+      break;
+    }
+  }
+  return false;
+}
+
 LLVMSymbolizer::BinaryPair
 LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
   BinaryMapTy::iterator I = BinaryForPath.find(Path);
@@ -240,6 +311,18 @@ LLVMSymbolizer::getOrCreateBinary(const
         DbgBin = ParsedDbgBinary.take();
         ParsedBinariesAndObjects.push_back(DbgBin);
       }
+    }
+    // Try to locate the debug binary using .gnu_debuglink section.
+    if (DbgBin == 0) {
+      std::string DebuglinkName;
+      uint32_t CRCHash;
+      std::string DebugBinaryPath;
+      if (getGNUDebuglinkContents(Bin, DebuglinkName, CRCHash) &&
+          findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath) &&
+          !error(createBinary(DebugBinaryPath, ParsedDbgBinary))) {
+        DbgBin = ParsedDbgBinary.take();
+        ParsedBinariesAndObjects.push_back(DbgBin);
+      }
     }
   }
   if (DbgBin == 0)





More information about the llvm-commits mailing list