Skip to content

Commit 06afe4e

Browse files
Merge branch 'main' into get-huge-money
2 parents ce97bad + ba7e273 commit 06afe4e

File tree

76 files changed

+873
-1644
lines changed

Some content is hidden

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

76 files changed

+873
-1644
lines changed

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,17 @@ class BinaryContext {
537537
BinaryFunction *createInjectedBinaryFunction(const std::string &Name,
538538
bool IsSimple = true);
539539

540+
/// Patch the original binary contents at address \p Address with a sequence
541+
/// of instructions from the \p Instructions list. The callee is responsible
542+
/// for checking that the sequence doesn't cross any function or section
543+
/// boundaries.
544+
///
545+
/// Optional \p Name can be assigned to the patch. The name will be emitted to
546+
/// the symbol table at \p Address.
547+
BinaryFunction *createInstructionPatch(uint64_t Address,
548+
InstructionListType &Instructions,
549+
const Twine &Name = "");
550+
540551
std::vector<BinaryFunction *> &getInjectedBinaryFunctions() {
541552
return InjectedBinaryFunctions;
542553
}

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -637,10 +637,6 @@ class MCPlusBuilder {
637637
return false;
638638
}
639639

640-
virtual void getADRReg(const MCInst &Inst, MCPhysReg &RegName) const {
641-
llvm_unreachable("not implemented");
642-
}
643-
644640
virtual bool isMoveMem2Reg(const MCInst &Inst) const { return false; }
645641

646642
virtual bool mayLoad(const MCInst &Inst) const {
@@ -1538,6 +1534,13 @@ class MCPlusBuilder {
15381534
llvm_unreachable("not implemented");
15391535
}
15401536

1537+
/// Undo the linker's ADRP+ADD to ADR relaxation. Take \p ADRInst and return
1538+
/// ADRP+ADD instruction sequence.
1539+
virtual InstructionListType undoAdrpAddRelaxation(const MCInst &ADRInst,
1540+
MCContext *Ctx) const {
1541+
llvm_unreachable("not implemented");
1542+
}
1543+
15411544
/// Return not 0 if the instruction CurInst, in combination with the recent
15421545
/// history of disassembled instructions supplied by [Begin, End), is a linker
15431546
/// generated veneer/stub that needs patching. This happens in AArch64 when

bolt/include/bolt/Passes/PatchEntries.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ class PatchEntries : public BinaryFunctionPass {
2626
struct Patch {
2727
const MCSymbol *Symbol;
2828
uint64_t Address;
29-
uint64_t FileOffset;
30-
BinarySection *Section;
3129
};
3230

3331
public:

bolt/lib/Core/BinaryContext.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2400,6 +2400,32 @@ BinaryContext::createInjectedBinaryFunction(const std::string &Name,
24002400
return BF;
24012401
}
24022402

2403+
BinaryFunction *BinaryContext::createInstructionPatch(
2404+
uint64_t Address, InstructionListType &Instructions, const Twine &Name) {
2405+
ErrorOr<BinarySection &> Section = getSectionForAddress(Address);
2406+
assert(Section && "cannot get section for patching");
2407+
assert(Section->hasSectionRef() && Section->isText() &&
2408+
"can only patch input file code sections");
2409+
2410+
const uint64_t FileOffset =
2411+
Section->getInputFileOffset() + Address - Section->getAddress();
2412+
2413+
std::string PatchName = Name.str();
2414+
if (PatchName.empty()) {
2415+
// Assign unique name to the patch.
2416+
static uint64_t N = 0;
2417+
PatchName = "__BP_" + std::to_string(N++);
2418+
}
2419+
2420+
BinaryFunction *PBF = createInjectedBinaryFunction(PatchName);
2421+
PBF->setOutputAddress(Address);
2422+
PBF->setFileOffset(FileOffset);
2423+
PBF->setOriginSection(&Section.get());
2424+
PBF->addBasicBlock()->addInstructions(Instructions);
2425+
2426+
return PBF;
2427+
}
2428+
24032429
std::pair<size_t, size_t>
24042430
BinaryContext::calculateEmittedSize(BinaryFunction &BF, bool FixBranches) {
24052431
// Adjust branch instruction to match the current layout.

bolt/lib/Passes/ADRRelaxationPass.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,10 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
7171
continue;
7272
}
7373

74-
MCPhysReg Reg;
75-
BC.MIB->getADRReg(Inst, Reg);
76-
int64_t Addend = BC.MIB->getTargetAddend(Inst);
77-
InstructionListType Addr;
78-
74+
InstructionListType AdrpAdd;
7975
{
8076
auto L = BC.scopeLock();
81-
Addr = BC.MIB->materializeAddress(Symbol, BC.Ctx.get(), Reg, Addend);
77+
AdrpAdd = BC.MIB->undoAdrpAddRelaxation(Inst, BC.Ctx.get());
8278
}
8379

8480
if (It != BB.begin() && BC.MIB->isNoop(*std::prev(It))) {
@@ -99,7 +95,7 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
9995
PassFailed = true;
10096
return;
10197
}
102-
It = BB.replaceInstruction(It, Addr);
98+
It = BB.replaceInstruction(It, AdrpAdd);
10399
}
104100
}
105101
}

