summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h102
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h28
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp53
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp21
4 files changed, 119 insertions, 85 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index 236cc29a8f3..96e77d95e55 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -57,8 +57,7 @@ enum class ErrorPolicy { Halt, Continue };
/// This data structure is the top level entity that deals with dwarf debug
/// information parsing. The actual data is supplied through DWARFObj.
class DWARFContext : public DIContext {
- DWARFUnitVector CUs;
- DWARFUnitVector TUs;
+ DWARFUnitVector NormalUnits;
std::unique_ptr<DWARFUnitIndex> CUIndex;
std::unique_ptr<DWARFGdbIndex> GdbIndex;
std::unique_ptr<DWARFUnitIndex> TUIndex;
@@ -75,8 +74,7 @@ class DWARFContext : public DIContext {
std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
std::unique_ptr<AppleAcceleratorTable> AppleObjC;
- DWARFUnitVector DWOCUs;
- DWARFUnitVector DWOTUs;
+ DWARFUnitVector DWOUnits;
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
@@ -95,22 +93,17 @@ class DWARFContext : public DIContext {
std::unique_ptr<MCRegisterInfo> RegInfo;
/// Read compile units from the debug_info section (if necessary)
- /// and store them in CUs.
- void parseCompileUnits();
-
- /// Read type units from the debug_types sections (if necessary)
- /// and store them in TUs.
- void parseTypeUnits();
+ /// and type units from the debug_types sections (if necessary)
+ /// and store them in NormalUnits.
+ void parseNormalUnits();
/// Read compile units from the debug_info.dwo section (if necessary)
- /// and store them in DWOCUs.
- void parseDWOCompileUnits();
-
- /// Read type units from the debug_types.dwo section (if necessary)
- /// and store them in DWOTUs.
- void parseDWOTypeUnits();
+ /// and type units from the debug_types.dwo section (if necessary)
+ /// and store them in DWOUnits.
+ /// If \p Lazy is true, set up to parse but don't actually parse them.
+ enum { EagerParse = false, LazyParse = true };
+ void parseDWOUnits(bool Lazy = false);
-protected:
std::unique_ptr<const DWARFObject> DObj;
public:
@@ -142,64 +135,81 @@ public:
using cu_iterator_range = DWARFUnitVector::iterator_range;
using tu_iterator_range = DWARFUnitVector::iterator_range;
- /// Get compile units in this context.
- cu_iterator_range compile_units() {
- parseCompileUnits();
- return cu_iterator_range(CUs.begin(), CUs.end());
+ /// Get units from .debug_info in this context.
+ cu_iterator_range info_section_units() {
+ parseNormalUnits();
+ return cu_iterator_range(NormalUnits.begin(),
+ NormalUnits.begin() +
+ NormalUnits.getNumInfoUnits());
}
+ /// Get units from .debug_types in this context.
+ tu_iterator_range types_section_units() {
+ parseNormalUnits();
+ return tu_iterator_range(
+ NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
+ }
+
+ /// Get compile units in this context.
+ cu_iterator_range compile_units() { return info_section_units(); }
+
/// Get type units in this context.
- tu_iterator_range type_units() {
- parseTypeUnits();
- return tu_iterator_range(TUs.begin(), TUs.end());
+ tu_iterator_range type_units() { return types_section_units(); }
+
+ /// Get units from .debug_info..dwo in the DWO context.
+ cu_iterator_range dwo_info_section_units() {
+ parseDWOUnits();
+ return cu_iterator_range(DWOUnits.begin(),
+ DWOUnits.begin() + DWOUnits.getNumInfoUnits());
}
- /// Get compile units in the DWO context.
- cu_iterator_range dwo_compile_units() {
- parseDWOCompileUnits();
- return cu_iterator_range(DWOCUs.begin(), DWOCUs.end());
+ /// Get units from .debug_types.dwo in the DWO context.
+ tu_iterator_range dwo_types_section_units() {
+ parseDWOUnits();
+ return tu_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
+ DWOUnits.end());
}
+ /// Get compile units in the DWO context.
+ cu_iterator_range dwo_compile_units() { return dwo_info_section_units(); }
+
/// Get type units in the DWO context.
- tu_iterator_range dwo_type_units() {
- parseDWOTypeUnits();
- return tu_iterator_range(DWOTUs.begin(), DWOTUs.end());
- }
+ tu_iterator_range dwo_type_units() { return dwo_types_section_units(); }
/// Get the number of compile units in this context.
unsigned getNumCompileUnits() {
- parseCompileUnits();
- return CUs.size();
+ parseNormalUnits();
+ return NormalUnits.getNumInfoUnits();
}
- /// Get the number of compile units in this context.
+ /// Get the number of type units in this context.
unsigned getNumTypeUnits() {
- parseTypeUnits();
- return TUs.size();
+ parseNormalUnits();
+ return NormalUnits.getNumTypesUnits();
}
/// Get the number of compile units in the DWO context.
unsigned getNumDWOCompileUnits() {
- parseDWOCompileUnits();
- return DWOCUs.size();
+ parseDWOUnits();
+ return DWOUnits.getNumInfoUnits();
}
- /// Get the number of compile units in the DWO context.
+ /// Get the number of type units in the DWO context.
unsigned getNumDWOTypeUnits() {
- parseDWOTypeUnits();
- return DWOTUs.size();
+ parseDWOUnits();
+ return DWOUnits.getNumTypesUnits();
}
/// Get the unit at the specified index.
DWARFUnit *getUnitAtIndex(unsigned index) {
- parseCompileUnits();
- return CUs[index].get();
+ parseNormalUnits();
+ return NormalUnits[index].get();
}
/// Get the unit at the specified index for the DWO units.
DWARFUnit *getDWOUnitAtIndex(unsigned index) {
- parseDWOCompileUnits();
- return DWOCUs[index].get();
+ parseDWOUnits();
+ return DWOUnits[index].get();
}
DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index 8e8c96c72bd..0908504f000 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -104,10 +104,13 @@ public:
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
DWARFSectionKind Kind);
-/// Describes one section's Units.
+/// Describe a collection of units. Intended to hold all units either from
+/// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo.
class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
- std::function<std::unique_ptr<DWARFUnit>(uint32_t, const DWARFSection *)>
+ std::function<std::unique_ptr<DWARFUnit>(uint32_t, DWARFSectionKind,
+ const DWARFSection *)>
Parser;
+ unsigned NumInfoUnits = 0;
public:
using UnitVector = SmallVectorImpl<std::unique_ptr<DWARFUnit>>;
@@ -116,11 +119,31 @@ public:
DWARFUnit *getUnitForOffset(uint32_t Offset) const;
DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
+
+ /// Read units from a .debug_info or .debug_types section. Calls made
+ /// before finishedInfoUnits() are assumed to be for .debug_info sections,
+ /// calls after finishedInfoUnits() are for .debug_types sections. Caller
+ /// must not mix calls to addUnitsForSection and addUnitsForDWOSection.
void addUnitsForSection(DWARFContext &C, const DWARFSection &Section,
DWARFSectionKind SectionKind);
+ /// Read units from a .debug_info.dwo or .debug_types.dwo section. Calls
+ /// made before finishedInfoUnits() are assumed to be for .debug_info.dwo
+ /// sections, calls after finishedInfoUnits() are for .debug_types.dwo
+ /// sections. Caller must not mix calls to addUnitsForSection and
+ /// addUnitsForDWOSection.
void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection,
DWARFSectionKind SectionKind, bool Lazy = false);
+ /// Returns number of all units held by this instance.
+ unsigned getNumUnits() { return size(); }
+ /// Returns number of units from all .debug_info[.dwo] sections.
+ unsigned getNumInfoUnits() { return NumInfoUnits; }
+ /// Returns number of units from all .debug_types[.dwo] sections.
+ unsigned getNumTypesUnits() { return size() - NumInfoUnits; }
+ /// Indicate that parsing .debug_info[.dwo] is done, and remaining units
+ /// will be from .debug_types[.dwo].
+ void finishedInfoUnits() { NumInfoUnits = size(); }
+
private:
void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj,
const DWARFSection &Section, const DWARFDebugAbbrev *DA,
@@ -238,6 +261,7 @@ public:
virtual ~DWARFUnit();
DWARFContext& getContext() const { return Context; }
+ const DWARFSection &getInfoSection() const { return InfoSection; }
uint32_t getOffset() const { return Header.getOffset(); }
const dwarf::FormParams &getFormParams() const {
return Header.getFormParams();
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 79e463da824..683da066422 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -351,9 +351,9 @@ void DWARFContext::dump(
}
};
dumpDebugInfo(Explicit, ".debug_info", DObj->getInfoSection(),
- compile_units());
+ info_section_units());
dumpDebugInfo(ExplicitDWO, ".debug_info.dwo", DObj->getInfoDWOSection(),
- dwo_compile_units());
+ dwo_info_section_units());
auto dumpDebugType = [&](const char *Name, tu_iterator_range TUs) {
OS << '\n' << Name << " contents:\n";
@@ -367,9 +367,9 @@ void DWARFContext::dump(
};
if ((DumpType & DIDT_DebugTypes)) {
if (Explicit || getNumTypeUnits())
- dumpDebugType(".debug_types", type_units());
+ dumpDebugType(".debug_types", types_section_units());
if (ExplicitDWO || getNumDWOTypeUnits())
- dumpDebugType(".debug_types.dwo", dwo_type_units());
+ dumpDebugType(".debug_types.dwo", dwo_types_section_units());
}
if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
@@ -581,13 +581,12 @@ void DWARFContext::dump(
}
DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
- if (DWOCUs.empty())
- DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
- true);
+ parseDWOUnits(LazyParse);
if (const auto &CUI = getCUIndex()) {
if (const auto *R = CUI.getFromHash(Hash))
- return dyn_cast_or_null<DWARFCompileUnit>(DWOCUs.getUnitForIndexEntry(*R));
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ DWOUnits.getUnitForIndexEntry(*R));
return nullptr;
}
@@ -612,8 +611,8 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
}
DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
- parseCompileUnits();
- if (auto *CU = CUs.getUnitForOffset(Offset))
+ parseNormalUnits();
+ if (auto *CU = NormalUnits.getUnitForOffset(Offset))
return CU->getDIEForOffset(Offset);
return DWARFDie();
}
@@ -842,37 +841,31 @@ Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
RecoverableErrorCallback);
}
-void DWARFContext::parseCompileUnits() {
- if (!CUs.empty())
- return;
- CUs.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
-}
-
-void DWARFContext::parseTypeUnits() {
- if (!TUs.empty())
+void DWARFContext::parseNormalUnits() {
+ if (!NormalUnits.empty())
return;
+ NormalUnits.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
+ NormalUnits.finishedInfoUnits();
DObj->forEachTypesSections([&](const DWARFSection &S) {
- TUs.addUnitsForSection(*this, S, DW_SECT_TYPES);
+ NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
});
}
-void DWARFContext::parseDWOCompileUnits() {
- if (!DWOCUs.empty())
- return;
- DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO);
-}
-
-void DWARFContext::parseDWOTypeUnits() {
- if (!DWOTUs.empty())
+void DWARFContext::parseDWOUnits(bool Lazy) {
+ if (!DWOUnits.empty())
return;
+ DWOUnits.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
+ Lazy);
+ DWOUnits.finishedInfoUnits();
DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
- DWOTUs.addUnitsForDWOSection(*this, S, DW_SECT_TYPES);
+ DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
});
}
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
- parseCompileUnits();
- return dyn_cast_or_null<DWARFCompileUnit>(CUs.getUnitForOffset(Offset));
+ parseNormalUnits();
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ NormalUnits.getUnitForOffset(Offset));
}
DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 671fdeb111a..408eeb4070d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -62,16 +62,16 @@ void DWARFUnitVector::addUnitsImpl(
DWARFDataExtractor Data(Obj, Section, LE, 0);
// Lazy initialization of Parser, now that we have all section info.
if (!Parser) {
- const DWARFUnitIndex *Index = nullptr;
- if (IsDWO)
- Index = &getDWARFUnitIndex(Context, SectionKind);
Parser = [=, &Context, &Obj, &Section, &SOS, &LS](
- uint32_t Offset,
+ uint32_t Offset, DWARFSectionKind SectionKind,
const DWARFSection *CurSection) -> std::unique_ptr<DWARFUnit> {
const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
if (!Data.isValidOffset(Offset))
return nullptr;
+ const DWARFUnitIndex *Index = nullptr;
+ if (IsDWO)
+ Index = &getDWARFUnitIndex(Context, SectionKind);
DWARFUnitHeader Header;
if (!Header.extract(Context, Data, &Offset, SectionKind, Index))
return nullptr;
@@ -89,14 +89,21 @@ void DWARFUnitVector::addUnitsImpl(
}
if (Lazy)
return;
+ // Find a reasonable insertion point within the vector. We skip over
+ // (a) units from a different section, (b) units from the same section
+ // but with lower offset-within-section. This keeps units in order
+ // within a section, although not necessarily within the object file,
+ // even if we do lazy parsing.
auto I = this->begin();
uint32_t Offset = 0;
while (Data.isValidOffset(Offset)) {
- if (I != this->end() && (*I)->getOffset() == Offset) {
+ if (I != this->end() &&
+ (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
++I;
continue;
}
- auto U = Parser(Offset, &Section);
+ auto U = Parser(Offset, SectionKind, &Section);
+ // If parsing failed, we're done with this section.
if (!U)
break;
Offset = U->getNextUnitOffset();
@@ -134,7 +141,7 @@ DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
if (!Parser)
return nullptr;
- auto U = Parser(Offset, nullptr);
+ auto U = Parser(Offset, DW_SECT_INFO, nullptr);
if (!U)
U = nullptr;
OpenPOWER on IntegriCloud