diff --git a/bolt/src/DWARFRewriter.cpp b/bolt/src/DWARFRewriter.cpp index c77830388d56..fca4ea8d5ce3 100644 --- a/bolt/src/DWARFRewriter.cpp +++ b/bolt/src/DWARFRewriter.cpp @@ -164,7 +164,6 @@ static bool isHighPcFormEightBytes(dwarf::Form DwarfForm) { void DWARFRewriter::updateDebugInfo() { ErrorOr DebugInfo = BC.getUniqueSectionByName(".debug_info"); - if (!DebugInfo) return; @@ -841,9 +840,9 @@ void DWARFRewriter::finalizeDebugSections( AbbrevSectionContents->size()); // Update abbreviation offsets if they were changed. - for (auto &CU : BC.DwCtx->compile_units()) { - if (CU->isDWOUnit()) - continue; + SimpleBinaryPatcher *DebugTypesPatcher = nullptr; + for (auto &CU : BC.DwCtx->normal_units()) { + assert(!CU->isDWOUnit()); const uint64_t NewAbbrevOffset = AbbrevWriter->getAbbreviationsOffsetForUnit(*CU); @@ -854,8 +853,22 @@ void DWARFRewriter::finalizeDebugSections( // unit_length - 4 bytes // version - 2 bytes // So + 6 to patch debug_abbrev_offset - DebugInfoPatcher.addLE32Patch(CU->getOffset() + 6, - static_cast(NewAbbrevOffset)); + constexpr uint64_t AbbrevFieldOffset = 6; + if (!CU->isTypeUnit()) { + DebugInfoPatcher.addLE32Patch(CU->getOffset() + AbbrevFieldOffset, + static_cast(NewAbbrevOffset)); + continue; + } + + if (!DebugTypesPatcher) { + ErrorOr DebugTypes = + BC.getUniqueSectionByName(".debug_types"); + DebugTypes->registerPatcher(std::make_unique()); + DebugTypesPatcher = + static_cast(DebugTypes->getPatcher()); + } + DebugTypesPatcher->addLE32Patch(CU->getOffset() + AbbrevFieldOffset, + static_cast(NewAbbrevOffset)); } } diff --git a/bolt/src/DebugData.cpp b/bolt/src/DebugData.cpp index 406da24727f1..b8a3134b7707 100644 --- a/bolt/src/DebugData.cpp +++ b/bolt/src/DebugData.cpp @@ -409,19 +409,20 @@ void DebugAbbrevWriter::addUnitAbbreviations(DWARFUnit &Unit) { if (!Abbrevs) return; - uint64_t CUIndex = Unit.getOffset(); - - if (CUAbbrevData.find(CUIndex) == CUAbbrevData.end()) { - std::lock_guard Lock(WriterMutex); - AbbrevData &Data = CUAbbrevData[CUIndex]; - Data.Buffer = std::make_unique(); - Data.Stream = std::make_unique(*Data.Buffer); - } + // Multiple units may share the same abbreviations. Only add abbreviations + // for the first unit and reuse them. + const uint64_t AbbrevOffset = Unit.getAbbreviationsOffset(); + if (CUAbbrevData.find(AbbrevOffset) != CUAbbrevData.end()) + return; std::lock_guard Lock(WriterMutex); + AbbrevData &UnitData = CUAbbrevData[AbbrevOffset]; + UnitData.Buffer = std::make_unique(); + UnitData.Stream = std::make_unique(*UnitData.Buffer); + const auto &UnitPatches = Patches[&Unit]; - raw_svector_ostream &OS = *CUAbbrevData[CUIndex].Stream.get(); + raw_svector_ostream &OS = *UnitData.Stream.get(); // Take a fast path if there are no patches to apply. Simply copy the original // contents. @@ -502,20 +503,20 @@ std::unique_ptr DebugAbbrevWriter::finalize() { // Pre-calculate the total size of abbrev section. uint64_t Size = 0; for (const auto &KV : CUAbbrevData) { - const AbbrevData &Data = KV.second; - Size += Data.Buffer->size(); + const AbbrevData &UnitData = KV.second; + Size += UnitData.Buffer->size(); } ReturnBuffer.reserve(Size); uint64_t Pos = 0; for (auto &KV : CUAbbrevData) { - AbbrevData &Data = KV.second; - ReturnBuffer.append(*Data.Buffer); - Data.Offset = Pos; - Pos += Data.Buffer->size(); + AbbrevData &UnitData = KV.second; + ReturnBuffer.append(*UnitData.Buffer); + UnitData.Offset = Pos; + Pos += UnitData.Buffer->size(); - Data.Buffer.reset(); - Data.Stream.reset(); + UnitData.Buffer.reset(); + UnitData.Stream.reset(); } return std::make_unique(ReturnBuffer); diff --git a/bolt/src/DebugData.h b/bolt/src/DebugData.h index 3db34c10bfb7..5b45e3dc3874 100644 --- a/bolt/src/DebugData.h +++ b/bolt/src/DebugData.h @@ -443,7 +443,7 @@ class DebugAbbrevWriter { std::unique_ptr Buffer; std::unique_ptr Stream; }; - /// Map CU offset to abbreviations data. + /// Map original CU abbrev offset to abbreviations data. std::map CUAbbrevData; /// Attributes Substitution information. @@ -490,9 +490,10 @@ public: /// Return an offset in the finalized section corresponding to CU \p Unit. uint64_t getAbbreviationsOffsetForUnit(const DWARFUnit &Unit) { - assert(CUAbbrevData.find(Unit.getOffset()) != CUAbbrevData.end() && + assert(CUAbbrevData.find(Unit.getAbbreviationsOffset()) != + CUAbbrevData.end() && "no abbrev data found for unit"); - return CUAbbrevData[Unit.getOffset()].Offset; + return CUAbbrevData[Unit.getAbbreviationsOffset()].Offset; } };