diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/DebugInfo/DWARFContext.cpp | 64 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARFUnit.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARFUnit.h | 33 |
3 files changed, 50 insertions, 62 deletions
diff --git a/llvm/lib/DebugInfo/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARFContext.cpp index 819fc142e50..39799f0b235 100644 --- a/llvm/lib/DebugInfo/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARFContext.cpp @@ -314,84 +314,28 @@ DWARFContext::getLineTableForUnit(DWARFUnit *cu) { } void DWARFContext::parseCompileUnits() { - if (!CUs.empty()) - return; - uint32_t offset = 0; - const DataExtractor &DIData = DataExtractor(getInfoSection().Data, - isLittleEndian(), 0); - while (DIData.isValidOffset(offset)) { - std::unique_ptr<DWARFCompileUnit> CU(new DWARFCompileUnit(*this, - getDebugAbbrev(), getInfoSection().Data, getRangeSection(), - getStringSection(), StringRef(), getAddrSection(), - &getInfoSection().Relocs, isLittleEndian(), CUs)); - if (!CU->extract(DIData, &offset)) { - break; - } - CUs.push_back(std::move(CU)); - offset = CUs.back()->getNextUnitOffset(); - } + CUs.parse(*this, getInfoSection().Data, getInfoSection().Relocs); } void DWARFContext::parseTypeUnits() { if (!TUs.empty()) return; for (const auto &I : getTypesSections()) { - uint32_t offset = 0; - const DataExtractor &DIData = - DataExtractor(I.second.Data, isLittleEndian(), 0); TUs.push_back(DWARFUnitSection<DWARFTypeUnit>()); - auto &TUS = TUs.back(); - while (DIData.isValidOffset(offset)) { - std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(*this, - getDebugAbbrev(), I.second.Data, getRangeSection(), - getStringSection(), StringRef(), getAddrSection(), - &I.second.Relocs, isLittleEndian(), TUS)); - if (!TU->extract(DIData, &offset)) - break; - TUS.push_back(std::move(TU)); - offset = TUS.back()->getNextUnitOffset(); - } + TUs.back().parse(*this, I.second.Data, I.second.Relocs); } } void DWARFContext::parseDWOCompileUnits() { - if (!DWOCUs.empty()) - return; - uint32_t offset = 0; - const DataExtractor &DIData = - DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0); - while (DIData.isValidOffset(offset)) { - std::unique_ptr<DWARFCompileUnit> DWOCU(new DWARFCompileUnit(*this, - getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(), - getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), - &getInfoDWOSection().Relocs, isLittleEndian(), DWOCUs)); - if (!DWOCU->extract(DIData, &offset)) { - break; - } - DWOCUs.push_back(std::move(DWOCU)); - offset = DWOCUs.back()->getNextUnitOffset(); - } + DWOCUs.parseDWO(*this, getInfoDWOSection().Data, getInfoDWOSection().Relocs); } void DWARFContext::parseDWOTypeUnits() { if (!DWOTUs.empty()) return; for (const auto &I : getTypesDWOSections()) { - uint32_t offset = 0; - const DataExtractor &DIData = - DataExtractor(I.second.Data, isLittleEndian(), 0); DWOTUs.push_back(DWARFUnitSection<DWARFTypeUnit>()); - auto &TUS = DWOTUs.back(); - while (DIData.isValidOffset(offset)) { - std::unique_ptr<DWARFTypeUnit> TU(new DWARFTypeUnit(*this, - getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(), - getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), - &I.second.Relocs, isLittleEndian(), TUS)); - if (!TU->extract(DIData, &offset)) - break; - TUS.push_back(std::move(TU)); - offset = TUS.back()->getNextUnitOffset(); - } + DWOTUs.back().parseDWO(*this, I.second.Data, I.second.Relocs); } } diff --git a/llvm/lib/DebugInfo/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARFUnit.cpp index faf385c1474..46a765c7046 100644 --- a/llvm/lib/DebugInfo/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARFUnit.cpp @@ -17,6 +17,21 @@ using namespace llvm; using namespace dwarf; + +void DWARFUnitSectionBase::parse(DWARFContext &C, StringRef SectionData, + const RelocAddrMap &Map) { + parseImpl(C, C.getDebugAbbrev(), SectionData, C.getRangeSection(), + C.getStringSection(), StringRef(), C.getAddrSection(), Map, + C.isLittleEndian()); +} + +void DWARFUnitSectionBase::parseDWO(DWARFContext &C, StringRef SectionData, + const RelocAddrMap &Map) { + parseImpl(C, C.getDebugAbbrevDWO(), SectionData, C.getRangeDWOSection(), + C.getStringDWOSection(), C.getStringOffsetDWOSection(), + C.getAddrSection(), Map, C.isLittleEndian()); +} + DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, const RelocAddrMap *M, bool LE, diff --git a/llvm/lib/DebugInfo/DWARFUnit.h b/llvm/lib/DebugInfo/DWARFUnit.h index 9762f65491b..a57bead4750 100644 --- a/llvm/lib/DebugInfo/DWARFUnit.h +++ b/llvm/lib/DebugInfo/DWARFUnit.h @@ -36,7 +36,15 @@ public: /// same section this Unit originated from. virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0; + void parse(DWARFContext &C, StringRef SectionData, const RelocAddrMap &Map); + void parseDWO(DWARFContext &C, StringRef SectionData, const RelocAddrMap &Map); + protected: + virtual void parseImpl(DWARFContext &Context, const DWARFDebugAbbrev *DA, + StringRef Section, StringRef RS, StringRef SS, + StringRef SOS, StringRef AOS, const RelocAddrMap &M, + bool isLittleEndian) = 0; + ~DWARFUnitSectionBase() {} }; @@ -52,10 +60,12 @@ class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>, } }; + bool Parsed; + public: - DWARFUnitSection() {} + DWARFUnitSection() : Parsed(false) {} DWARFUnitSection(DWARFUnitSection &&DUS) : - SmallVector<std::unique_ptr<UnitType>, 1>(std::move(DUS)) {} + SmallVector<std::unique_ptr<UnitType>, 1>(std::move(DUS)), Parsed(DUS.Parsed) {} typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector; typedef typename UnitVector::iterator iterator; @@ -68,6 +78,25 @@ public: return CU->get(); return nullptr; } + + private: + void parseImpl(DWARFContext &Context, const DWARFDebugAbbrev *DA, + StringRef Section, StringRef RS, StringRef SS, StringRef SOS, + StringRef AOS, const RelocAddrMap &M, bool LE) override { + if (Parsed) + return; + DataExtractor Data(Section, LE, 0); + uint32_t Offset = 0; + while (Data.isValidOffset(Offset)) { + auto U = make_unique<UnitType>(Context, DA, Section, RS, SS, SOS, AOS, &M, + Data.isLittleEndian(), *this); + if (!U->extract(Data, &Offset)) + break; + this->push_back(std::move(U)); + Offset = this->back()->getNextUnitOffset(); + } + Parsed = true; + } }; class DWARFUnit { |