Skip to content

Commit 5bb3060

Browse files
Merge pull request #8115 from felipepiovezan/felipe/cherry-picks-debugnames3
[Cherry-Pick] Patches for DWARFLinker and DebugNames
2 parents 6751d2a + 7e8b96a commit 5bb3060

File tree

302 files changed

+16101
-2231
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

302 files changed

+16101
-2231
lines changed

bolt/include/bolt/Core/BinaryFunction.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,15 +2298,10 @@ class BinaryFunction {
22982298
/// removed.
22992299
uint64_t translateInputToOutputAddress(uint64_t Address) const;
23002300

2301-
/// Take address ranges corresponding to the input binary and translate
2302-
/// them to address ranges in the output binary.
2303-
DebugAddressRangesVector translateInputToOutputRanges(
2304-
const DWARFAddressRangesVector &InputRanges) const;
2305-
2306-
/// Similar to translateInputToOutputRanges() but operates on location lists
2307-
/// and moves associated data to output location lists.
2308-
DebugLocationsVector
2309-
translateInputToOutputLocationList(const DebugLocationsVector &InputLL) const;
2301+
/// Translate a contiguous range of addresses in the input binary into a set
2302+
/// of ranges in the output binary.
2303+
DebugAddressRangesVector
2304+
translateInputToOutputRange(DebugAddressRange InRange) const;
23102305

23112306
/// Return true if the function is an AArch64 linker inserted veneer
23122307
bool isAArch64Veneer() const;

bolt/include/bolt/Core/DIEBuilder.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,6 @@ class DIEBuilder {
359359
return Die->replaceValue(getState().DIEAlloc, Attribute, Form, NewValue);
360360
}
361361

362-
template <class T>
363362
bool deleteValue(DIEValueList *Die, dwarf::Attribute Attribute) {
364363
return Die->deleteValue(Attribute);
365364
}

bolt/include/bolt/Core/DebugData.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/CodeGen/DIE.h"
1919
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
2020
#include "llvm/MC/MCDwarf.h"
21+
#include "llvm/Support/FormatVariadic.h"
2122
#include "llvm/Support/SMLoc.h"
2223
#include "llvm/Support/raw_ostream.h"
2324
#include <cstdint>
@@ -95,6 +96,12 @@ static inline bool operator<(const DebugAddressRange &LHS,
9596
return std::tie(LHS.LowPC, LHS.HighPC) < std::tie(RHS.LowPC, RHS.HighPC);
9697
}
9798

99+
inline raw_ostream &operator<<(raw_ostream &OS,
100+
const DebugAddressRange &Range) {
101+
OS << formatv("[{0:x}, {1:x})", Range.LowPC, Range.HighPC);
102+
return OS;
103+
}
104+
98105
/// DebugAddressRangesVector - represents a set of absolute address ranges.
99106
using DebugAddressRangesVector = SmallVector<DebugAddressRange, 2>;
100107

@@ -106,6 +113,18 @@ struct DebugLocationEntry {
106113
SmallVector<uint8_t, 4> Expr;
107114
};
108115

116+
inline raw_ostream &operator<<(raw_ostream &OS,
117+
const DebugLocationEntry &Entry) {
118+
OS << formatv("[{0:x}, {1:x}) : [", Entry.LowPC, Entry.HighPC);
119+
const char *Sep = "";
120+
for (unsigned Byte : Entry.Expr) {
121+
OS << Sep << Byte;
122+
Sep = ", ";
123+
}
124+
OS << "]";
125+
return OS;
126+
}
127+
109128
using DebugLocationsVector = SmallVector<DebugLocationEntry, 4>;
110129

111130
/// References a row in a DWARFDebugLine::LineTable by the DWARF

bolt/include/bolt/Rewrite/DWARFRewriter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class DWARFRewriter {
125125
/// attribute.
126126
void updateDWARFObjectAddressRanges(
127127
DWARFUnit &Unit, DIEBuilder &DIEBldr, DIE &Die,
128-
uint64_t DebugRangesOffset, uint64_t LowPCToUse,
128+
uint64_t DebugRangesOffset,
129129
std::optional<uint64_t> RangesBase = std::nullopt);
130130

131131
std::unique_ptr<DebugBufferVector>
@@ -173,7 +173,7 @@ class DWARFRewriter {
173173
void convertToRangesPatchDebugInfo(
174174
DWARFUnit &Unit, DIEBuilder &DIEBldr, DIE &Die,
175175
uint64_t RangesSectionOffset, DIEValue &LowPCAttrInfo,
176-
DIEValue &HighPCAttrInfo, uint64_t LowPCToUse,
176+
DIEValue &HighPCAttrInfo,
177177
std::optional<uint64_t> RangesBase = std::nullopt);
178178

179179
/// Adds a \p Str to .debug_str section.

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 67 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -4195,92 +4195,88 @@ uint64_t BinaryFunction::translateInputToOutputAddress(uint64_t Address) const {
41954195
BB->getOutputAddressRange().second);
41964196
}
41974197

4198-
DebugAddressRangesVector BinaryFunction::translateInputToOutputRanges(
4199-
const DWARFAddressRangesVector &InputRanges) const {
4200-
DebugAddressRangesVector OutputRanges;
4198+
DebugAddressRangesVector
4199+
BinaryFunction::translateInputToOutputRange(DebugAddressRange InRange) const {
4200+
DebugAddressRangesVector OutRanges;
42014201

4202+
// The function was removed from the output. Return an empty range.
42024203
if (isFolded())
4203-
return OutputRanges;
4204+
return OutRanges;
42044205

4205-
// If the function hasn't changed return the same ranges.
4206+
// If the function hasn't changed return the same range.
42064207
if (!isEmitted()) {
4207-
OutputRanges.resize(InputRanges.size());
4208-
llvm::transform(InputRanges, OutputRanges.begin(),
4209-
[](const DWARFAddressRange &Range) {
4210-
return DebugAddressRange(Range.LowPC, Range.HighPC);
4211-
});
4212-
return OutputRanges;
4208+
OutRanges.emplace_back(InRange);
4209+
return OutRanges;
4210+
}
4211+
4212+
if (!containsAddress(InRange.LowPC))
4213+
return OutRanges;
4214+
4215+
// Special case of an empty range [X, X). Some tools expect X to be updated.
4216+
if (InRange.LowPC == InRange.HighPC) {
4217+
if (uint64_t NewPC = translateInputToOutputAddress(InRange.LowPC))
4218+
OutRanges.push_back(DebugAddressRange{NewPC, NewPC});
4219+
return OutRanges;
42134220
}
42144221

4215-
// Even though we will merge ranges in a post-processing pass, we attempt to
4216-
// merge them in a main processing loop as it improves the processing time.
4217-
uint64_t PrevEndAddress = 0;
4218-
for (const DWARFAddressRange &Range : InputRanges) {
4219-
if (!containsAddress(Range.LowPC)) {
4222+
uint64_t InputOffset = InRange.LowPC - getAddress();
4223+
const uint64_t InputEndOffset =
4224+
std::min(InRange.HighPC - getAddress(), getSize());
4225+
4226+
auto BBI = llvm::upper_bound(BasicBlockOffsets,
4227+
BasicBlockOffset(InputOffset, nullptr),
4228+
CompareBasicBlockOffsets());
4229+
assert(BBI != BasicBlockOffsets.begin());
4230+
4231+
// Iterate over blocks in the input order using BasicBlockOffsets.
4232+
for (--BBI; InputOffset < InputEndOffset && BBI != BasicBlockOffsets.end();
4233+
InputOffset = BBI->second->getEndOffset(), ++BBI) {
4234+
const BinaryBasicBlock &BB = *BBI->second;
4235+
if (InputOffset < BB.getOffset() || InputOffset >= BB.getEndOffset()) {
42204236
LLVM_DEBUG(
42214237
dbgs() << "BOLT-DEBUG: invalid debug address range detected for "
4222-
<< *this << " : [0x" << Twine::utohexstr(Range.LowPC) << ", 0x"
4223-
<< Twine::utohexstr(Range.HighPC) << "]\n");
4224-
PrevEndAddress = 0;
4225-
continue;
4238+
<< *this << " : [0x" << Twine::utohexstr(InRange.LowPC)
4239+
<< ", 0x" << Twine::utohexstr(InRange.HighPC) << "]\n");
4240+
break;
42264241
}
4227-
uint64_t InputOffset = Range.LowPC - getAddress();
4228-
const uint64_t InputEndOffset =
4229-
std::min(Range.HighPC - getAddress(), getSize());
4230-
4231-
auto BBI = llvm::upper_bound(BasicBlockOffsets,
4232-
BasicBlockOffset(InputOffset, nullptr),
4233-
CompareBasicBlockOffsets());
4234-
--BBI;
4235-
do {
4236-
const BinaryBasicBlock *BB = BBI->second;
4237-
if (InputOffset < BB->getOffset() || InputOffset >= BB->getEndOffset()) {
4238-
LLVM_DEBUG(
4239-
dbgs() << "BOLT-DEBUG: invalid debug address range detected for "
4240-
<< *this << " : [0x" << Twine::utohexstr(Range.LowPC)
4241-
<< ", 0x" << Twine::utohexstr(Range.HighPC) << "]\n");
4242-
PrevEndAddress = 0;
4243-
break;
4244-
}
42454242

4246-
// Skip the range if the block was deleted.
4247-
if (const uint64_t OutputStart = BB->getOutputAddressRange().first) {
4248-
const uint64_t StartAddress =
4249-
OutputStart + InputOffset - BB->getOffset();
4250-
uint64_t EndAddress = BB->getOutputAddressRange().second;
4251-
if (InputEndOffset < BB->getEndOffset())
4252-
EndAddress = StartAddress + InputEndOffset - InputOffset;
4253-
4254-
if (StartAddress == PrevEndAddress) {
4255-
OutputRanges.back().HighPC =
4256-
std::max(OutputRanges.back().HighPC, EndAddress);
4257-
} else {
4258-
OutputRanges.emplace_back(StartAddress,
4259-
std::max(StartAddress, EndAddress));
4260-
}
4261-
PrevEndAddress = OutputRanges.back().HighPC;
4262-
}
4243+
// Skip the block if it wasn't emitted.
4244+
if (!BB.getOutputAddressRange().first)
4245+
continue;
42634246

4264-
InputOffset = BB->getEndOffset();
4265-
++BBI;
4266-
} while (InputOffset < InputEndOffset);
4267-
}
4247+
// Find output address for an instruction with an offset greater or equal
4248+
// to /p Offset. The output address should fall within the same basic
4249+
// block boundaries.
4250+
auto translateBlockOffset = [&](const uint64_t Offset) {
4251+
const uint64_t OutAddress = BB.getOutputAddressRange().first + Offset;
4252+
return OutAddress;
4253+
};
42684254

4269-
// Post-processing pass to sort and merge ranges.
4270-
llvm::sort(OutputRanges);
4271-
DebugAddressRangesVector MergedRanges;
4272-
PrevEndAddress = 0;
4273-
for (const DebugAddressRange &Range : OutputRanges) {
4274-
if (Range.LowPC <= PrevEndAddress) {
4275-
MergedRanges.back().HighPC =
4276-
std::max(MergedRanges.back().HighPC, Range.HighPC);
4277-
} else {
4278-
MergedRanges.emplace_back(Range.LowPC, Range.HighPC);
4255+
uint64_t OutLowPC = BB.getOutputAddressRange().first;
4256+
if (InputOffset > BB.getOffset())
4257+
OutLowPC = translateBlockOffset(InputOffset - BB.getOffset());
4258+
4259+
uint64_t OutHighPC = BB.getOutputAddressRange().second;
4260+
if (InputEndOffset < BB.getEndOffset()) {
4261+
assert(InputEndOffset >= BB.getOffset());
4262+
OutHighPC = translateBlockOffset(InputEndOffset - BB.getOffset());
42794263
}
4280-
PrevEndAddress = MergedRanges.back().HighPC;
4264+
4265+
// Check if we can expand the last translated range.
4266+
if (!OutRanges.empty() && OutRanges.back().HighPC == OutLowPC)
4267+
OutRanges.back().HighPC = std::max(OutRanges.back().HighPC, OutHighPC);
4268+
else
4269+
OutRanges.emplace_back(OutLowPC, std::max(OutLowPC, OutHighPC));
42814270
}
42824271

4283-
return MergedRanges;
4272+
LLVM_DEBUG({
4273+
dbgs() << "BOLT-DEBUG: translated address range " << InRange << " -> ";
4274+
for (const DebugAddressRange &R : OutRanges)
4275+
dbgs() << R << ' ';
4276+
dbgs() << '\n';
4277+
});
4278+
4279+
return OutRanges;
42844280
}
42854281

42864282
MCInst *BinaryFunction::getInstructionAtOffset(uint64_t Offset) {
@@ -4311,92 +4307,6 @@ MCInst *BinaryFunction::getInstructionAtOffset(uint64_t Offset) {
43114307
}
43124308
}
43134309

4314-
DebugLocationsVector BinaryFunction::translateInputToOutputLocationList(
4315-
const DebugLocationsVector &InputLL) const {
4316-
DebugLocationsVector OutputLL;
4317-
4318-
if (isFolded())
4319-
return OutputLL;
4320-
4321-
// If the function hasn't changed - there's nothing to update.
4322-
if (!isEmitted())
4323-
return InputLL;
4324-
4325-
uint64_t PrevEndAddress = 0;
4326-
SmallVectorImpl<uint8_t> *PrevExpr = nullptr;
4327-
for (const DebugLocationEntry &Entry : InputLL) {
4328-
const uint64_t Start = Entry.LowPC;
4329-
const uint64_t End = Entry.HighPC;
4330-
if (!containsAddress(Start)) {
4331-
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: invalid debug address range detected "
4332-
"for "
4333-
<< *this << " : [0x" << Twine::utohexstr(Start)
4334-
<< ", 0x" << Twine::utohexstr(End) << "]\n");
4335-
continue;
4336-
}
4337-
uint64_t InputOffset = Start - getAddress();
4338-
const uint64_t InputEndOffset = std::min(End - getAddress(), getSize());
4339-
auto BBI = llvm::upper_bound(BasicBlockOffsets,
4340-
BasicBlockOffset(InputOffset, nullptr),
4341-
CompareBasicBlockOffsets());
4342-
--BBI;
4343-
do {
4344-
const BinaryBasicBlock *BB = BBI->second;
4345-
if (InputOffset < BB->getOffset() || InputOffset >= BB->getEndOffset()) {
4346-
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: invalid debug address range detected "
4347-
"for "
4348-
<< *this << " : [0x" << Twine::utohexstr(Start)
4349-
<< ", 0x" << Twine::utohexstr(End) << "]\n");
4350-
PrevEndAddress = 0;
4351-
break;
4352-
}
4353-
4354-
// Skip the range if the block was deleted.
4355-
if (const uint64_t OutputStart = BB->getOutputAddressRange().first) {
4356-
const uint64_t StartAddress =
4357-
OutputStart + InputOffset - BB->getOffset();
4358-
uint64_t EndAddress = BB->getOutputAddressRange().second;
4359-
if (InputEndOffset < BB->getEndOffset())
4360-
EndAddress = StartAddress + InputEndOffset - InputOffset;
4361-
4362-
if (StartAddress == PrevEndAddress && Entry.Expr == *PrevExpr) {
4363-
OutputLL.back().HighPC = std::max(OutputLL.back().HighPC, EndAddress);
4364-
} else {
4365-
OutputLL.emplace_back(DebugLocationEntry{
4366-
StartAddress, std::max(StartAddress, EndAddress), Entry.Expr});
4367-
}
4368-
PrevEndAddress = OutputLL.back().HighPC;
4369-
PrevExpr = &OutputLL.back().Expr;
4370-
}
4371-
4372-
++BBI;
4373-
InputOffset = BB->getEndOffset();
4374-
} while (InputOffset < InputEndOffset);
4375-
}
4376-
4377-
// Sort and merge adjacent entries with identical location.
4378-
llvm::stable_sort(
4379-
OutputLL, [](const DebugLocationEntry &A, const DebugLocationEntry &B) {
4380-
return A.LowPC < B.LowPC;
4381-
});
4382-
DebugLocationsVector MergedLL;
4383-
PrevEndAddress = 0;
4384-
PrevExpr = nullptr;
4385-
for (const DebugLocationEntry &Entry : OutputLL) {
4386-
if (Entry.LowPC <= PrevEndAddress && *PrevExpr == Entry.Expr) {
4387-
MergedLL.back().HighPC = std::max(Entry.HighPC, MergedLL.back().HighPC);
4388-
} else {
4389-
const uint64_t Begin = std::max(Entry.LowPC, PrevEndAddress);
4390-
const uint64_t End = std::max(Begin, Entry.HighPC);
4391-
MergedLL.emplace_back(DebugLocationEntry{Begin, End, Entry.Expr});
4392-
}
4393-
PrevEndAddress = MergedLL.back().HighPC;
4394-
PrevExpr = &MergedLL.back().Expr;
4395-
}
4396-
4397-
return MergedLL;
4398-
}
4399-
44004310
void BinaryFunction::printLoopInfo(raw_ostream &OS) const {
44014311
if (!opts::shouldPrint(*this))
44024312
return;

bolt/lib/Rewrite/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS
66
Object
77
Support
88
DWARFLinker
9+
DWARFLinkerClassic
910
AsmPrinter
1011
TargetParser
1112
)

0 commit comments

Comments
 (0)