From a34ec4a961503e1ceb6c6c3ce0b59911960b8fa1 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Thu, 9 Jan 2014 05:08:24 +0000 Subject: llvm-dwarfdump: type unit dwo support git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198850 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/DebugInfo/DIContext.h | 1 + lib/DebugInfo/DWARFContext.cpp | 39 ++++++++++++++++++++++++++++++--- lib/DebugInfo/DWARFContext.h | 24 ++++++++++++++++++++ tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 1 + 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h index a1a4642103..37f2a260ae 100644 --- a/include/llvm/DebugInfo/DIContext.h +++ b/include/llvm/DebugInfo/DIContext.h @@ -105,6 +105,7 @@ enum DIDumpType { DIDT_Info, DIDT_InfoDwo, DIDT_Types, + DIDT_TypesDwo, DIDT_Line, DIDT_Loc, DIDT_Ranges, diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index e8c47802a5..b725619d8e 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -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 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()) { diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h index e74b5baaa0..9bac69d6e5 100644 --- a/lib/DebugInfo/DWARFContext.h +++ b/lib/DebugInfo/DWARFContext.h @@ -38,6 +38,7 @@ class DWARFContext : public DIContext { OwningPtr DebugFrame; SmallVector DWOCUs; + SmallVector DWOTUs; OwningPtr 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() { diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index 413a50b9b9..7c6cc68fb9 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -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"), -- cgit v1.2.3