llvm-dwarfdump: type unit dwo support
authorDavid Blaikie <dblaikie@gmail.com>
Thu, 9 Jan 2014 05:08:24 +0000 (05:08 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Thu, 9 Jan 2014 05:08:24 +0000 (05:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198850 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/DIContext.h
lib/DebugInfo/DWARFContext.cpp
lib/DebugInfo/DWARFContext.h
tools/llvm-dwarfdump/llvm-dwarfdump.cpp

index a1a4642103d88d4f528305365ae5509844dd7966..37f2a260ae61b14098470178f3db26cffd1c11ba 100644 (file)
@@ -105,6 +105,7 @@ enum DIDumpType {
   DIDT_Info,
   DIDT_InfoDwo,
   DIDT_Types,
+  DIDT_TypesDwo,
   DIDT_Line,
   DIDT_Loc,
   DIDT_Ranges,
index e8c47802a58efec8519e4aa802c901ce1cecde2e..b725619d8e2528f16def360a984676717979a480 100644 (file)
@@ -91,6 +91,13 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType) {
       getTypeUnitAtIndex(i)->dump(OS);
   }
 
+  if (DumpType == DIDT_All || DumpType == DIDT_TypesDwo)
+    if (getNumDWOTypeUnits()) {
+      OS << "\n.debug_types.dwo contents:\n";
+      for (unsigned i = 0, e = getNumDWOTypeUnits(); i != e; ++i)
+        getDWOTypeUnitAtIndex(i)->dump(OS);
+    }
+
   if (DumpType == DIDT_All || DumpType == DIDT_Loc) {
     OS << "\n.debug_loc contents:\n";
     getDebugLoc()->dump(OS);
@@ -333,6 +340,27 @@ void DWARFContext::parseDWOCompileUnits() {
   }
 }
 
+void DWARFContext::parseDWOTypeUnits() {
+  const TypeSectionMap &Sections = getTypesDWOSections();
+  for (TypeSectionMap::const_iterator I = Sections.begin(), E = Sections.end();
+       I != E; ++I) {
+    uint32_t offset = 0;
+    const DataExtractor &DIData =
+        DataExtractor(I->second.Data, isLittleEndian(), 0);
+    while (DIData.isValidOffset(offset)) {
+      OwningPtr<DWARFTypeUnit> TU(new DWARFTypeUnit(
+          getDebugAbbrevDWO(), I->second.Data, getAbbrevDWOSection(),
+          getRangeDWOSection(), getStringDWOSection(),
+          getStringOffsetDWOSection(), getAddrSection(), &I->second.Relocs,
+          isLittleEndian()));
+      if (!TU->extract(DIData, &offset))
+        break;
+      DWOTUs.push_back(TU.take());
+      offset = DWOTUs.back()->getNextUnitOffset();
+    }
+  }
+}
+
 namespace {
   struct OffsetComparator {
     bool operator()(const DWARFCompileUnit *LHS,
@@ -632,6 +660,8 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
       // Find debug_types data by section rather than name as there are
       // multiple, comdat grouped, debug_types sections.
       TypesSections[*i].Data = data;
+    } else if (name == "debug_types.dwo") {
+      TypesDWOSections[*i].Data = data;
     }
 
     section_iterator RelocatedSection = i->getRelocatedSection();
@@ -652,11 +682,14 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
         .Case("debug_line", &LineSection.Relocs)
         .Default(0);
     if (!Map) {
-      if (RelSecName != "debug_types")
-        continue;
       // Find debug_types relocs by section rather than name as there are
       // multiple, comdat grouped, debug_types sections.
-      Map = &TypesSections[*RelocatedSection].Relocs;
+      if (RelSecName == "debug_types")
+        Map = &TypesSections[*RelocatedSection].Relocs;
+      else if (RelSecName == "debug_types.dwo")
+        Map = &TypesDWOSections[*RelocatedSection].Relocs;
+      else
+        continue;
     }
 
     if (i->begin_relocations() != i->end_relocations()) {
index e74b5baaa0a32b977ad61f1179fd91382ce30d4c..9bac69d6e5225ccada077d2cec1334f131f20c13 100644 (file)
@@ -38,6 +38,7 @@ class DWARFContext : public DIContext {
   OwningPtr<DWARFDebugFrame> DebugFrame;
 
   SmallVector<DWARFCompileUnit *, 1> DWOCUs;
+  SmallVector<DWARFTypeUnit *, 1> DWOTUs;
   OwningPtr<DWARFDebugAbbrev> AbbrevDWO;
 
   DWARFContext(DWARFContext &) LLVM_DELETED_FUNCTION;
@@ -53,6 +54,10 @@ class DWARFContext : public DIContext {
   /// DWOCUs.
   void parseDWOCompileUnits();
 
+  /// Read type units from the debug_types.dwo section and store them in
+  /// DWOTUs.
+  void parseDWOTypeUnits();
+
 public:
   struct Section {
     StringRef Data;
@@ -89,6 +94,13 @@ public:
     return DWOCUs.size();
   }
 
+  /// Get the number of compile units in the DWO context.
+  unsigned getNumDWOTypeUnits() {
+    if (DWOTUs.empty())
+      parseDWOTypeUnits();
+    return DWOTUs.size();
+  }
+
   /// Get the compile unit at the specified index for this compile unit.
   DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
     if (CUs.empty())
@@ -110,6 +122,13 @@ public:
     return DWOCUs[index];
   }
 
+  /// Get the type unit at the specified index for the DWO type units.
+  DWARFTypeUnit *getDWOTypeUnitAtIndex(unsigned index) {
+    if (DWOTUs.empty())
+      parseDWOTypeUnits();
+    return DWOTUs[index];
+  }
+
   /// Get a pointer to the parsed DebugAbbrev object.
   const DWARFDebugAbbrev *getDebugAbbrev();
 
@@ -156,6 +175,7 @@ public:
 
   // Sections for DWARF5 split dwarf proposal.
   virtual const Section &getInfoDWOSection() = 0;
+  virtual const TypeSectionMap &getTypesDWOSections() = 0;
   virtual StringRef getAbbrevDWOSection() = 0;
   virtual StringRef getStringDWOSection() = 0;
   virtual StringRef getStringOffsetDWOSection() = 0;
@@ -197,6 +217,7 @@ class DWARFContextInMemory : public DWARFContext {
 
   // Sections for DWARF5 split dwarf proposal.
   Section InfoDWOSection;
+  TypeSectionMap TypesDWOSections;
   StringRef AbbrevDWOSection;
   StringRef StringDWOSection;
   StringRef StringOffsetDWOSection;
@@ -226,6 +247,9 @@ public:
 
   // Sections for DWARF5 split dwarf proposal.
   virtual const Section &getInfoDWOSection() { return InfoDWOSection; }
+  virtual const TypeSectionMap &getTypesDWOSections() {
+    return TypesDWOSections;
+  }
   virtual StringRef getAbbrevDWOSection() { return AbbrevDWOSection; }
   virtual StringRef getStringDWOSection() { return StringDWOSection; }
   virtual StringRef getStringOffsetDWOSection() {
index 413a50b9b90b1465b78a21ac9d9fe2d6e8dccfb6..7c6cc68fb9f261af65ad06812f35b4e0ab06dd39 100644 (file)
@@ -63,6 +63,7 @@ DumpType("debug-dump", cl::init(DIDT_All),
         clEnumValN(DIDT_Info, "info", ".debug_info"),
         clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"),
         clEnumValN(DIDT_Types, "types", ".debug_types"),
+        clEnumValN(DIDT_TypesDwo, "types.dwo", ".debug_types.dwo"),
         clEnumValN(DIDT_Line, "line", ".debug_line"),
         clEnumValN(DIDT_Loc, "loc", ".debug_loc"),
         clEnumValN(DIDT_Frames, "frames", ".debug_frame"),