aboutsummaryrefslogtreecommitdiff
path: root/bolt
diff options
context:
space:
mode:
authorSayhaan Siddiqui <49014204+sayhaan@users.noreply.github.com>2024-07-15 23:03:43 -0700
committerGitHub <noreply@github.com>2024-07-15 23:03:43 -0700
commite140a8a3c83017c998a0dacbf9d128918852b429 (patch)
tree426457d88990385507570ba8637fa195b9492f25 /bolt
parent8618c86ee2cc518ccc6b753179c40f68ba5218a8 (diff)
downloadllvm-e140a8a3c83017c998a0dacbf9d128918852b429.zip
llvm-e140a8a3c83017c998a0dacbf9d128918852b429.tar.gz
llvm-e140a8a3c83017c998a0dacbf9d128918852b429.tar.bz2
[BOLT][DWARF][NFC] Refactor address writers (#98094)
Refactors address writers to create an instance for each CU and its DWO CU.
Diffstat (limited to 'bolt')
-rw-r--r--bolt/include/bolt/Core/DebugData.h64
-rw-r--r--bolt/include/bolt/Rewrite/DWARFRewriter.h15
-rw-r--r--bolt/lib/Core/DebugData.cpp100
-rw-r--r--bolt/lib/Rewrite/DWARFRewriter.cpp97
-rw-r--r--bolt/test/X86/dwarf5-addr-section-reuse.s6
5 files changed, 165 insertions, 117 deletions
diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 2324e57..5935ffa 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -256,7 +256,7 @@ public:
};
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 @@ public:
}
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
@@ -336,21 +336,36 @@ using AddressSectionBuffer = SmallVector<char, 4>;
class DebugAddrWriter {
public:
DebugAddrWriter() = delete;
- DebugAddrWriter(BinaryContext *BC_);
+ DebugAddrWriter(BinaryContext *BC_) : DebugAddrWriter(BC_, UCHAR_MAX) {};
+ DebugAddrWriter(BinaryContext *BC_, uint8_t AddressByteSize);
virtual ~DebugAddrWriter(){};
/// Given an address returns an index in .debug_addr.
/// Adds Address to map.
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 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() const { return Buffer->size(); }
+
+ /// Returns True if Buffer is not empty.
+ bool isInitialized() const { return !Buffer->empty(); }
- /// Returns False if .debug_addr section was created..
- bool isInitialized() const { return !AddressMaps.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's buffer.
+ void appendToAddressBuffer(const AddressSectionBuffer &Buffer) {
+ *AddressStream << Buffer;
+ }
protected:
class AddressForDWOCU {
@@ -407,23 +422,32 @@ protected:
}
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;
/// 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 {
public:
DebugAddrWriterDwarf5() = delete;
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 void update(DIEBuilder &DIEBlder, DWARFUnit &CUs) override;
+ 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;
protected:
/// Given DWARFUnit \p Unit returns either DWO ID or it's offset within
@@ -435,6 +459,10 @@ protected:
}
return Unit.getOffset();
}
+
+private:
+ std::optional<uint64_t> AddrOffsetSectionBase = std::nullopt;
+ static constexpr uint32_t HeaderSize = 8;
};
/// This class is NOT thread safe.
@@ -583,12 +611,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,8 +626,6 @@ public:
}
}
- static 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;
@@ -630,7 +654,7 @@ private:
/// 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 4f576eaa..abd18b5 100644
--- a/bolt/include/bolt/Rewrite/DWARFRewriter.h
+++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h
@@ -66,10 +66,6 @@ private:
/// .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> AddrWriter;
-
/// Stores and serializes information that will be put in to the
/// .debug_addr DWARF section.
/// Does not do de-duplication.
@@ -93,6 +89,10 @@ private:
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 +115,7 @@ private:
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.
@@ -141,13 +142,15 @@ private:
/// 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 76c3545..002f58c 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) {
@@ -390,7 +388,9 @@ void DebugARangesSectionWriter::writeARangesSection(
}
}
-DebugAddrWriter::DebugAddrWriter(BinaryContext *BC) : BC(BC) {
+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);
}
@@ -405,11 +405,6 @@ 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];
auto Entry = Map.find(Address);
if (Entry == Map.end()) {
auto Index = Map.getNextIndex();
@@ -449,29 +444,23 @@ 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())
- return;
- std::vector<IndexAddressPair> SortedMap(AM->second.indexToAddressBegin(),
- AM->second.indexToAdddessEnd());
+void DebugAddrWriter::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+ const uint64_t Offset) {
+ updateAddressBase(DIEBlder, *this, CU, Offset);
+}
+
+std::optional<uint64_t> DebugAddrWriter::finalize(const 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 = CU.getAddressByteSize();
uint32_t Counter = 0;
auto WriteAddress = [&](uint64_t Address) -> void {
++Counter;
- switch (AddrSize) {
+ switch (AddressByteSize) {
default:
assert(false && "Address Size is invalid.");
break;
@@ -490,10 +479,19 @@ void DebugAddrWriter::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
WriteAddress(0);
WriteAddress(Val.second);
}
- updateAddressBase(DIEBlder, *this, CU, Offset);
+ return std::nullopt;
+}
+
+void DebugAddrWriterDwarf5::updateAddrBase(DIEBuilder &DIEBlder, DWARFUnit &CU,
+ const uint64_t Offset) {
+ /// Header for DWARF5 has size 8, so we add it to the offset.
+ updateAddressBase(DIEBlder, *this, CU, Offset + HeaderSize);
}
-void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
+DenseMap<uint64_t, uint64_t> DebugAddrWriter::UnmodifiedAddressOffsets;
+
+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()
@@ -504,55 +502,44 @@ void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
Endian == llvm::endianness::little, 0);
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);
// 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 (!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()) {
- updateAddressBase(DIEBlder, *this, CU, Iter->getSecond());
- 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())
- 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
- 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;
@@ -571,6 +558,7 @@ void DebugAddrWriterDwarf5::update(DIEBuilder &DIEBlder, DWARFUnit &CU) {
writeAddress(0);
writeAddress(Val.second);
}
+ return std::nullopt;
}
void DebugLocWriter::init() {
@@ -723,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);
}
@@ -789,8 +777,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 89168b4..042c39a 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -612,12 +612,15 @@ 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()) {
- AddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
+ FinalAddrWriter = std::make_unique<DebugAddrWriterDwarf5>(&BC);
RangeListsSectionWriter = std::make_unique<DebugRangeListsSectionWriter>();
- DebugRangeListsSectionWriter::setAddressWriter(AddrWriter.get());
} else {
- AddrWriter = std::make_unique<DebugAddrWriter>(&BC);
+ FinalAddrWriter = std::make_unique<DebugAddrWriter>(&BC);
}
if (BC.isDWARFLegacyUsed()) {
@@ -625,34 +628,42 @@ 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.
- 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, CU.getAddressByteSize(), CU.getAddrOffsetSectionBase());
+ RangeListsSectionWriter->setAddressWriter(AddrW.get());
LocListWritersByCU[CUIndex] =
- std::make_unique<DebugLoclistWriter>(CU, DwarfVersion, false);
+ 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 DWORangeListsSectionWriter =
std::make_unique<DebugRangeListsSectionWriter>();
- RangeListsSectionWriter->initSection(CU);
- RangeListsWritersByCU[*DWOId] = std::move(RangeListsSectionWriter);
+ DWORangeListsSectionWriter->initSection(CU);
+ DWORangeListsSectionWriter->setAddressWriter(AddrW.get());
+ RangeListsWritersByCU[*DWOId] = std::move(DWORangeListsSectionWriter);
}
+ AddressWritersByCU[CU.getOffset()] = std::move(AddrW);
} else {
+ auto AddrW =
+ std::make_unique<DebugAddrWriter>(&BC, CU.getAddressByteSize());
+ 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 &&
"LegacyRangeLists writer for DWO unit already exists.");
auto LegacyRangesSectionWriterByCU =
std::make_unique<DebugRangesSectionWriter>();
+ LegacyRangesSectionWriterByCU->initSection(CU);
LegacyRangesWritersByCU[*DWOId] =
std::move(LegacyRangesSectionWriterByCU);
}
@@ -674,10 +685,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();
+ DebugAddrWriter *AddressWriter =
+ AddressWritersByCU[Unit->getOffset()].get();
// Skipping CUs that failed to load.
if (SplitCU) {
DIEBuilder DWODIEBuilder(BC, &(*SplitCU)->getContext(), DebugNamesTable,
@@ -698,7 +711,8 @@ void DWARFRewriter::updateDebugInfo() {
DWODIEBuilder.updateDWONameCompDirForTypes(DWOStrOffstsWriter,
DWOStrWriter, **SplitCU,
DwarfOutputPath, DWOName);
- DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true);
+ DebugLoclistWriter DebugLocDWoWriter(*Unit, Unit->getVersion(), true,
+ *AddressWriter);
DebugRangesSectionWriter *TempRangesSectionWriter = RangesSectionWriter;
if (Unit->getVersion() >= 5) {
TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get();
@@ -709,7 +723,7 @@ void DWARFRewriter::updateDebugInfo() {
}
updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter,
- *TempRangesSectionWriter);
+ *TempRangesSectionWriter, *AddressWriter);
DebugLocDWoWriter.finalize(DWODIEBuilder,
*DWODIEBuilder.getUnitDIEbyUnit(**SplitCU));
if (Unit->getVersion() >= 5)
@@ -728,11 +742,10 @@ void DWARFRewriter::updateDebugInfo() {
}
updateUnitDebugInfo(*Unit, *DIEBlder, *DebugLocWriter, *RangesSectionWriter,
- RangesBase);
+ *AddressWriter, RangesBase);
DebugLocWriter->finalize(*DIEBlder, *DIEBlder->getUnitDIEbyUnit(*Unit));
if (Unit->getVersion() >= 5)
RangesSectionWriter->finalizeSection();
- AddrWriter->update(*DIEBlder, *Unit);
};
DIEBuilder DIEBlder(BC, BC.DwCtx.get(), DebugNamesTable);
@@ -758,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
@@ -773,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);
}
@@ -782,7 +795,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 +829,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 +993,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 +1210,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 +1262,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));
@@ -1512,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 =
@@ -1565,13 +1579,12 @@ 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();
+ if (FinalAddrWriter.isInitialized()) {
+ std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
+ FinalAddrWriter.releaseBuffer();
BC.registerOrUpdateNoteSection(".debug_addr",
- copyByteArray(AddressSectionContents),
- AddressSectionContents.size());
+ copyByteArray(*AddressSectionContents),
+ AddressSectionContents->size());
}
Streamer.emitAbbrevs(DIEBlder.getAbbrevs(), BC.DwCtx->getMaxVersion());
@@ -1624,8 +1637,26 @@ 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();
+ 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())
+ AddressWriter->updateAddrBase(DIEBlder, *CU, BufferOffset);
+ if (AddressWriter->isInitialized()) {
+ std::unique_ptr<AddressSectionBuffer> AddressSectionContents =
+ AddressWriter->releaseBuffer();
+ FinalAddrWriter.appendToAddressBuffer(*AddressSectionContents);
+ }
if (CU->getVersion() != 4)
continue;
std::optional<uint64_t> DWOId = CU->getDWOId();
@@ -2155,6 +2186,10 @@ 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");
+ DebugAddrWriter *AddrWriter = AddrWriterIterator->second.get();
const uint32_t Index = AddrWriter->getIndexFromAddress(0, Unit);
DIEBldr.replaceValue(&Die, LowPCAttrInfo.getAttribute(),
LowPCAttrInfo.getForm(), DIEInteger(Index));
diff --git a/bolt/test/X86/dwarf5-addr-section-reuse.s b/bolt/test/X86/dwarf5-addr-section-reuse.s
index 6b00ce0..cf511d6 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)