diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h index 5935ffaa46af..6ea3b1af1024 100644 --- a/bolt/include/bolt/Core/DebugData.h +++ b/bolt/include/bolt/Core/DebugData.h @@ -475,7 +475,8 @@ public: } /// Update Str offset in .debug_str in .debug_str_offsets. - void updateAddressMap(uint32_t Index, uint32_t Address); + void updateAddressMap(uint32_t Index, uint32_t Address, + const DWARFUnit &Unit); /// Get offset for given index in original .debug_str_offsets section. uint64_t getOffset(uint32_t Index) const { return StrOffsets[Index]; } @@ -507,6 +508,8 @@ private: std::unique_ptr StrOffsetsBuffer; std::unique_ptr StrOffsetsStream; std::map IndexToAddressMap; + [[maybe_unused]] + DenseSet DebugStrOffsetFinalized; SmallVector StrOffsets; std::unordered_map ProcessedBaseOffsets; bool StrOffsetSectionWasModified = false; diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp index b0f550fd7731..8f6195f6b6ea 100644 --- a/bolt/lib/Core/DIEBuilder.cpp +++ b/bolt/lib/Core/DIEBuilder.cpp @@ -78,7 +78,7 @@ static void addStringHelper(DebugStrOffsetsWriter &StrOffstsWriter, uint32_t NewOffset = StrWriter.addString(Str); if (Unit.getVersion() >= 5) { StrOffstsWriter.updateAddressMap(DIEAttrInfo.getDIEInteger().getValue(), - NewOffset); + NewOffset, Unit); return; } DIEBldr.replaceValue(&Die, DIEAttrInfo.getAttribute(), DIEAttrInfo.getForm(), diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp index 002f58c47434..bd8aa807f1aa 100644 --- a/bolt/lib/Core/DebugData.cpp +++ b/bolt/lib/Core/DebugData.cpp @@ -851,7 +851,11 @@ void DebugStrOffsetsWriter::initialize(DWARFUnit &Unit) { StrOffsetsSection.Data.data() + Contr->Base + Offset)); } -void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address) { +void DebugStrOffsetsWriter::updateAddressMap(uint32_t Index, uint32_t Address, + const DWARFUnit &Unit) { + assert(DebugStrOffsetFinalized.count(Unit.getOffset()) == 0 && + "Cannot update address map since debug_str_offsets was already " + "finalized for this CU."); IndexToAddressMap[Index] = Address; StrOffsetSectionWasModified = true; } @@ -906,6 +910,8 @@ void DebugStrOffsetsWriter::finalizeSection(DWARFUnit &Unit, } StrOffsetSectionWasModified = false; + assert(DebugStrOffsetFinalized.insert(Unit.getOffset()).second && + "debug_str_offsets was already finalized for this CU."); clear(); } diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 1fe6eb938cec..beef1a8f902a 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -714,7 +714,8 @@ void DWARFRewriter::updateDebugInfo() { RangesBase = RangesSectionWriter.getSectionOffset() + getDWARF5RngListLocListHeaderSize(); RangesSectionWriter.initSection(Unit); - StrOffstsWriter->finalizeSection(Unit, DIEBlder); + if (!SplitCU) + StrOffstsWriter->finalizeSection(Unit, DIEBlder); } else if (SplitCU) { RangesBase = LegacyRangesSectionWriter.get()->getSectionOffset(); } @@ -760,6 +761,8 @@ void DWARFRewriter::updateDebugInfo() { : std::optional(opts::DwarfOutputPath.c_str()); std::string DWOName = DIEBlder.updateDWONameCompDir( *StrOffstsWriter, *StrWriter, *CU, DwarfOutputPath, std::nullopt); + if (CU->getVersion() >= 5) + StrOffstsWriter->finalizeSection(*CU, DIEBlder); processSplitCU(*CU, **SplitCU, DIEBlder, *TempRangesSectionWriter, AddressWriter, DWOName, DwarfOutputPath); } diff --git a/bolt/test/X86/dwarf5-df-larger-batch-size.test b/bolt/test/X86/dwarf5-df-larger-batch-size.test new file mode 100644 index 000000000000..c2c5f63e07ad --- /dev/null +++ b/bolt/test/X86/dwarf5-df-larger-batch-size.test @@ -0,0 +1,28 @@ +; RUN: rm -rf %t +; RUN: mkdir %t +; RUN: cd %t +; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-input-lowpc-ranges-main.s \ +; RUN: -split-dwarf-file=main.dwo -o main.o +; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-input-lowpc-ranges-other.s \ +; RUN: -split-dwarf-file=mainOther.dwo -o other.o +; RUN: %clang %cflags main.o other.o -o main.exe +; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --cu-processing-batch-size=1 +; RUN: llvm-bolt main.exe -o main-batch.exe.bolt --update-debug-sections --cu-processing-batch-size=2 +; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt >> %t/foo.txt +; RUN: cat %t/foo.txt | FileCheck -check-prefix=BOLT %s +; RUN: llvm-dwarfdump --show-form --verbose --debug-info main.exe.bolt >> %t/foo-batch.txt +; RUN: cat %t/foo-batch.txt | FileCheck -check-prefix=BOLT-BATCH %s + +;; Tests that BOLT correctly handles DWO name strings with larger batch sizes. + +; BOLT: DW_TAG_skeleton_unit +; BOLT: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "main.dwo.dwo") + +; BOLT: DW_TAG_skeleton_unit +; BOLT: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "mainOther.dwo.dwo") + +; BOLT-BATCH: DW_TAG_skeleton_unit +; BOLT-BATCH: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "main.dwo.dwo") + +; BOLT-BATCH: DW_TAG_skeleton_unit +; BOLT-BATCH: DW_AT_dwo_name [DW_FORM_strx1] (indexed (00000001) string = "mainOther.dwo.dwo")