[llvm] r303609 - libDebugInfo: Support symbolizing using DWP files

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Mon May 22 23:48:54 PDT 2017


Author: dblaikie
Date: Tue May 23 01:48:53 2017
New Revision: 303609

URL: http://llvm.org/viewvc/llvm-project?rev=303609&view=rev
Log:
libDebugInfo: Support symbolizing using DWP files

Added:
    llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o
    llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o.dwp
Modified:
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
    llvm/trunk/test/DebugInfo/llvm-symbolizer.test

Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h?rev=303609&r1=303608&r2=303609&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h Tue May 23 01:48:53 2017
@@ -76,6 +76,8 @@ class DWARFContext : public DIContext {
     std::unique_ptr<DWARFContext> Context;
   };
   StringMap<std::weak_ptr<DWOFile>> DWOFiles;
+  std::weak_ptr<DWOFile> DWP;
+  bool CheckedForDWP = false;
 
   /// Read compile units from the debug_info section (if necessary)
   /// and store them in CUs.
@@ -171,6 +173,8 @@ public:
     return DWOCUs[index].get();
   }
 
+  DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
+
   /// Get a DIE given an exact offset.
   DWARFDie getDIEForOffset(uint32_t Offset);
 
@@ -212,6 +216,7 @@ public:
   DIInliningInfo getInliningInfoForAddress(uint64_t Address,
       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
 
+  virtual StringRef getFileName() const = 0;
   virtual bool isLittleEndian() const = 0;
   virtual uint8_t getAddressSize() const = 0;
   virtual const DWARFSection &getInfoSection() = 0;
@@ -271,6 +276,7 @@ private:
 class DWARFContextInMemory : public DWARFContext {
   virtual void anchor();
 
+  StringRef FileName;
   bool IsLittleEndian;
   uint8_t AddressSize;
   DWARFSection InfoSection;
@@ -324,6 +330,7 @@ public:
                        uint8_t AddrSize,
                        bool isLittleEndian = sys::IsLittleEndianHost);
 
+  StringRef getFileName() const override { return FileName; }
   bool isLittleEndian() const override { return IsLittleEndian; }
   uint8_t getAddressSize() const override { return AddressSize; }
   const DWARFSection &getInfoSection() override { return InfoSection; }

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=303609&r1=303608&r2=303609&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Tue May 23 01:48:53 2017
@@ -287,6 +287,15 @@ void DWARFContext::dump(raw_ostream &OS,
                      getStringSection(), isLittleEndian());
 }
 
+DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
+  // FIXME: Improve this for the case where this DWO file is really a DWP file
+  // with an index - use the index for lookup instead of a linear search.
+  for (const auto &DWOCU : dwo_compile_units())
+    if (DWOCU->getDWOId() == Hash)
+      return DWOCU.get();
+  return nullptr;
+}
+
 DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
   parseCompileUnits();
   if (auto *CU = CUs.getUnitForOffset(Offset))
