[llvm] [BOLT][DWARF][NFC] Refactor address writers (PR #98094)

Sayhaan Siddiqui via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 11 16:35:16 PDT 2024


https://github.com/sayhaan updated https://github.com/llvm/llvm-project/pull/98094

>From cfb901ec45eae9ca0b0a47182d29d9836a827008 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Mon, 8 Jul 2024 10:26:50 -0700
Subject: [PATCH 01/14] Refactor address writers

Summary:

Test Plan:

Reviewers:

Subscribers:

Tasks:

Tags:

Differential Revision: https://phabricator.intern.facebook.com/D59493903
---
 bolt/include/bolt/Core/DebugData.h        | 53 ++++++++++++-----
 bolt/include/bolt/Rewrite/DWARFRewriter.h |  5 ++
 bolt/lib/Core/DebugData.cpp               | 71 +++++++++++------------
 bolt/lib/Rewrite/DWARFRewriter.cpp        | 63 ++++++++++++--------
 4 files changed, 118 insertions(+), 74 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 2324e577cc7c9..70d3db86a33ff 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -343,14 +343,34 @@ class DebugAddrWriter {
   uint32_t getIndexFromAddress(uint64_t Address, DWARFUnit &CU);
 
   /// Write out entries in to .debug_addr section for CUs.
-  virtual void update(DIEBuilder &DIEBlder, DWARFUnit &CUs);
+  virtual void update();
 
   /// Return buffer with all the entries in .debug_addr already writen out using
   /// update(...).
   virtual AddressSectionBuffer &finalize() { return *Buffer; }
 
   /// Returns False if .debug_addr section was created..
-  bool isInitialized() const { return !AddressMaps.empty(); }
+  bool isInitialized() { return Map.empty; }
+
+  /// Updates address base with the given Offset.
+  virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+                              const uint64_t Offset);
+
+  /// Appends an AddressSectionBuffer to the address writer buffer for the given
+  /// CU.
+  void appendToAddressBuffer(const AddressSectionBuffer &Buffer) {
+    *AddressStream << Buffer;
+  }
+
+  /// Sets AddressByteSize for the CU.
+  void setAddressByteSize(uint8_t AddressByteSize) {
+    this->AddressByteSize = AddressByteSize;
+  }
+
+  /// Sets AddrOffsetSectionBase for the CU.
+  void setAddrOffsetSectionBase(std::optional<uint64_t> AddrOffsetSectionBase) {
+    this->AddrOffsetSectionBase = AddrOffsetSectionBase;
+  }
 
 protected:
   class AddressForDWOCU {
@@ -395,6 +415,8 @@ class DebugAddrWriter {
 
     void dump();
 
+    bool empty = false;
+
   private:
     AddressToIndexMap AddressToIndex;
     IndexToAddressMap IndexToAddress;
@@ -407,14 +429,16 @@ class DebugAddrWriter {
   }
 
   BinaryContext *BC;
-  /// Maps DWOID to AddressForDWOCU.
-  std::unordered_map<uint64_t, AddressForDWOCU> AddressMaps;
+  /// Address for the DWO CU associated with the address writer.
+  AddressForDWOCU Map;
+  uint8_t AddressByteSize;
+  std::optional<uint64_t> AddrOffsetSectionBase;
   /// Mutex used for parallel processing of debug info.
   std::mutex WriterMutex;
   std::unique_ptr<AddressSectionBuffer> Buffer;
   std::unique_ptr<raw_svector_ostream> AddressStream;
   /// Used to track sections that were not modified so that they can be re-used.
-  DenseMap<uint64_t, uint64_t> UnmodifiedAddressOffsets;
+  static DenseMap<uint64_t, uint64_t> UnmodifiedAddressOffsets;
 };
 
 class DebugAddrWriterDwarf5 : public DebugAddrWriter {
@@ -423,7 +447,10 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC) {}
 
   /// Write out entries in to .debug_addr section for CUs.
-  virtual void update(DIEBuilder &DIEBlder, DWARFUnit &CUs) override;
+  virtual void update() override;
+
+  virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+                              const uint64_t Offset) override;
 
 protected:
   /// Given DWARFUnit \p Unit returns either DWO ID or it's offset within
@@ -583,12 +610,10 @@ class DebugLoclistWriter : public DebugLocWriter {
 public:
   ~DebugLoclistWriter() {}
   DebugLoclistWriter() = delete;
-  DebugLoclistWriter(DWARFUnit &Unit, uint8_t DV, bool SD)
-      : DebugLocWriter(DV, LocWriterKind::DebugLoclistWriter), CU(Unit),
-        IsSplitDwarf(SD) {
-    assert(DebugLoclistWriter::AddrWriter &&
-           "Please use SetAddressWriter to initialize "
-           "DebugAddrWriter before instantiation.");
+  DebugLoclistWriter(DWARFUnit &Unit, uint8_t DV, bool SD,
+                     DebugAddrWriter *AddrW)
+      : DebugLocWriter(DV, LocWriterKind::DebugLoclistWriter),
+        AddrWriter(AddrW), CU(Unit), IsSplitDwarf(SD) {
     if (DwarfVersion >= 5) {
       LocBodyBuffer = std::make_unique<DebugBufferVector>();
       LocBodyStream = std::make_unique<raw_svector_ostream>(*LocBodyBuffer);
@@ -600,7 +625,7 @@ class DebugLoclistWriter : public DebugLocWriter {
     }
   }
 
-  static void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
+  void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
 
   /// Stores location lists internally to be written out during finalize phase.
   virtual void addList(DIEBuilder &DIEBldr, DIE &Die, DIEValue &AttrInfo,
@@ -630,7 +655,7 @@ class DebugLoclistWriter : public DebugLocWriter {
   /// Writes out locations in to a local buffer and applies debug info patches.
   void finalizeDWARF5(DIEBuilder &DIEBldr, DIE &Die);
 
-  static DebugAddrWriter *AddrWriter;
+  DebugAddrWriter *AddrWriter;
   DWARFUnit &CU;
   bool IsSplitDwarf{false};
   // Used for DWARF5 to store location lists before being finalized.
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index 4f576eaa95576..49cec64ce4cea 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -93,6 +93,10 @@ class DWARFRewriter {
   std::unordered_map<uint64_t, std::unique_ptr<DebugRangesSectionWriter>>
       LegacyRangesWritersByCU;
 
+  /// Stores address writer for each CU.
+  std::unordered_map<uint64_t, std::unique_ptr<DebugAddrWriter>>
+      AddressWritersByCU;
+
   std::mutex LocListDebugInfoPatchesMutex;
 
   /// Dwo id specific its RangesBase.
@@ -115,6 +119,7 @@ class DWARFRewriter {
   void updateUnitDebugInfo(DWARFUnit &Unit, DIEBuilder &DIEBldr,
                            DebugLocWriter &DebugLocWriter,
                            DebugRangesSectionWriter &RangesSectionWriter,
+                           DebugAddrWriter &AddressWriter,
                            std::optional<uint64_t> RangesBase = std::nullopt);
 
   /// Patches the binary for an object's address ranges to be updated.
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 76c3545c63088..323464d946c43 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -393,6 +393,7 @@ void DebugARangesSectionWriter::writeARangesSection(
 DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
   Buffer = std::make_unique<AddressSectionBuffer>();
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
+  Map = AddressForDWOCU();
 }
 
 void DebugAddrWriter::AddressForDWOCU::dump() {
@@ -405,11 +406,8 @@ void DebugAddrWriter::AddressForDWOCU::dump() {
 }
 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) {
   std::lock_guard<std::mutex> Lock(WriterMutex);
-  const uint64_t CUID = getCUID(CU);
-  if (!AddressMaps.count(CUID))
-    AddressMaps[CUID] = AddressForDWOCU();
-
-  AddressForDWOCU &Map = AddressMaps[CUID];
+  if (Map.begin() == Map.end())
+    Map.empty = true;
   auto Entry = Map.find(Address);
   if (Entry == Map.end()) {
     auto Index = Map.getNextIndex();
@@ -449,25 +447,20 @@ static void updateAddressBase(DIEBuilder &DIEBlder, DebugAddrWriter &AddrWriter,
   }
 }
 
-void DebugAddrWriter::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
-  // Handling the case where debug information is a mix of Debug fission and
-  // monolithic.
-  if (!CU.getDWOId())
-    return;
-  const uint64_t CUID = getCUID(CU);
-  auto AM = AddressMaps.find(CUID);
-  // Adding to map even if it did not contribute to .debug_addr.
-  // The Skeleton CU might still have DW_AT_GNU_addr_base.
-  uint64_t Offset = Buffer->size();
-  // If does not exist this CUs DWO section didn't contribute to .debug_addr.
-  if (AM == AddressMaps.end())
+void DebugAddrWriter::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+                                     const uint64_t Offset) {
+  updateAddressBase(DIEBlder, *this, CU, Offset);
+}
+
+void DebugAddrWriter::update() {
+  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd())
     return;
-  std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(),
-                                          AM->second.indexToAdddessEnd());
+  std::vector<IndexAddressPair> SortedMap(Map.indexToAddressBegin(),
+                                          Map.indexToAdddessEnd());
   // Sorting address in increasing order of indices.
   llvm::sort(SortedMap, llvm::less_first());
 
-  uint8_t AddrSize = CU.getAddressByteSize();
+  uint8_t AddrSize = AddressByteSize;
   uint32_t Counter = 0;
   auto WriteAddress = [&](uint64_t Address) -> void {
     ++Counter;
@@ -490,10 +483,23 @@ void DebugAddrWriter::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
       WriteAddress(0);
     WriteAddress(Val.second);
   }
-  updateAddressBase(DIEBlder, *this, CU, Offset);
 }
 
-void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
+void DebugAddrWriterDwarf5::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+                                           const uint64_t Offset) {
+  /// Doesn't update address base if the CU doesn't access .debug_addr.
+  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd()) {
+    std::optional<uint64_t> BaseOffset = CU.getAddrOffsetSectionBase();
+    if (!BaseOffset)
+      return;
+  }
+  /// Header for DWARF5 has size 8, so we add it to the offset.
+  updateAddressBase(DIEBlder, *this, CU, Offset + 8);
+}
+
+DenseMap<uint64_t, uint64_t> DebugAddrWriter::UnmodifiedAddressOffsets;
+
+void DebugAddrWriterDwarf5::update() {
   // Need to layout all sections within .debug_addr
   // Within each section sort Address by index.
   const endianness Endian = BC->DwCtx->isLittleEndian()
@@ -505,14 +511,11 @@ void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
   DWARFDebugAddrTable AddrTable;
   DIDumpOptions DumpOpts;
   constexpr uint32_t HeaderSize = 8;
-  const uint64_t CUID = getCUID(CU);
-  const uint8_t AddrSize = CU.getAddressByteSize();
-  auto AMIter = AddressMaps.find(CUID);
+  const uint8_t AddrSize = AddressByteSize;
   // A case where CU has entry in .debug_addr, but we don't modify addresses
   // for it.
-  if (AMIter == AddressMaps.end()) {
-    AMIter = AddressMaps.insert({CUID, AddressForDWOCU()}).first;
-    std::optional<uint64_t> BaseOffset = CU.getAddrOffsetSectionBase();
+  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd()) {
+    std::optional<uint64_t> BaseOffset = AddrOffsetSectionBase;
     if (!BaseOffset)
       return;
     // Address base offset is to the first entry.
@@ -520,7 +523,6 @@ void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
     uint64_t Offset = *BaseOffset - HeaderSize;
     auto Iter = UnmodifiedAddressOffsets.find(Offset);
     if (Iter != UnmodifiedAddressOffsets.end()) {
-      updateAddressBase(DIEBlder, *this, CU, Iter->getSecond());
       return;
     }
     UnmodifiedAddressOffsets[Offset] = Buffer->size() + HeaderSize;
@@ -529,16 +531,13 @@ void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
       DumpOpts.RecoverableErrorHandler(std::move(Err));
       return;
     }
-
     uint32_t Index = 0;
     for (uint64_t Addr : AddrTable.getAddressEntries())
-      AMIter->second.insert(Addr, Index++);
+      Map.insert(Addr, Index++);
   }
 
-  updateAddressBase(DIEBlder, *this, CU, Buffer->size() + HeaderSize);
-
-  std::vector<IndexAddressPair> SortedMap(AMIter->second.indexToAddressBegin(),
-                                          AMIter->second.indexToAdddessEnd());
+  std::vector<IndexAddressPair> SortedMap(Map.indexToAddressBegin(),
+                                          Map.indexToAdddessEnd());
   // Sorting address in increasing order of indices.
   llvm::sort(SortedMap, llvm::less_first());
   // Writing out Header
@@ -789,8 +788,6 @@ void DebugLoclistWriter::finalize(DIEBuilder &DIEBldr, DIE &Die) {
     finalizeDWARF5(DIEBldr, Die);
 }
 
-DebugAddrWriter *DebugLoclistWriter::AddrWriter = nullptr;
-
 static std::string encodeLE(size_t ByteSize, uint64_t NewValue) {
   std::string LE64(ByteSize, 0);
   for (size_t I = 0; I < ByteSize; ++I) {
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 89168b4bd559c..2a0fe77315c97 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -615,7 +615,6 @@ void DWARFRewriter::updateDebugInfo() {
   if (BC.isDWARF5Used()) {
     AddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
     RangeListsSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
-    DebugRangeListsSectionWriter::setAddressWriter(AddrWriter.get());
   } else {
     AddrWriter = std::make_unique<DebugAddrWriter>(&BC);
   }
@@ -625,8 +624,6 @@ void DWARFRewriter::updateDebugInfo() {
     LegacyRangesSectionWriter->initSection();
   }
 
-  DebugLoclistWriter::setAddressWriter(AddrWriter.get());
-
   uint32_t CUIndex = 0;
   std::mutex AccessMutex;
   // Needs to be invoked in the same order as CUs are processed.
@@ -634,8 +631,16 @@ void DWARFRewriter::updateDebugInfo() {
     std::lock_guard<std::mutex> Lock(AccessMutex);
     const uint16_t DwarfVersion = CU.getVersion();
     if (DwarfVersion >= 5) {
-      LocListWritersByCU[CUIndex] =
-          std::make_unique<DebugLoclistWriter>(CU, DwarfVersion, false);
+      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC);
+      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
+      DebugRangeListsSectionWriter::setAddressWriter(
+          AddressWritersByCU[CU.getOffset()].get());
+      AddressWritersByCU[CU.getOffset()]->setAddressByteSize(
+          CU.getAddressByteSize());
+      AddressWritersByCU[CU.getOffset()]->setAddrOffsetSectionBase(
+          CU.getAddrOffsetSectionBase());
+      LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
+          CU, DwarfVersion, false, AddressWritersByCU[CU.getOffset()].get());
 
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
@@ -647,6 +652,10 @@ void DWARFRewriter::updateDebugInfo() {
       }
 
     } else {
+      auto AddrW = std::make_unique<DebugAddrWriter>(&BC);
+      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
+      AddressWritersByCU[CU.getOffset()]->setAddressByteSize(
+          CU.getAddressByteSize());
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
@@ -678,6 +687,7 @@ void DWARFRewriter::updateDebugInfo() {
     DebugRangesSectionWriter *RangesSectionWriter =
         Unit->getVersion() >= 5 ? RangeListsSectionWriter.get()
                                 : LegacyRangesSectionWriter.get();
+    auto &AddressWriter = AddressWritersByCU[Unit->getOffset()];
     // Skipping CUs that failed to load.
     if (SplitCU) {
       DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable,
@@ -698,7 +708,8 @@ void DWARFRewriter::updateDebugInfo() {
       DWODIEBuilder.updateDWONameCompDirForTypes(DWOStrOffstsWriter,
                                                  DWOStrWriter, **SplitCU,
                                                  DwarfOutputPath, DWOName);
-      DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true);
+      DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true,
+                                           AddressWriter.get());
       DebugRangesSectionWriter *TempRangesSectionWriter = RangesSectionWriter;
       if (Unit->getVersion() >= 5) {
         TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get();
@@ -709,7 +720,7 @@ void DWARFRewriter::updateDebugInfo() {
       }
 
       updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter,
-                          *TempRangesSectionWriter);
+                          *TempRangesSectionWriter, *AddressWriter.get());
       DebugLocDWoWriter.finalize(DWODIEBuilder,
                                  *DWODIEBuilder.getUnitDIEbyUnit(**SplitCU));
       if (Unit->getVersion() >= 5)
@@ -728,11 +739,10 @@ void DWARFRewriter::updateDebugInfo() {
     }
 
     updateUnitDebugInfo(*Unit, *DIEBlder, *DebugLocWriter, *RangesSectionWriter,
-                        RangesBase);
+                        *AddressWriter.get(), RangesBase);
     DebugLocWriter->finalize(*DIEBlder, *DIEBlder->getUnitDIEbyUnit(*Unit));
     if (Unit->getVersion() >= 5)
       RangesSectionWriter->finalizeSection();
-    AddrWriter->update(*DIEBlder, *Unit);
   };
 
   DIEBuilder DIEBlder(BC, BC.DwCtx.get(), DebugNamesTable);
@@ -782,7 +792,7 @@ void DWARFRewriter::updateDebugInfo() {
 void DWARFRewriter::updateUnitDebugInfo(
     DWARFUnit &Unit, DIEBuilder &DIEBldr, DebugLocWriter &DebugLocWriter,
     DebugRangesSectionWriter &RangesSectionWriter,
-    std::optional<uint64_t> RangesBase) {
+    DebugAddrWriter &AddressWriter, std::optional<uint64_t> RangesBase) {
   // Cache debug ranges so that the offset for identical ranges could be reused.
   std::map<DebugAddressRangesVector, uint64_t> CachedRanges;
 
@@ -816,7 +826,7 @@ void DWARFRewriter::updateUnitDebugInfo(
 
     if (FormLowPC == dwarf::DW_FORM_addrx ||
         FormLowPC == dwarf::DW_FORM_GNU_addr_index)
-      LowPC = AddrWriter->getIndexFromAddress(LowPC, Unit);
+      LowPC = AddressWriter.getIndexFromAddress(LowPC, Unit);
 
     if (LowPCVal)
       DIEBldr.replaceValue(Die, AttrLowPC, FormLowPC, DIEInteger(LowPC));
@@ -980,7 +990,7 @@ void DWARFRewriter::updateUnitDebugInfo(
 
         if (AttrVal.getForm() == dwarf::DW_FORM_addrx) {
           const uint32_t Index =
-              AddrWriter->getIndexFromAddress(UpdatedAddress, Unit);
+              AddressWriter.getIndexFromAddress(UpdatedAddress, Unit);
           DIEBldr.replaceValue(Die, AttrVal.getAttribute(), AttrVal.getForm(),
                                DIEInteger(Index));
         } else if (AttrVal.getForm() == dwarf::DW_FORM_addr) {
@@ -1197,7 +1207,7 @@ void DWARFRewriter::updateUnitDebugInfo(
                 assert(EntryAddress && "Address is not found.");
                 assert(Index <= std::numeric_limits<uint32_t>::max() &&
                        "Invalid Operand Index.");
-                const uint32_t AddrIndex = AddrWriter->getIndexFromAddress(
+                const uint32_t AddrIndex = AddressWriter.getIndexFromAddress(
                     EntryAddress->Address, Unit);
                 // update Index into .debug_address section for DW_AT_location.
                 // The Size field is not stored in IR, we need to minus 1 in
@@ -1249,7 +1259,7 @@ void DWARFRewriter::updateUnitDebugInfo(
           std::lock_guard<std::mutex> Lock(DWARFRewriterMutex);
           if (Form == dwarf::DW_FORM_addrx ||
               Form == dwarf::DW_FORM_GNU_addr_index) {
-            const uint32_t Index = AddrWriter->getIndexFromAddress(
+            const uint32_t Index = AddressWriter.getIndexFromAddress(
                 NewAddress ? NewAddress : Address, Unit);
             DIEBldr.replaceValue(Die, LowPCAttrInfo.getAttribute(),
                                  LowPCAttrInfo.getForm(), DIEInteger(Index));
@@ -1565,14 +1575,10 @@ void DWARFRewriter::finalizeDebugSections(
           LocationListSectionContents->size());
   }
 
-  // AddrWriter should be finalized after debug_loc since more addresses can be
-  // added there.
-  if (AddrWriter->isInitialized()) {
-    AddressSectionBuffer AddressSectionContents = AddrWriter->finalize();
-    BC.registerOrUpdateNoteSection(".debug_addr",
-                                   copyByteArray(AddressSectionContents),
-                                   AddressSectionContents.size());
-  }
+  AddressSectionBuffer AddressSectionContents = AddrWriter->finalize();
+  BC.registerOrUpdateNoteSection(".debug_addr",
+                                 copyByteArray(AddressSectionContents),
+                                 AddressSectionContents.size());
 
   Streamer.emitAbbrevs(DIEBlder.getAbbrevs(), BC.DwCtx->getMaxVersion());
   Streamer.finish();
@@ -1626,6 +1632,16 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
                                          CUOffsetMap &CUMap,
                                          const std::list<DWARFUnit *> &CUs) {
   for (DWARFUnit *CU : CUs) {
+    auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
+    assert(AddressWriterIterator != AddressWritersByCU.end() &&
+           "AddressWriter does not exist for CU");
+    auto &AddressWriter = AddressWriterIterator->second;
+    AddressWriter->update();
+    AddressWriter->updateAddrBase(DIEBlder, *CU, AddrWriter->finalize().size());
+    if (AddressWriter->isInitialized()) {
+      AddressSectionBuffer AddressSectionContents = AddressWriter->finalize();
+      AddrWriter->appendToAddressBuffer(AddressSectionContents);
+    }
     if (CU->getVersion() != 4)
       continue;
     std::optional<uint64_t> DWOId = CU->getDWOId();
@@ -2155,7 +2171,8 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
   // when it's absent.
   if (IsUnitDie) {
     if (LowForm == dwarf::DW_FORM_addrx) {
-      const uint32_t Index = AddrWriter->getIndexFromAddress(0, Unit);
+      const uint32_t Index =
+          AddressWritersByCU[Unit.getOffset()]->getIndexFromAddress(0, Unit);
       DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
                            LowPCAttrInfo.getForm(), DIEInteger(Index));
     } else {

>From 89eb24d773838b85ae44c28d95412a4bcbefaeae Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 15:29:42 -0700
Subject: [PATCH 02/14] Updates and formatting changes

---
 bolt/include/bolt/Core/DebugData.h        | 21 +++++---
 bolt/include/bolt/Rewrite/DWARFRewriter.h |  2 +-
 bolt/lib/Core/DebugData.cpp               | 52 ++++++++------------
 bolt/lib/Rewrite/DWARFRewriter.cpp        | 59 ++++++++++++++---------
 4 files changed, 71 insertions(+), 63 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 70d3db86a33ff..8bec44c19a35c 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -343,14 +343,19 @@ class DebugAddrWriter {
   uint32_t getIndexFromAddress(uint64_t Address, DWARFUnit &CU);
 
   /// Write out entries in to .debug_addr section for CUs.
-  virtual void update();
+  virtual std::optional<uint64_t> finalize(const size_t BufferSize);
 
   /// Return buffer with all the entries in .debug_addr already writen out using
   /// update(...).
-  virtual AddressSectionBuffer &finalize() { return *Buffer; }
+  virtual std::unique_ptr<AddressSectionBuffer> releaseBuffer() {
+    return std::move(Buffer);
+  }
+
+  /// Returns buffer size.
+  virtual size_t getBufferSize() { return Buffer->size(); }
 
   /// Returns False if .debug_addr section was created..
-  bool isInitialized() { return Map.empty; }
+  bool isInitialized() { return Buffer->size() > 0; }
 
   /// Updates address base with the given Offset.
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
@@ -363,12 +368,13 @@ class DebugAddrWriter {
   }
 
   /// Sets AddressByteSize for the CU.
-  void setAddressByteSize(uint8_t AddressByteSize) {
+  void setAddressByteSize(const uint8_t AddressByteSize) {
     this->AddressByteSize = AddressByteSize;
   }
 
   /// Sets AddrOffsetSectionBase for the CU.
-  void setAddrOffsetSectionBase(std::optional<uint64_t> AddrOffsetSectionBase) {
+  void setAddrOffsetSectionBase(
+      const std::optional<uint64_t> AddrOffsetSectionBase) {
     this->AddrOffsetSectionBase = AddrOffsetSectionBase;
   }
 
@@ -415,8 +421,6 @@ class DebugAddrWriter {
 
     void dump();
 
-    bool empty = false;
-
   private:
     AddressToIndexMap AddressToIndex;
     IndexToAddressMap IndexToAddress;
@@ -433,6 +437,7 @@ class DebugAddrWriter {
   AddressForDWOCU Map;
   uint8_t AddressByteSize;
   std::optional<uint64_t> AddrOffsetSectionBase;
+  static constexpr uint32_t HeaderSize = 8;
   /// Mutex used for parallel processing of debug info.
   std::mutex WriterMutex;
   std::unique_ptr<AddressSectionBuffer> Buffer;
@@ -447,7 +452,7 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC) {}
 
   /// Write out entries in to .debug_addr section for CUs.
-  virtual void update() override;
+  virtual std::optional<uint64_t> finalize(const size_t BufferSize) override;
 
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
                               const uint64_t Offset) override;
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index 49cec64ce4cea..ac3b26b08e593 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -68,7 +68,7 @@ class DWARFRewriter {
 
   /// Stores and serializes information that will be put into the
   /// .debug_addr DWARF section.
-  std::unique_ptr<DebugAddrWriter> AddrWriter;
+  std::unique_ptr<DebugAddrWriter> FinalAddrWriter;
 
   /// Stores and serializes information that will be put in to the
   /// .debug_addr DWARF section.
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 323464d946c43..bbf4a9e3b42b1 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -393,7 +393,6 @@ void DebugARangesSectionWriter::writeARangesSection(
 DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
   Buffer = std::make_unique<AddressSectionBuffer>();
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
-  Map = AddressForDWOCU();
 }
 
 void DebugAddrWriter::AddressForDWOCU::dump() {
@@ -406,8 +405,6 @@ void DebugAddrWriter::AddressForDWOCU::dump() {
 }
 uint32_t DebugAddrWriter::getIndexFromAddress(uint64_t Address, DWARFUnit &CU) {
   std::lock_guard<std::mutex> Lock(WriterMutex);
-  if (Map.begin() == Map.end())
-    Map.empty = true;
   auto Entry = Map.find(Address);
   if (Entry == Map.end()) {
     auto Index = Map.getNextIndex();
@@ -452,19 +449,18 @@ void DebugAddrWriter::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
   updateAddressBase(DIEBlder, *this, CU, Offset);
 }
 
-void DebugAddrWriter::update() {
-  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd())
-    return;
+std::optional<uint64_t> DebugAddrWriter::finalize(size_t BufferSize) {
+  if (Map.begin() == Map.end())
+    return std::nullopt;
   std::vector<IndexAddressPair> SortedMap(Map.indexToAddressBegin(),
                                           Map.indexToAdddessEnd());
   // Sorting address in increasing order of indices.
   llvm::sort(SortedMap, llvm::less_first());
 
-  uint8_t AddrSize = AddressByteSize;
   uint32_t Counter = 0;
   auto WriteAddress = [&](uint64_t Address) -> void {
     ++Counter;
-    switch (AddrSize) {
+    switch (AddressByteSize) {
     default:
       assert(false && "Address Size is invalid.");
       break;
@@ -483,23 +479,18 @@ void DebugAddrWriter::update() {
       WriteAddress(0);
     WriteAddress(Val.second);
   }
+  return std::nullopt;
 }
 
 void DebugAddrWriterDwarf5::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
                                            const uint64_t Offset) {
-  /// Doesn't update address base if the CU doesn't access .debug_addr.
-  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd()) {
-    std::optional<uint64_t> BaseOffset = CU.getAddrOffsetSectionBase();
-    if (!BaseOffset)
-      return;
-  }
   /// Header for DWARF5 has size 8, so we add it to the offset.
-  updateAddressBase(DIEBlder, *this, CU, Offset + 8);
+  updateAddressBase(DIEBlder, *this, CU, Offset + HeaderSize);
 }
 
 DenseMap<uint64_t, uint64_t> DebugAddrWriter::UnmodifiedAddressOffsets;
 
-void DebugAddrWriterDwarf5::update() {
+std::optional<uint64_t> DebugAddrWriterDwarf5::finalize(size_t BufferSize) {
   // Need to layout all sections within .debug_addr
   // Within each section sort Address by index.
   const endianness Endian = BC->DwCtx->isLittleEndian()
@@ -510,26 +501,22 @@ void DebugAddrWriterDwarf5::update() {
                               Endian == llvm::endianness::little, 0);
   DWARFDebugAddrTable AddrTable;
   DIDumpOptions DumpOpts;
-  constexpr uint32_t HeaderSize = 8;
-  const uint8_t AddrSize = AddressByteSize;
   // A case where CU has entry in .debug_addr, but we don't modify addresses
   // for it.
-  if (Map.indexToAddressBegin() == Map.indexToAdddessEnd()) {
-    std::optional<uint64_t> BaseOffset = AddrOffsetSectionBase;
-    if (!BaseOffset)
-      return;
+  if (Map.begin() == Map.end()) {
+    if (!AddrOffsetSectionBase)
+      return std::nullopt;
     // Address base offset is to the first entry.
     // The size of header is 8 bytes.
-    uint64_t Offset = *BaseOffset - HeaderSize;
+    uint64_t Offset = *AddrOffsetSectionBase - HeaderSize;
     auto Iter = UnmodifiedAddressOffsets.find(Offset);
-    if (Iter != UnmodifiedAddressOffsets.end()) {
-      return;
-    }
-    UnmodifiedAddressOffsets[Offset] = Buffer->size() + HeaderSize;
-    if (Error Err = AddrTable.extract(AddrData, &Offset, 5, AddrSize,
+    if (Iter != UnmodifiedAddressOffsets.end())
+      return Iter->second;
+    UnmodifiedAddressOffsets[Offset] = BufferSize;
+    if (Error Err = AddrTable.extract(AddrData, &Offset, 5, AddressByteSize,
                                       DumpOpts.WarningHandler)) {
       DumpOpts.RecoverableErrorHandler(std::move(Err));
-      return;
+      return std::nullopt;
     }
     uint32_t Index = 0;
     for (uint64_t Addr : AddrTable.getAddressEntries())
@@ -541,17 +528,17 @@ void DebugAddrWriterDwarf5::update() {
   // Sorting address in increasing order of indices.
   llvm::sort(SortedMap, llvm::less_first());
   // Writing out Header
-  const uint32_t Length = SortedMap.size() * AddrSize + 4;
+  const uint32_t Length = SortedMap.size() * AddressByteSize + 4;
   support::endian::write(*AddressStream, Length, Endian);
   support::endian::write(*AddressStream, static_cast<uint16_t>(5), Endian);
-  support::endian::write(*AddressStream, static_cast<uint8_t>(AddrSize),
+  support::endian::write(*AddressStream, static_cast<uint8_t>(AddressByteSize),
                          Endian);
   support::endian::write(*AddressStream, static_cast<uint8_t>(0), Endian);
 
   uint32_t Counter = 0;
   auto writeAddress = [&](uint64_t Address) -> void {
     ++Counter;
-    switch (AddrSize) {
+    switch (AddressByteSize) {
     default:
       llvm_unreachable("Address Size is invalid.");
       break;
@@ -570,6 +557,7 @@ void DebugAddrWriterDwarf5::update() {
       writeAddress(0);
     writeAddress(Val.second);
   }
+  return std::nullopt;
 }
 
 void DebugLocWriter::init() {
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 2a0fe77315c97..1283123cfa3f6 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -613,10 +613,10 @@ void DWARFRewriter::updateDebugInfo() {
   }
 
   if (BC.isDWARF5Used()) {
-    AddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
+    FinalAddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
     RangeListsSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
   } else {
-    AddrWriter = std::make_unique<DebugAddrWriter>(&BC);
+    FinalAddrWriter = std::make_unique<DebugAddrWriter>(&BC);
   }
 
   if (BC.isDWARFLegacyUsed()) {
@@ -632,15 +632,16 @@ void DWARFRewriter::updateDebugInfo() {
     const uint16_t DwarfVersion = CU.getVersion();
     if (DwarfVersion >= 5) {
       auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC);
-      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
+      std::unique_ptr<DebugAddrWriter> &AddressWriterIterator =
+          AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
+              .first->second;
       DebugRangeListsSectionWriter::setAddressWriter(
-          AddressWritersByCU[CU.getOffset()].get());
-      AddressWritersByCU[CU.getOffset()]->setAddressByteSize(
-          CU.getAddressByteSize());
-      AddressWritersByCU[CU.getOffset()]->setAddrOffsetSectionBase(
+          AddressWriterIterator.get());
+      AddressWriterIterator->setAddressByteSize(CU.getAddressByteSize());
+      AddressWriterIterator->setAddrOffsetSectionBase(
           CU.getAddrOffsetSectionBase());
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
-          CU, DwarfVersion, false, AddressWritersByCU[CU.getOffset()].get());
+          CU, DwarfVersion, false, AddressWriterIterator.get());
 
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
@@ -653,9 +654,10 @@ void DWARFRewriter::updateDebugInfo() {
 
     } else {
       auto AddrW = std::make_unique<DebugAddrWriter>(&BC);
-      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
-      AddressWritersByCU[CU.getOffset()]->setAddressByteSize(
-          CU.getAddressByteSize());
+      std::unique_ptr<DebugAddrWriter> &AddressWriterIterator =
+          AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
+              .first->second;
+      AddressWriterIterator->setAddressByteSize(CU.getAddressByteSize());
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
@@ -687,7 +689,8 @@ void DWARFRewriter::updateDebugInfo() {
     DebugRangesSectionWriter *RangesSectionWriter =
         Unit->getVersion() >= 5 ? RangeListsSectionWriter.get()
                                 : LegacyRangesSectionWriter.get();
-    auto &AddressWriter = AddressWritersByCU[Unit->getOffset()];
+    std::unique_ptr<DebugAddrWriter> &AddressWriter =
+        AddressWritersByCU[Unit->getOffset()];
     // Skipping CUs that failed to load.
     if (SplitCU) {
       DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable,
@@ -1575,10 +1578,13 @@ void DWARFRewriter::finalizeDebugSections(
           LocationListSectionContents->size());
   }
 
-  AddressSectionBuffer AddressSectionContents = AddrWriter->finalize();
-  BC.registerOrUpdateNoteSection(".debug_addr",
-                                 copyByteArray(AddressSectionContents),
-                                 AddressSectionContents.size());
+  if (FinalAddrWriter->isInitialized()) {
+    std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
+        FinalAddrWriter->releaseBuffer();
+    BC.registerOrUpdateNoteSection(".debug_addr",
+                                   copyByteArray(*AddressSectionContents),
+                                   AddressSectionContents->size());
+  }
 
   Streamer.emitAbbrevs(DIEBlder.getAbbrevs(), BC.DwCtx->getMaxVersion());
   Streamer.finish();
@@ -1635,12 +1641,18 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
     auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
     assert(AddressWriterIterator != AddressWritersByCU.end() &&
            "AddressWriter does not exist for CU");
-    auto &AddressWriter = AddressWriterIterator->second;
-    AddressWriter->update();
-    AddressWriter->updateAddrBase(DIEBlder, *CU, AddrWriter->finalize().size());
+    std::unique_ptr<DebugAddrWriter> &AddressWriter =
+        AddressWriterIterator->second;
+    const size_t BufferOffset = FinalAddrWriter->getBufferSize();
+    std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
+    if (Offset)
+      AddressWriter->updateAddrBase(DIEBlder, *CU, *Offset);
+    else if (AddressWriter->isInitialized())
+      AddressWriter->updateAddrBase(DIEBlder, *CU, BufferOffset);
     if (AddressWriter->isInitialized()) {
-      AddressSectionBuffer AddressSectionContents = AddressWriter->finalize();
-      AddrWriter->appendToAddressBuffer(AddressSectionContents);
+      std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
+          AddressWriter->releaseBuffer();
+      FinalAddrWriter->appendToAddressBuffer(*AddressSectionContents);
     }
     if (CU->getVersion() != 4)
       continue;
@@ -2171,8 +2183,11 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
   // when it's absent.
   if (IsUnitDie) {
     if (LowForm == dwarf::DW_FORM_addrx) {
+      auto AddrWriterIterator = AddressWritersByCU.find(Unit.getOffset());
+      assert(AddrWriterIterator != AddressWritersByCU.end() &&
+             "AddressWriter does not exist for CU");
       const uint32_t Index =
-          AddressWritersByCU[Unit.getOffset()]->getIndexFromAddress(0, Unit);
+          AddrWriterIterator->second->getIndexFromAddress(0, Unit);
       DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
                            LowPCAttrInfo.getForm(), DIEInteger(Index));
     } else {

>From f5d094d2b805abdc1c20d9594211577c89d79bc2 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 15:37:25 -0700
Subject: [PATCH 03/14] Add comment

---
 bolt/lib/Rewrite/DWARFRewriter.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 1283123cfa3f6..3dd0eba8d2ce7 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -1645,6 +1645,8 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
         AddressWriterIterator->second;
     const size_t BufferOffset = FinalAddrWriter->getBufferSize();
     std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
+    /// If Offset already exists in UnmodifiedAddressOffsets, then update with
+    /// Offset, else update with BufferOffset.
     if (Offset)
       AddressWriter->updateAddrBase(DIEBlder, *CU, *Offset);
     else if (AddressWriter->isInitialized())

>From ae5b1ba863df538429325aa6e070a7d73d155294 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 15:40:16 -0700
Subject: [PATCH 04/14] Formatting changes

---
 bolt/lib/Core/DebugData.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index bbf4a9e3b42b1..5ad7582f08280 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -449,7 +449,7 @@ void DebugAddrWriter::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
   updateAddressBase(DIEBlder, *this, CU, Offset);
 }
 
-std::optional<uint64_t> DebugAddrWriter::finalize(size_t BufferSize) {
+std::optional<uint64_t> DebugAddrWriter::finalize(const size_t BufferSize) {
   if (Map.begin() == Map.end())
     return std::nullopt;
   std::vector<IndexAddressPair> SortedMap(Map.indexToAddressBegin(),
@@ -490,7 +490,7 @@ void DebugAddrWriterDwarf5::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
 
 DenseMap<uint64_t, uint64_t> DebugAddrWriter::UnmodifiedAddressOffsets;
 
-std::optional<uint64_t> DebugAddrWriterDwarf5::finalize(size_t BufferSize) {
+std::optional<uint64_t> DebugAddrWriterDwarf5::finalize(const size_t BufferSize) {
   // Need to layout all sections within .debug_addr
   // Within each section sort Address by index.
   const endianness Endian = BC->DwCtx->isLittleEndian()

>From b51aceb778fa9ed97e5d3bb1294b9a168e1f2676 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 15:45:10 -0700
Subject: [PATCH 05/14] Formatting changes

---
 bolt/lib/Core/DebugData.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 5ad7582f08280..c93e96b529c79 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -490,7 +490,8 @@ void DebugAddrWriterDwarf5::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
 
 DenseMap<uint64_t, uint64_t> DebugAddrWriter::UnmodifiedAddressOffsets;
 
-std::optional<uint64_t> DebugAddrWriterDwarf5::finalize(const size_t BufferSize) {
+std::optional<uint64_t>
+DebugAddrWriterDwarf5::finalize(const size_t BufferSize) {
   // Need to layout all sections within .debug_addr
   // Within each section sort Address by index.
   const endianness Endian = BC->DwCtx->isLittleEndian()

>From d266b7d425558a476682a16db40ec93378ee9c71 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Tue, 9 Jul 2024 16:32:13 -0700
Subject: [PATCH 06/14] Updated test to catch edge case

---
 bolt/test/X86/dwarf5-addr-section-reuse.s | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/bolt/test/X86/dwarf5-addr-section-reuse.s b/bolt/test/X86/dwarf5-addr-section-reuse.s
index 6b00ce0fdf805..cf511d6d111e0 100644
--- a/bolt/test/X86/dwarf5-addr-section-reuse.s
+++ b/bolt/test/X86/dwarf5-addr-section-reuse.s
@@ -1,7 +1,7 @@
 # RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-main-addr-section-reuse.s    -o %tmain.o
 # RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-helper1-addr-section-reuse.s -o %thelper1.o
 # RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-helper2-addr-section-reuse.s -o %thelper2.o
-# RUN: %clang %cflags -dwarf-5 %tmain.o %thelper1.o %thelper2.o -o %t.exe -Wl,-q
+# RUN: %clang %cflags -dwarf-5 %thelper1.o %tmain.o %thelper2.o -o %t.exe -Wl,-q
 # RUN: llvm-dwarfdump --debug-info %t.exe | FileCheck --check-prefix=PRECHECK %s
 # RUN: llvm-bolt %t.exe -o %t.exe.bolt --update-debug-sections
 # RUN: llvm-dwarfdump --debug-info %t.exe.bolt | FileCheck --check-prefix=POSTCHECK %s
@@ -14,5 +14,5 @@
 # PRECHECK: DW_AT_addr_base (0x00000008)
 
 # POSTCHECK: DW_AT_addr_base (0x00000008)
-# POSTCHECK: DW_AT_addr_base (0x00000020)
-# POSTCHECK: DW_AT_addr_base (0x00000020)
+# POSTCHECK: DW_AT_addr_base (0x00000018)
+# POSTCHECK: DW_AT_addr_base (0x00000008)

>From d65ffa88a12f1309ec666c900e8158d4b46d8a32 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 16:01:31 -0700
Subject: [PATCH 07/14] Updates and formatting changes

---
 bolt/include/bolt/Core/DebugData.h | 38 ++++++++--------------
 bolt/lib/Core/DebugData.cpp        |  7 ++--
 bolt/lib/Rewrite/DWARFRewriter.cpp | 51 ++++++++++++++----------------
 3 files changed, 43 insertions(+), 53 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 8bec44c19a35c..1bbf13f0c60a6 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -256,7 +256,7 @@ class DebugRangeListsSectionWriter : public DebugRangesSectionWriter {
   };
   virtual ~DebugRangeListsSectionWriter(){};
 
-  static void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
+  void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
 
   /// Add ranges with caching.
   uint64_t addRanges(
@@ -284,7 +284,7 @@ class DebugRangeListsSectionWriter : public DebugRangesSectionWriter {
   }
 
 private:
-  static DebugAddrWriter *AddrWriter;
+  DebugAddrWriter *AddrWriter = nullptr;
   /// Used to find unique CU ID.
   DWARFUnit *CU;
   /// Current relative offset of range list entry within this CUs rangelist
@@ -337,6 +337,7 @@ class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
   DebugAddrWriter(BinaryContext *BC_);
+  DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.
   /// Adds Address to map.
@@ -354,30 +355,18 @@ class DebugAddrWriter {
   /// Returns buffer size.
   virtual size_t getBufferSize() { return Buffer->size(); }
 
-  /// Returns False if .debug_addr section was created..
-  bool isInitialized() { return Buffer->size() > 0; }
+  /// Returns True if Buffer is not empty.
+  bool isInitialized() { return !Buffer->empty(); }
 
   /// Updates address base with the given Offset.
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
                               const uint64_t Offset);
 
-  /// Appends an AddressSectionBuffer to the address writer buffer for the given
-  /// CU.
+  /// Appends an AddressSectionBuffer to the address writer's buffer.
   void appendToAddressBuffer(const AddressSectionBuffer &Buffer) {
     *AddressStream << Buffer;
   }
 
-  /// Sets AddressByteSize for the CU.
-  void setAddressByteSize(const uint8_t AddressByteSize) {
-    this->AddressByteSize = AddressByteSize;
-  }
-
-  /// Sets AddrOffsetSectionBase for the CU.
-  void setAddrOffsetSectionBase(
-      const std::optional<uint64_t> AddrOffsetSectionBase) {
-    this->AddrOffsetSectionBase = AddrOffsetSectionBase;
-  }
-
 protected:
   class AddressForDWOCU {
   public:
@@ -436,8 +425,6 @@ class DebugAddrWriter {
   /// Address for the DWO CU associated with the address writer.
   AddressForDWOCU Map;
   uint8_t AddressByteSize;
-  std::optional<uint64_t> AddrOffsetSectionBase;
-  static constexpr uint32_t HeaderSize = 8;
   /// Mutex used for parallel processing of debug info.
   std::mutex WriterMutex;
   std::unique_ptr<AddressSectionBuffer> Buffer;
@@ -449,7 +436,8 @@ class DebugAddrWriter {
 class DebugAddrWriterDwarf5 : public DebugAddrWriter {
 public:
   DebugAddrWriterDwarf5() = delete;
-  DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC) {}
+  DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC){}
+  DebugAddrWriterDwarf5(BinaryContext *BC, uint8_t AddressByteSize, std::optional<uint64_t> AddrOffsetSectionBase) : DebugAddrWriter(BC, AddressByteSize), AddrOffsetSectionBase(AddrOffsetSectionBase){}
 
   /// Write out entries in to .debug_addr section for CUs.
   virtual std::optional<uint64_t> finalize(const size_t BufferSize) override;
@@ -467,6 +455,10 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
     }
     return Unit.getOffset();
   }
+
+private:
+  std::optional<uint64_t> AddrOffsetSectionBase;
+  static constexpr uint32_t HeaderSize = 8;
 };
 
 /// This class is NOT thread safe.
@@ -616,9 +608,9 @@ class DebugLoclistWriter : public DebugLocWriter {
   ~DebugLoclistWriter() {}
   DebugLoclistWriter() = delete;
   DebugLoclistWriter(DWARFUnit &Unit, uint8_t DV, bool SD,
-                     DebugAddrWriter *AddrW)
+                     DebugAddrWriter &AddrW)
       : DebugLocWriter(DV, LocWriterKind::DebugLoclistWriter),
-        AddrWriter(AddrW), CU(Unit), IsSplitDwarf(SD) {
+        AddrWriter(&AddrW), CU(Unit), IsSplitDwarf(SD) {
     if (DwarfVersion >= 5) {
       LocBodyBuffer = std::make_unique<DebugBufferVector>();
       LocBodyStream = std::make_unique<raw_svector_ostream>(*LocBodyBuffer);
@@ -630,8 +622,6 @@ class DebugLoclistWriter : public DebugLocWriter {
     }
   }
 
-  void setAddressWriter(DebugAddrWriter *AddrW) { AddrWriter = AddrW; }
-
   /// Stores location lists internally to be written out during finalize phase.
   virtual void addList(DIEBuilder &DIEBldr, DIE &Die, DIEValue &AttrInfo,
                        DebugLocationsVector &LocList) override;
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index c93e96b529c79..562ea5d759a1d 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -184,8 +184,6 @@ void DebugRangesSectionWriter::appendToRangeBuffer(
   *RangesStream << CUBuffer;
 }
 
-DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr;
-
 uint64_t DebugRangeListsSectionWriter::addRanges(
     DebugAddressRangesVector &&Ranges,
     std::map<DebugAddressRangesVector, uint64_t> &CachedRanges) {
@@ -395,6 +393,11 @@ DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
 }
 
+DebugAddrWriter::DebugAddrWriter(BinaryContext *BC, const uint8_t AddressByteSize) : BC(BC), AddressByteSize(AddressByteSize) {
+  Buffer = std::make_unique<AddressSectionBuffer>();
+  AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
+}
+
 void DebugAddrWriter::AddressForDWOCU::dump() {
   std::vector<IndexAddressPair> SortedMap(indexToAddressBegin(),
                                           indexToAdddessEnd());
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 3dd0eba8d2ce7..d9b7982e1232b 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -627,21 +627,18 @@ void DWARFRewriter::updateDebugInfo() {
   uint32_t CUIndex = 0;
   std::mutex AccessMutex;
   // Needs to be invoked in the same order as CUs are processed.
-  auto createRangeLocList = [&](DWARFUnit &CU) -> DebugLocWriter * {
+  auto createRangeLocListAddressWriters = [&](DWARFUnit &CU) -> DebugLocWriter * {
     std::lock_guard<std::mutex> Lock(AccessMutex);
     const uint16_t DwarfVersion = CU.getVersion();
     if (DwarfVersion >= 5) {
-      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC);
-      std::unique_ptr<DebugAddrWriter> &AddressWriterIterator =
+      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
+      DebugAddrWriter *AddressWriter =
           AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
-              .first->second;
-      DebugRangeListsSectionWriter::setAddressWriter(
-          AddressWriterIterator.get());
-      AddressWriterIterator->setAddressByteSize(CU.getAddressByteSize());
-      AddressWriterIterator->setAddrOffsetSectionBase(
-          CU.getAddrOffsetSectionBase());
+              .first->second.get();
+      RangeListsSectionWriter->setAddressWriter(
+          AddressWriter);
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
-          CU, DwarfVersion, false, AddressWriterIterator.get());
+          CU, DwarfVersion, false, *AddressWriter);
 
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
@@ -649,23 +646,22 @@ void DWARFRewriter::updateDebugInfo() {
         auto RangeListsSectionWriter =
             std::make_unique<DebugRangeListsSectionWriter>();
         RangeListsSectionWriter->initSection(CU);
-        RangeListsWritersByCU[*DWOId] = std::move(RangeListsSectionWriter);
+        DebugRangeListsSectionWriter *RangeListSectionWriter = RangeListsWritersByCU.insert({*DWOId, std::move(RangeListsSectionWriter)}).first->second.get();
+        RangeListSectionWriter->setAddressWriter(AddressWriter);
       }
 
     } else {
-      auto AddrW = std::make_unique<DebugAddrWriter>(&BC);
-      std::unique_ptr<DebugAddrWriter> &AddressWriterIterator =
-          AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
-              .first->second;
-      AddressWriterIterator->setAddressByteSize(CU.getAddressByteSize());
+      auto AddrW = std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
+      AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
                "LegacyRangeLists writer for DWO unit already exists.");
         auto LegacyRangesSectionWriterByCU =
             std::make_unique<DebugRangesSectionWriter>();
-        LegacyRangesWritersByCU[*DWOId] =
-            std::move(LegacyRangesSectionWriterByCU);
+        LegacyRangesSectionWriterByCU->initSection(CU);
+        LegacyRangesWritersByCU.insert({*DWOId,
+            std::move(LegacyRangesSectionWriterByCU)});
       }
     }
     return LocListWritersByCU[CUIndex++].get();
@@ -685,12 +681,12 @@ void DWARFRewriter::updateDebugInfo() {
     std::optional<uint64_t> DWOId = Unit->getDWOId();
     if (DWOId)
       SplitCU = BC.getDWOCU(*DWOId);
-    DebugLocWriter *DebugLocWriter = createRangeLocList(*Unit);
+    DebugLocWriter *DebugLocWriter = createRangeLocListAddressWriters(*Unit);
     DebugRangesSectionWriter *RangesSectionWriter =
         Unit->getVersion() >= 5 ? RangeListsSectionWriter.get()
                                 : LegacyRangesSectionWriter.get();
-    std::unique_ptr<DebugAddrWriter> &AddressWriter =
-        AddressWritersByCU[Unit->getOffset()];
+    DebugAddrWriter *AddressWriter =
+        AddressWritersByCU[Unit->getOffset()].get();
     // Skipping CUs that failed to load.
     if (SplitCU) {
       DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable,
@@ -712,7 +708,7 @@ void DWARFRewriter::updateDebugInfo() {
                                                  DWOStrWriter, **SplitCU,
                                                  DwarfOutputPath, DWOName);
       DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true,
-                                           AddressWriter.get());
+                                           *AddressWriter);
       DebugRangesSectionWriter *TempRangesSectionWriter = RangesSectionWriter;
       if (Unit->getVersion() >= 5) {
         TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get();
@@ -723,7 +719,7 @@ void DWARFRewriter::updateDebugInfo() {
       }
 
       updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter,
-                          *TempRangesSectionWriter, *AddressWriter.get());
+                          *TempRangesSectionWriter, *AddressWriter);
       DebugLocDWoWriter.finalize(DWODIEBuilder,
                                  *DWODIEBuilder.getUnitDIEbyUnit(**SplitCU));
       if (Unit->getVersion() >= 5)
@@ -742,7 +738,7 @@ void DWARFRewriter::updateDebugInfo() {
     }
 
     updateUnitDebugInfo(*Unit, *DIEBlder, *DebugLocWriter, *RangesSectionWriter,
-                        *AddressWriter.get(), RangesBase);
+                        *AddressWriter, RangesBase);
     DebugLocWriter->finalize(*DIEBlder, *DIEBlder->getUnitDIEbyUnit(*Unit));
     if (Unit->getVersion() >= 5)
       RangesSectionWriter->finalizeSection();
@@ -1641,8 +1637,8 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
     auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
     assert(AddressWriterIterator != AddressWritersByCU.end() &&
            "AddressWriter does not exist for CU");
-    std::unique_ptr<DebugAddrWriter> &AddressWriter =
-        AddressWriterIterator->second;
+    DebugAddrWriter *AddressWriter =
+        AddressWriterIterator->second.get();
     const size_t BufferOffset = FinalAddrWriter->getBufferSize();
     std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
     /// If Offset already exists in UnmodifiedAddressOffsets, then update with
@@ -2188,8 +2184,9 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
       auto AddrWriterIterator = AddressWritersByCU.find(Unit.getOffset());
       assert(AddrWriterIterator != AddressWritersByCU.end() &&
              "AddressWriter does not exist for CU");
+      DebugAddrWriter *AddrWriter = AddrWriterIterator->second.get();
       const uint32_t Index =
-          AddrWriterIterator->second->getIndexFromAddress(0, Unit);
+          AddrWriter->getIndexFromAddress(0, Unit);
       DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
                            LowPCAttrInfo.getForm(), DIEInteger(Index));
     } else {

>From 02b8c9cde97aaba0532f280a8420c70861302118 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 16:03:54 -0700
Subject: [PATCH 08/14] Formatting changes

---
 bolt/include/bolt/Core/DebugData.h |  7 +++++--
 bolt/lib/Core/DebugData.cpp        |  4 +++-
 bolt/lib/Rewrite/DWARFRewriter.cpp | 27 +++++++++++++++------------
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 1bbf13f0c60a6..481cca05539c2 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -436,8 +436,11 @@ class DebugAddrWriter {
 class DebugAddrWriterDwarf5 : public DebugAddrWriter {
 public:
   DebugAddrWriterDwarf5() = delete;
-  DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC){}
-  DebugAddrWriterDwarf5(BinaryContext *BC, uint8_t AddressByteSize, std::optional<uint64_t> AddrOffsetSectionBase) : DebugAddrWriter(BC, AddressByteSize), AddrOffsetSectionBase(AddrOffsetSectionBase){}
+  DebugAddrWriterDwarf5(BinaryContext *BC) : DebugAddrWriter(BC) {}
+  DebugAddrWriterDwarf5(BinaryContext *BC, uint8_t AddressByteSize,
+                        std::optional<uint64_t> AddrOffsetSectionBase)
+      : DebugAddrWriter(BC, AddressByteSize),
+        AddrOffsetSectionBase(AddrOffsetSectionBase) {}
 
   /// Write out entries in to .debug_addr section for CUs.
   virtual std::optional<uint64_t> finalize(const size_t BufferSize) override;
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 562ea5d759a1d..4b19e7d8440ff 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -393,7 +393,9 @@ DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
 }
 
-DebugAddrWriter::DebugAddrWriter(BinaryContext *BC, const uint8_t AddressByteSize) : BC(BC), AddressByteSize(AddressByteSize) {
+DebugAddrWriter::DebugAddrWriter(BinaryContext *BC,
+                                 const uint8_t AddressByteSize)
+    : BC(BC), AddressByteSize(AddressByteSize) {
   Buffer = std::make_unique<AddressSectionBuffer>();
   AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
 }
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index d9b7982e1232b..8649cc1b0d28c 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -627,16 +627,17 @@ void DWARFRewriter::updateDebugInfo() {
   uint32_t CUIndex = 0;
   std::mutex AccessMutex;
   // Needs to be invoked in the same order as CUs are processed.
-  auto createRangeLocListAddressWriters = [&](DWARFUnit &CU) -> DebugLocWriter * {
+  auto createRangeLocListAddressWriters =
+      [&](DWARFUnit &CU) -> DebugLocWriter * {
     std::lock_guard<std::mutex> Lock(AccessMutex);
     const uint16_t DwarfVersion = CU.getVersion();
     if (DwarfVersion >= 5) {
-      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(&BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
+      auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(
+          &BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
       DebugAddrWriter *AddressWriter =
           AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
               .first->second.get();
-      RangeListsSectionWriter->setAddressWriter(
-          AddressWriter);
+      RangeListsSectionWriter->setAddressWriter(AddressWriter);
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
           CU, DwarfVersion, false, *AddressWriter);
 
@@ -646,12 +647,16 @@ void DWARFRewriter::updateDebugInfo() {
         auto RangeListsSectionWriter =
             std::make_unique<DebugRangeListsSectionWriter>();
         RangeListsSectionWriter->initSection(CU);
-        DebugRangeListsSectionWriter *RangeListSectionWriter = RangeListsWritersByCU.insert({*DWOId, std::move(RangeListsSectionWriter)}).first->second.get();
+        DebugRangeListsSectionWriter *RangeListSectionWriter =
+            RangeListsWritersByCU
+                .insert({*DWOId, std::move(RangeListsSectionWriter)})
+                .first->second.get();
         RangeListSectionWriter->setAddressWriter(AddressWriter);
       }
 
     } else {
-      auto AddrW = std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
+      auto AddrW =
+          std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
       AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
@@ -660,8 +665,8 @@ void DWARFRewriter::updateDebugInfo() {
         auto LegacyRangesSectionWriterByCU =
             std::make_unique<DebugRangesSectionWriter>();
         LegacyRangesSectionWriterByCU->initSection(CU);
-        LegacyRangesWritersByCU.insert({*DWOId,
-            std::move(LegacyRangesSectionWriterByCU)});
+        LegacyRangesWritersByCU.insert(
+            {*DWOId, std::move(LegacyRangesSectionWriterByCU)});
       }
     }
     return LocListWritersByCU[CUIndex++].get();
@@ -1637,8 +1642,7 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
     auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
     assert(AddressWriterIterator != AddressWritersByCU.end() &&
            "AddressWriter does not exist for CU");
-    DebugAddrWriter *AddressWriter =
-        AddressWriterIterator->second.get();
+    DebugAddrWriter *AddressWriter = AddressWriterIterator->second.get();
     const size_t BufferOffset = FinalAddrWriter->getBufferSize();
     std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
     /// If Offset already exists in UnmodifiedAddressOffsets, then update with
@@ -2185,8 +2189,7 @@ void DWARFRewriter::convertToRangesPatchDebugInfo(
       assert(AddrWriterIterator != AddressWritersByCU.end() &&
              "AddressWriter does not exist for CU");
       DebugAddrWriter *AddrWriter = AddrWriterIterator->second.get();
-      const uint32_t Index =
-          AddrWriter->getIndexFromAddress(0, Unit);
+      const uint32_t Index = AddrWriter->getIndexFromAddress(0, Unit);
       DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
                            LowPCAttrInfo.getForm(), DIEInteger(Index));
     } else {

>From fa40d614f4f7cfed6c7d7eaea0ba63c6e4595cdd Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 20:42:06 -0700
Subject: [PATCH 09/14] Clean up code updating maps

---
 bolt/lib/Rewrite/DWARFRewriter.cpp | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index 8649cc1b0d28c..ccb541c9bb361 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -634,25 +634,21 @@ void DWARFRewriter::updateDebugInfo() {
     if (DwarfVersion >= 5) {
       auto AddrW = std::make_unique<DebugAddrWriterDwarf5>(
           &BC, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
-      DebugAddrWriter *AddressWriter =
-          AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)})
-              .first->second.get();
-      RangeListsSectionWriter->setAddressWriter(AddressWriter);
-      LocListWritersByCU[CUIndex] = std::make_unique<DebugLoclistWriter>(
-          CU, DwarfVersion, false, *AddressWriter);
+      RangeListsSectionWriter->setAddressWriter(AddrW.get());
+      LocListWritersByCU[CUIndex] =
+          std::make_unique<DebugLoclistWriter>(CU, DwarfVersion, false, *AddrW);
 
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
                "RangeLists writer for DWO unit already exists.");
-        auto RangeListsSectionWriter =
+        auto RangeListSectionWriter =
             std::make_unique<DebugRangeListsSectionWriter>();
-        RangeListsSectionWriter->initSection(CU);
-        DebugRangeListsSectionWriter *RangeListSectionWriter =
-            RangeListsWritersByCU
-                .insert({*DWOId, std::move(RangeListsSectionWriter)})
-                .first->second.get();
-        RangeListSectionWriter->setAddressWriter(AddressWriter);
+        RangeListSectionWriter->initSection(CU);
+        RangeListSectionWriter->setAddressWriter(AddrW.get());
+        RangeListsWritersByCU.insert(
+            {*DWOId, std::move(RangeListSectionWriter)});
       }
+      AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
 
     } else {
       auto AddrW =

>From d975f44d4a800f98126ead6579a15d059195e51a Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 21:05:16 -0700
Subject: [PATCH 10/14] Remove redundant code

---
 bolt/include/bolt/Core/DebugData.h | 4 ++--
 bolt/lib/Core/DebugData.cpp        | 5 -----
 2 files changed, 2 insertions(+), 7 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 481cca05539c2..fba5da77451bb 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -336,7 +336,7 @@ using AddressSectionBuffer = SmallVector<char, 4>;
 class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
-  DebugAddrWriter(BinaryContext *BC_);
+  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, 255){};
   DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.
@@ -460,7 +460,7 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   }
 
 private:
-  std::optional<uint64_t> AddrOffsetSectionBase;
+  std::optional<uint64_t> AddrOffsetSectionBase = INT_MAX;
   static constexpr uint32_t HeaderSize = 8;
 };
 
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index 4b19e7d8440ff..b5d5c0a62fd2b 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -388,11 +388,6 @@ void DebugARangesSectionWriter::writeARangesSection(
   }
 }
 
-DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
-  Buffer = std::make_unique<AddressSectionBuffer>();
-  AddressStream = std::make_unique<raw_svector_ostream>(*Buffer);
-}
-
 DebugAddrWriter::DebugAddrWriter(BinaryContext *BC,
                                  const uint8_t AddressByteSize)
     : BC(BC), AddressByteSize(AddressByteSize) {

>From 984033dfcefd444b7824c71bd8336f2f03311b88 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Wed, 10 Jul 2024 21:10:36 -0700
Subject: [PATCH 11/14] Formatting change

---
 bolt/include/bolt/Core/DebugData.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index fba5da77451bb..b857745b0fdbe 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -336,7 +336,7 @@ using AddressSectionBuffer = SmallVector<char, 4>;
 class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
-  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, 255){};
+  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, 255) {};
   DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.

>From 3755731025f57266615db4bd0be990e48c43d6de Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Thu, 11 Jul 2024 10:01:57 -0700
Subject: [PATCH 12/14] Update to default initialization

---
 bolt/include/bolt/Core/DebugData.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index b857745b0fdbe..2000f512f3246 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -460,7 +460,7 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   }
 
 private:
-  std::optional<uint64_t> AddrOffsetSectionBase = INT_MAX;
+  std::optional<uint64_t> AddrOffsetSectionBase = std::nullopt;
   static constexpr uint32_t HeaderSize = 8;
 };
 

>From db8f5804e47e20dbd1e9b391997ff7c5d05ee8a5 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Thu, 11 Jul 2024 16:29:13 -0700
Subject: [PATCH 13/14] Updates and formatting changes

---
 bolt/include/bolt/Core/DebugData.h        | 11 +++---
 bolt/include/bolt/Rewrite/DWARFRewriter.h | 10 +++---
 bolt/lib/Core/DebugData.cpp               |  4 +--
 bolt/lib/Rewrite/DWARFRewriter.cpp        | 41 +++++++++++++----------
 4 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 2000f512f3246..fb9ddc7d17bc2 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -336,7 +336,7 @@ using AddressSectionBuffer = SmallVector<char, 4>;
 class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
-  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, 255) {};
+  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, UCHAR_MAX){};
   DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.
@@ -353,10 +353,10 @@ class DebugAddrWriter {
   }
 
   /// Returns buffer size.
-  virtual size_t getBufferSize() { return Buffer->size(); }
+  virtual size_t getBufferSize() const { return Buffer->size(); }
 
   /// Returns True if Buffer is not empty.
-  bool isInitialized() { return !Buffer->empty(); }
+  bool isInitialized() const { return !Buffer->empty(); }
 
   /// Updates address base with the given Offset.
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
@@ -445,6 +445,7 @@ class DebugAddrWriterDwarf5 : public DebugAddrWriter {
   /// Write out entries in to .debug_addr section for CUs.
   virtual std::optional<uint64_t> finalize(const size_t BufferSize) override;
 
+  /// Updates address base with the given Offset.
   virtual void updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
                               const uint64_t Offset) override;
 
@@ -613,7 +614,7 @@ class DebugLoclistWriter : public DebugLocWriter {
   DebugLoclistWriter(DWARFUnit &Unit, uint8_t DV, bool SD,
                      DebugAddrWriter &AddrW)
       : DebugLocWriter(DV, LocWriterKind::DebugLoclistWriter),
-        AddrWriter(&AddrW), CU(Unit), IsSplitDwarf(SD) {
+        AddrWriter(AddrW), CU(Unit), IsSplitDwarf(SD) {
     if (DwarfVersion >= 5) {
       LocBodyBuffer = std::make_unique<DebugBufferVector>();
       LocBodyStream = std::make_unique<raw_svector_ostream>(*LocBodyBuffer);
@@ -653,7 +654,7 @@ class DebugLoclistWriter : public DebugLocWriter {
   /// Writes out locations in to a local buffer and applies debug info patches.
   void finalizeDWARF5(DIEBuilder &DIEBldr, DIE &Die);
 
-  DebugAddrWriter *AddrWriter;
+  DebugAddrWriter &AddrWriter;
   DWARFUnit &CU;
   bool IsSplitDwarf{false};
   // Used for DWARF5 to store location lists before being finalized.
diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h
index ac3b26b08e593..abd18b56113b6 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -66,10 +66,6 @@ class DWARFRewriter {
   /// .debug_aranges DWARF section.
   std::unique_ptr<DebugARangesSectionWriter> ARangesSectionWriter;
 
-  /// Stores and serializes information that will be put into the
-  /// .debug_addr DWARF section.
-  std::unique_ptr<DebugAddrWriter> FinalAddrWriter;
-
   /// Stores and serializes information that will be put in to the
   /// .debug_addr DWARF section.
   /// Does not do de-duplication.
@@ -146,13 +142,15 @@ class DWARFRewriter {
   /// Process and write out CUs that are passsed in.
   void finalizeCompileUnits(DIEBuilder &DIEBlder, DIEStreamer &Streamer,
                             CUOffsetMap &CUMap,
-                            const std::list<DWARFUnit *> &CUs);
+                            const std::list<DWARFUnit *> &CUs,
+                            DebugAddrWriter &FinalAddrWriter);
 
   /// Finalize debug sections in the main binary.
   void finalizeDebugSections(DIEBuilder &DIEBlder,
                              DWARF5AcceleratorTable &DebugNamesTable,
                              DIEStreamer &Streamer, raw_svector_ostream &ObjOS,
-                             CUOffsetMap &CUMap);
+                             CUOffsetMap &CUMap,
+                             DebugAddrWriter &FinalAddrWriter);
 
   /// Patches the binary for DWARF address ranges (e.g. in functions and lexical
   /// blocks) to be updated.
diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp
index b5d5c0a62fd2b..002f58c474346 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -711,11 +711,11 @@ void DebugLoclistWriter::addList(DIEBuilder &DIEBldr, DIE &Die,
                                  DIEValue &AttrInfo,
                                  DebugLocationsVector &LocList) {
   if (DwarfVersion < 5)
-    writeLegacyLocList(AttrInfo, LocList, DIEBldr, Die, *AddrWriter, *LocBuffer,
+    writeLegacyLocList(AttrInfo, LocList, DIEBldr, Die, AddrWriter, *LocBuffer,
                        CU, *LocStream);
   else
     writeDWARF5LocList(NumberOfEntries, AttrInfo, LocList, Die, DIEBldr,
-                       *AddrWriter, *LocBodyBuffer, RelativeLocListOffsets, CU,
+                       AddrWriter, *LocBodyBuffer, RelativeLocListOffsets, CU,
                        *LocBodyStream);
 }
 
diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp
index ccb541c9bb361..042c39a574561 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -612,6 +612,10 @@ void DWARFRewriter::updateDebugInfo() {
     errs() << "BOLT-WARNING: --deterministic-debuginfo is being deprecated\n";
   }
 
+  /// Stores and serializes information that will be put into the
+  /// .debug_addr DWARF section.
+  std::unique_ptr<DebugAddrWriter> FinalAddrWriter;
+
   if (BC.isDWARF5Used()) {
     FinalAddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
     RangeListsSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
@@ -641,19 +645,18 @@ void DWARFRewriter::updateDebugInfo() {
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(RangeListsWritersByCU.count(*DWOId) == 0 &&
                "RangeLists writer for DWO unit already exists.");
-        auto RangeListSectionWriter =
+        auto DWORangeListsSectionWriter =
             std::make_unique<DebugRangeListsSectionWriter>();
-        RangeListSectionWriter->initSection(CU);
-        RangeListSectionWriter->setAddressWriter(AddrW.get());
-        RangeListsWritersByCU.insert(
-            {*DWOId, std::move(RangeListSectionWriter)});
+        DWORangeListsSectionWriter->initSection(CU);
+        DWORangeListsSectionWriter->setAddressWriter(AddrW.get());
+        RangeListsWritersByCU[*DWOId] = std::move(DWORangeListsSectionWriter);
       }
-      AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
+      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
 
     } else {
       auto AddrW =
           std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
-      AddressWritersByCU.insert({CU.getOffset(), std::move(AddrW)});
+      AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
       LocListWritersByCU[CUIndex] = std::make_unique<DebugLocWriter>();
       if (std::optional<uint64_t> DWOId = CU.getDWOId()) {
         assert(LegacyRangesWritersByCU.count(*DWOId) == 0 &&
@@ -661,8 +664,8 @@ void DWARFRewriter::updateDebugInfo() {
         auto LegacyRangesSectionWriterByCU =
             std::make_unique<DebugRangesSectionWriter>();
         LegacyRangesSectionWriterByCU->initSection(CU);
-        LegacyRangesWritersByCU.insert(
-            {*DWOId, std::move(LegacyRangesSectionWriterByCU)});
+        LegacyRangesWritersByCU[*DWOId] =
+            std::move(LegacyRangesSectionWriterByCU);
       }
     }
     return LocListWritersByCU[CUIndex++].get();
@@ -768,7 +771,7 @@ void DWARFRewriter::updateDebugInfo() {
       for (DWARFUnit *CU : DIEBlder.getProcessedCUs())
         processUnitDIE(CU, &DIEBlder);
       finalizeCompileUnits(DIEBlder, *Streamer, OffsetMap,
-                           DIEBlder.getProcessedCUs());
+                           DIEBlder.getProcessedCUs(), *FinalAddrWriter);
     }
   } else {
     // Update unit debug info in parallel
@@ -783,8 +786,8 @@ void DWARFRewriter::updateDebugInfo() {
   if (opts::WriteDWP)
     finalizeDWP(State);
 
-  finalizeDebugSections(DIEBlder, DebugNamesTable, *Streamer, *ObjOS,
-                        OffsetMap);
+  finalizeDebugSections(DIEBlder, DebugNamesTable, *Streamer, *ObjOS, OffsetMap,
+                        *FinalAddrWriter);
   GDBIndexSection.updateGdbIndexSection(OffsetMap, CUIndex,
                                         *ARangesSectionWriter);
 }
@@ -1522,7 +1525,8 @@ CUOffsetMap DWARFRewriter::finalizeTypeSections(DIEBuilder &DIEBlder,
 
 void DWARFRewriter::finalizeDebugSections(
     DIEBuilder &DIEBlder, DWARF5AcceleratorTable &DebugNamesTable,
-    DIEStreamer &Streamer, raw_svector_ostream &ObjOS, CUOffsetMap &CUMap) {
+    DIEStreamer &Streamer, raw_svector_ostream &ObjOS, CUOffsetMap &CUMap,
+    DebugAddrWriter &FinalAddrWriter) {
   if (StrWriter->isInitialized()) {
     RewriteInstance::addToDebugSectionsToOverwrite(".debug_str");
     std::unique_ptr<DebugStrBufferVector> DebugStrSectionContents =
@@ -1575,9 +1579,9 @@ void DWARFRewriter::finalizeDebugSections(
           LocationListSectionContents->size());
   }
 
-  if (FinalAddrWriter->isInitialized()) {
+  if (FinalAddrWriter.isInitialized()) {
     std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
-        FinalAddrWriter->releaseBuffer();
+        FinalAddrWriter.releaseBuffer();
     BC.registerOrUpdateNoteSection(".debug_addr",
                                    copyByteArray(*AddressSectionContents),
                                    AddressSectionContents->size());
@@ -1633,13 +1637,14 @@ void DWARFRewriter::finalizeDebugSections(
 void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
                                          DIEStreamer &Streamer,
                                          CUOffsetMap &CUMap,
-                                         const std::list<DWARFUnit *> &CUs) {
+                                         const std::list<DWARFUnit *> &CUs,
+                                         DebugAddrWriter &FinalAddrWriter) {
   for (DWARFUnit *CU : CUs) {
     auto AddressWriterIterator = AddressWritersByCU.find(CU->getOffset());
     assert(AddressWriterIterator != AddressWritersByCU.end() &&
            "AddressWriter does not exist for CU");
     DebugAddrWriter *AddressWriter = AddressWriterIterator->second.get();
-    const size_t BufferOffset = FinalAddrWriter->getBufferSize();
+    const size_t BufferOffset = FinalAddrWriter.getBufferSize();
     std::optional<uint64_t> Offset = AddressWriter->finalize(BufferOffset);
     /// If Offset already exists in UnmodifiedAddressOffsets, then update with
     /// Offset, else update with BufferOffset.
@@ -1650,7 +1655,7 @@ void DWARFRewriter::finalizeCompileUnits(DIEBuilder &DIEBlder,
     if (AddressWriter->isInitialized()) {
       std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
           AddressWriter->releaseBuffer();
-      FinalAddrWriter->appendToAddressBuffer(*AddressSectionContents);
+      FinalAddrWriter.appendToAddressBuffer(*AddressSectionContents);
     }
     if (CU->getVersion() != 4)
       continue;

>From 4907b23671450e94e418dfadf6345fa67a6a3a86 Mon Sep 17 00:00:00 2001
From: Sayhaan Siddiqui <sayhaan at meta.com>
Date: Thu, 11 Jul 2024 16:34:55 -0700
Subject: [PATCH 14/14] Formatting changes

---
 bolt/include/bolt/Core/DebugData.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index fb9ddc7d17bc2..5935ffaa46af7 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -336,7 +336,7 @@ using AddressSectionBuffer = SmallVector<char, 4>;
 class DebugAddrWriter {
 public:
   DebugAddrWriter() = delete;
-  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, UCHAR_MAX){};
+  DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, UCHAR_MAX) {};
   DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
   virtual ~DebugAddrWriter(){};
   /// Given an address returns an index in .debug_addr.



More information about the llvm-commits mailing list