bolt/lib/Passes/PatchEntries.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,8 @@ Error PatchEntries::runOnFunctions(BinaryContext &BC) {
8383
return false;
8484
}
8585

86-
PendingPatches.emplace_back(Patch{Symbol, Function.getAddress() + Offset,
87-
Function.getFileOffset() + Offset,
88-
Function.getOriginSection()});
86+
PendingPatches.emplace_back(
87+
Patch{Symbol, Function.getAddress() + Offset});
8988
NextValidByte = Offset + PatchSize;
9089
if (NextValidByte > Function.getMaxSize()) {
9190
if (opts::Verbosity >= 1)
@@ -118,16 +117,12 @@ Error PatchEntries::runOnFunctions(BinaryContext &BC) {
118117
}
119118

120119
for (Patch &Patch : PendingPatches) {
121-
BinaryFunction *PatchFunction = BC.createInjectedBinaryFunction(
120+
// Add instruction patch to the binary.
121+
InstructionListType Instructions;
122+
BC.MIB->createLongTailCall(Instructions, Patch.Symbol, BC.Ctx.get());
123+
BinaryFunction *PatchFunction = BC.createInstructionPatch(
124+
Patch.Address, Instructions,
122125
NameResolver::append(Patch.Symbol->getName(), ".org.0"));
123-
// Force the function to be emitted at the given address.
124-
PatchFunction->setOutputAddress(Patch.Address);
125-
PatchFunction->setFileOffset(Patch.FileOffset);
126-
PatchFunction->setOriginSection(Patch.Section);
127-
128-
InstructionListType Seq;
129-
BC.MIB->createLongTailCall(Seq, Patch.Symbol, BC.Ctx.get());
130-
PatchFunction->addBasicBlock()->addInstructions(Seq);
131126

132127
// Verify the size requirements.
133128
uint64_t HotSize, ColdSize;

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,23 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
278278
return Inst.getOpcode() == AArch64::ADDXri;
279279
}
280280

281-
void getADRReg(const MCInst &Inst, MCPhysReg &RegName) const override {
281+
MCPhysReg getADRReg(const MCInst &Inst) const {
282282
assert((isADR(Inst) || isADRP(Inst)) && "Not an ADR instruction");
283283
assert(MCPlus::getNumPrimeOperands(Inst) != 0 &&
284284
"No operands for ADR instruction");
285285
assert(Inst.getOperand(0).isReg() &&
286286
"Unexpected operand in ADR instruction");
287-
RegName = Inst.getOperand(0).getReg();
287+
return Inst.getOperand(0).getReg();
288+
}
289+
290+
InstructionListType undoAdrpAddRelaxation(const MCInst &ADRInst,
291+
MCContext *Ctx) const override {
292+
assert(isADR(ADRInst) && "ADR instruction expected");
293+
294+
const MCPhysReg Reg = getADRReg(ADRInst);
295+
const MCSymbol *Target = getTargetSymbol(ADRInst);
296+
const uint64_t Addend = getTargetAddend(ADRInst);
297+
return materializeAddress(Target, Ctx, Reg, Addend);
288298
}
289299

290300
bool isTB(const MCInst &Inst) const {

bolt/test/X86/Inputs/define_bar.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Mocks a vtable object weak def in the C++ stdlib.
2-
.data.rel.ro
2+
.section .data.rel.ro,"aw"
33
.weak bar
44
.type bar, %object
55
bar:

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ Changes in existing checks
122122
- Improved :doc:`misc-const-correctness
123123
<clang-tidy/checks/misc/const-correctness>` check by adding the option
124124
`AllowedTypes`, that excludes specified types from const-correctness
125-
checking.
125+
checking and fixing false positives when modifying variant by ``operator[]``
126+
with template in parameters.
126127

127128
- Improved :doc:`misc-redundant-expression
128129
<clang-tidy/checks/misc/redundant-expression>` check by providing additional

clang-tools-extra/test/clang-tidy/checkers/misc/const-correctness-values.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,3 +998,11 @@ void member_pointer_const(Value &x, PointerToConstMemberFunction m) {
998998
// CHECK-MESSAGES:[[@LINE-1]]:3: warning: variable 'member_pointer_tmp' of type 'Value &' can be declared 'const'
999999
(member_pointer_tmp.*m)();
10001000
}
1001+
1002+
namespace gh127776_false_positive {
1003+
template <class T> struct vector { T &operator[](int t); };
1004+
template <typename T> void f() {
1005+
vector<int> x;
1006+
x[T{}] = 3;
1007+
}
1008+
} // namespace gh127776_false_positive

0 commit comments

Comments
 (0)