@@ -899,22 +908,47 @@ DWARFContext::getInliningInfoForAddress(
 
 std::shared_ptr<DWARFContext>
 DWARFContext::getDWOContext(StringRef AbsolutePath) {
-  auto &Entry = DWOFiles[AbsolutePath];
-  if (auto S = Entry.lock()) {
+  if (auto S = DWP.lock()) {
     DWARFContext *Ctxt = S->Context.get();
     return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
   }
 
-  auto S = std::make_shared<DWOFile>();
-  auto Obj = object::ObjectFile::createObjectFile(AbsolutePath);
+  std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
+
+  if (auto S = Entry->lock()) {
+    DWARFContext *Ctxt = S->Context.get();
+    return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
+  }
+
+  SmallString<128> DWPName;
+  Expected<OwningBinary<ObjectFile>> Obj = [&] {
+    if (!CheckedForDWP) {
+      (getFileName() + ".dwp").toVector(DWPName);
+      auto Obj = object::ObjectFile::createObjectFile(DWPName);
+      if (Obj) {
+        Entry = &DWP;
+        return Obj;
+      } else {
+        CheckedForDWP = true;
+        // TODO: Should this error be handled (maybe in a high verbosity mode)
+        // before falling back to .dwo files?
+        consumeError(Obj.takeError());
+      }
+    }
+
+    return object::ObjectFile::createObjectFile(AbsolutePath);
+  }();
+
   if (!Obj) {
     // TODO: Actually report errors helpfully.
     consumeError(Obj.takeError());
     return nullptr;
   }
+
+  auto S = std::make_shared<DWOFile>();
   S->File = std::move(Obj.get());
   S->Context = llvm::make_unique<DWARFContextInMemory>(*S->File.getBinary());
-  Entry = S;
+  *Entry = S;
   auto *Ctxt = S->Context.get();
   return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
 }
@@ -1011,8 +1045,8 @@ Error DWARFContextInMemory::maybeDecompr
 }
 
 DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
-    const LoadedObjectInfo *L)
-    : IsLittleEndian(Obj.isLittleEndian()),
+                                           const LoadedObjectInfo *L)
+    : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()),
       AddressSize(Obj.getBytesInAddress()) {
   for (const SectionRef &Section : Obj.sections()) {
     StringRef name;

Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=303609&r1=303608&r2=303609&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Tue May 23 01:48:53 2017
@@ -274,13 +274,10 @@ bool DWARFUnit::parseDWO() {
   if (!DWOContext)
     return false;
 
-  for (const auto &DWOCU : DWOContext->dwo_compile_units())
-    if (DWOCU->getDWOId() == DWOId) {
-      DWO = std::shared_ptr<DWARFUnit>(std::move(DWOContext), DWOCU.get());
-      break;
-    }
-  if (!DWO)
+  DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
+  if (!DWOCU)
     return false;
+  DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
   // Share .debug_addr and .debug_ranges section with compile unit in .dwo
   DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
   auto DWORangesBase = UnitDie.getRangesBaseAttribute();

Added: llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o?rev=303609&view=auto
==============================================================================
Binary files llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o (added) and llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o Tue May 23 01:48:53 2017 differ

Added: llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o.dwp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o.dwp?rev=303609&view=auto
==============================================================================
Binary files llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o.dwp (added) and llvm/trunk/test/DebugInfo/Inputs/split-dwarf-dwp.o.dwp Tue May 23 01:48:53 2017 differ

Modified: llvm/trunk/test/DebugInfo/llvm-symbolizer.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/llvm-symbolizer.test?rev=303609&r1=303608&r2=303609&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/llvm-symbolizer.test (original)
+++ llvm/trunk/test/DebugInfo/llvm-symbolizer.test Tue May 23 01:48:53 2017
@@ -27,6 +27,9 @@ RUN: cp %p/Inputs/split-dwarf-multiple-c
 RUN: echo "%p/Inputs/split-dwarf-multiple-cu.o 0x4" >> %t.input
 RUN: cp %p/Inputs/split-dwarf-addr-object-relocation.dwo %T
 RUN: echo "%p/Inputs/split-dwarf-addr-object-relocation.o 0x14" >> %t.input
+RUN: cp %p/Inputs/split-dwarf-dwp.o %T
+RUN: cp %p/Inputs/split-dwarf-dwp.o.dwp %T
+RUN: echo "%T/split-dwarf-dwp.o 0x4" >> %t.input
 
 RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \
 RUN:    --default-arch=i386 < %t.input | FileCheck --check-prefix=CHECK --check-prefix=SPLIT --check-prefix=DWO %s
@@ -147,6 +150,11 @@ CHECK-NEXT: split-dwarf-addr-object-relo
 CHECK-NEXT: f3
 CHECK-NEXT: split-dwarf-addr-object-relocation.cpp:6:0
 
+CHECK:      f2
+CHECK-NEXT: split-dwarf-dwp.cpp:3:3
+CHECK-NEXT: f3
+CHECK-NEXT: split-dwarf-dwp.cpp:6:0
+
 RUN: echo "unexisting-file 0x1234" > %t.input2
 RUN: llvm-symbolizer < %t.input2 2>&1 | FileCheck %s --check-prefix=MISSING-FILE
 




More information about the llvm-commits mailing list