[llvm] [BOLT][DWARF][NFC] Refactor address writers (PR #98094)
Sayhaan Siddiqui via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 10 16:04:16 PDT 2024
https://github.com/sayhaan updated https://github.com/llvm/llvm-project/pull/98094
>From e5227a6247d621f287c9b54599ae0f8013387787 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 1/8] 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 144433ac78a37..05217c699f0dd 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -344,14 +344,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 {
@@ -396,6 +416,8 @@ class DebugAddrWriter {
void dump();
+ bool empty = false;
+
private:
AddressToIndexMap AddressToIndex;
IndexToAddressMap IndexToAddress;
@@ -408,14 +430,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 {
@@ -424,7 +448,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
@@ -584,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);
@@ -601,7 +626,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,
@@ -631,7 +656,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 08d4c45aac791..52df5d5e55707 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 1f426d0adfc61..22209f6d62303 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);
}
@@ -623,8 +622,6 @@ void DWARFRewriter::updateDebugInfo() {
if (BC.isDWARFLegacyUsed())
LegacyRangesSectionWriter = std::make_unique<DebugRangesSectionWriter>();
- DebugLoclistWriter::setAddressWriter(AddrWriter.get());
-
uint32_t CUIndex = 0;
std::mutex AccessMutex;
// Needs to be invoked in the same order as CUs are processed.
@@ -632,8 +629,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 &&
@@ -645,6 +650,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 &&
@@ -677,6 +686,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,
@@ -697,7 +707,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();
@@ -708,7 +719,7 @@ void DWARFRewriter::updateDebugInfo() {
}
updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter,
- *TempRangesSectionWriter);
+ *TempRangesSectionWriter, *AddressWriter.get());
DebugLocDWoWriter.finalize(DWODIEBuilder,
*DWODIEBuilder.getUnitDIEbyUnit(**SplitCU));
if (Unit->getVersion() >= 5)
@@ -727,11 +738,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);
@@ -781,7 +791,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;
@@ -815,7 +825,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));
@@ -979,7 +989,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) {
@@ -1196,7 +1206,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
@@ -1248,7 +1258,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));
@@ -1567,14 +1577,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();
@@ -1628,6 +1634,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();
@@ -2158,7 +2174,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 329a9480f708a74eef88f72c097959b454082a86 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 2/8] 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 05217c699f0dd..313e3aaa627d5 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -344,14 +344,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,
@@ -364,12 +369,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;
}
@@ -416,8 +422,6 @@ class DebugAddrWriter {
void dump();
- bool empty = false;
-
private:
AddressToIndexMap AddressToIndex;
IndexToAddressMap IndexToAddress;
@@ -434,6 +438,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;
@@ -448,7 +453,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 52df5d5e55707..8f9816f7b905f 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 22209f6d62303..03f11972188ac 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())
@@ -630,15 +630,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 &&
@@ -651,9 +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());
+ 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 &&
@@ -686,7 +688,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,
@@ -1577,10 +1580,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();
@@ -1637,12 +1643,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;
@@ -2174,8 +2186,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 637df228f22351c9b65e0844f46ef33be4881a60 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 3/8] 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 03f11972188ac..60be27314c20a 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -1647,6 +1647,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 9262e7a28afcdc99115bd223fd5f60b06a7e8339 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 4/8] 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 8f9816f7b905f..5a1168900475b 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 3108b8a79a4a9fdbc4e50f3bfe39f36a7cf6361c 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 5/8] 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 5a1168900475b..314faacb1e231 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 38d043a216b0cb556a075ce961783ff4ccceec58 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 6/8] 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 3c2c58c06e5a06806b43ac8dcbb8e30f43abbe67 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 7/8] Updates and formatting changes
---
bolt/include/bolt/Core/DebugData.h | 38 +++++++++--------------
bolt/lib/Core/DebugData.cpp | 7 +++--
bolt/lib/Rewrite/DWARFRewriter.cpp | 50 ++++++++++++++----------------
3 files changed, 42 insertions(+), 53 deletions(-)
diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h
index 313e3aaa627d5..e7e0be692cbc6 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -257,7 +257,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(
@@ -285,7 +285,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
@@ -338,6 +338,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.
@@ -355,30 +356,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:
@@ -437,8 +426,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;
@@ -450,7 +437,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;
@@ -468,6 +456,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.
@@ -617,9 +609,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);
@@ -631,8 +623,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 314faacb1e231..dde7be5e2dfb3 100644
--- a/bolt/lib/Core/DebugData.cpp
+++ b/bolt/lib/Core/DebugData.cpp
@@ -183,8 +183,6 @@ void DebugRangesSectionWriter::appendToRangeBuffer(
SectionOffset = RangesBuffer->size();
}
-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 60be27314c20a..18a7e6f5b3063 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -625,21 +625,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 &&
@@ -647,15 +644,13 @@ 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 &&
@@ -663,8 +658,8 @@ void DWARFRewriter::updateDebugInfo() {
auto LegacyRangesSectionWriterByCU =
std::make_unique<DebugRangesSectionWriter>();
LegacyRangesSectionWriterByCU->initSection(CU);
- LegacyRangesWritersByCU[*DWOId] =
- std::move(LegacyRangesSectionWriterByCU);
+ LegacyRangesWritersByCU.insert({*DWOId,
+ std::move(LegacyRangesSectionWriterByCU)});
}
}
return LocListWritersByCU[CUIndex++].get();
@@ -684,12 +679,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,
@@ -711,7 +706,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();
@@ -722,7 +717,7 @@ void DWARFRewriter::updateDebugInfo() {
}
updateUnitDebugInfo(*(*SplitCU), DWODIEBuilder, DebugLocDWoWriter,
- *TempRangesSectionWriter, *AddressWriter.get());
+ *TempRangesSectionWriter, *AddressWriter);
DebugLocDWoWriter.finalize(DWODIEBuilder,
*DWODIEBuilder.getUnitDIEbyUnit(**SplitCU));
if (Unit->getVersion() >= 5)
@@ -741,7 +736,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();
@@ -1643,8 +1638,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
@@ -2191,8 +2186,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 d6a713890befa3ed430b18e753cf5d349c58515c 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 8/8] 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 e7e0be692cbc6..93f12432dec5e 100644
--- a/bolt/include/bolt/Core/DebugData.h
+++ b/bolt/include/bolt/Core/DebugData.h
@@ -437,8 +437,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 dde7be5e2dfb3..ccd362d31344f 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 18a7e6f5b3063..4e7ac997c9ce8 100644
--- a/bolt/lib/Rewrite/DWARFRewriter.cpp
+++ b/bolt/lib/Rewrite/DWARFRewriter.cpp
@@ -625,16 +625,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);
@@ -644,12 +645,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()) {
@@ -658,8 +663,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();
@@ -1638,8 +1643,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
@@ -2187,8 +2191,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 {
More information about the llvm-commits
mailing list