Index: lib/DebugInfo/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARFContext.cpp +++ lib/DebugInfo/DWARFContext.cpp @@ -314,84 +314,38 @@ } 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 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, getDebugAbbrev(), getInfoSection().Data, getRangeSection(), + getStringSection(), StringRef(), getAddrSection(), + &getInfoSection().Relocs, isLittleEndian()); } 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()); - auto &TUS = TUs.back(); - while (DIData.isValidOffset(offset)) { - std::unique_ptr 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, getDebugAbbrev(), I.second.Data, getRangeSection(), + getStringSection(), StringRef(), getAddrSection(), + &I.second.Relocs, isLittleEndian()); } } 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 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.parse(*this, getDebugAbbrevDWO(), getInfoDWOSection().Data, + getRangeDWOSection(), getStringDWOSection(), + getStringOffsetDWOSection(), getAddrSection(), + &getInfoDWOSection().Relocs, isLittleEndian()); } 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()); - auto &TUS = DWOTUs.back(); - while (DIData.isValidOffset(offset)) { - std::unique_ptr 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().parse(*this, getDebugAbbrevDWO(), I.second.Data, + getRangeDWOSection(), getStringDWOSection(), + getStringOffsetDWOSection(), getAddrSection(), + &I.second.Relocs, isLittleEndian()); } } Index: lib/DebugInfo/DWARFUnit.h =================================================================== --- lib/DebugInfo/DWARFUnit.h +++ lib/DebugInfo/DWARFUnit.h @@ -52,8 +52,9 @@ } }; + bool Parsed; public: - DWARFUnitSection() {} + DWARFUnitSection() : Parsed(false) {} DWARFUnitSection(DWARFUnitSection &&DUS) : SmallVector, 1>(std::move(DUS)) {} @@ -61,6 +62,24 @@ typedef typename UnitVector::iterator iterator; typedef llvm::iterator_range iterator_range; + void parse(DWARFContext &Context, const DWARFDebugAbbrev *DA, + StringRef Section, StringRef RS, StringRef SS, StringRef SOS, + StringRef AOS, const RelocAddrMap *M, bool LE) { + if (Parsed) + return; + DataExtractor Data(Section, LE, 0); + uint32_t Offset = 0; + while (Data.isValidOffset(Offset)) { + auto U = make_unique(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; + } + UnitType *getUnitForOffset(uint32_t Offset) const { auto *CU = std::upper_bound(this->begin(), this->end(), Offset, UnitOffsetComparator());