Skip to content

Commit 8521bd2

Browse files
authored
[BOLT][AArch64] Handle PAuth call instructions in isIndirectCall (#133227)
Handle `BLRA*` opcodes in AArch64MCPlusBuilder::isIndirectCall, update getRegUsedAsCallDest accordingly.
1 parent ff5b649 commit 8521bd2

File tree

4 files changed

+30
-17
lines changed

4 files changed

+30
-17
lines changed

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -577,12 +577,12 @@ class MCPlusBuilder {
577577
return getNoRegister();
578578
}
579579

580-
/// Returns the register used as call destination, or no-register, if not
581-
/// an indirect call. Sets IsAuthenticatedInternally if the instruction
582-
/// accepts a signed pointer as its operand and authenticates it internally.
580+
/// Returns the register used as the destination of an indirect branch or call
581+
/// instruction. Sets IsAuthenticatedInternally if the instruction accepts
582+
/// a signed pointer as its operand and authenticates it internally.
583583
virtual MCPhysReg
584-
getRegUsedAsCallDest(const MCInst &Inst,
585-
bool &IsAuthenticatedInternally) const {
584+
getRegUsedAsIndirectBranchDest(const MCInst &Inst,
585+
bool &IsAuthenticatedInternally) const {
586586
llvm_unreachable("not implemented");
587587
return getNoRegister();
588588
}

bolt/lib/Passes/PAuthGadgetScanner.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,14 +498,16 @@ static std::shared_ptr<Report>
498498
shouldReportCallGadget(const BinaryContext &BC, const MCInstReference &Inst,
499499
const State &S) {
500500
static const GadgetKind CallKind("non-protected call found");
501-
if (!BC.MIB->isCall(Inst) && !BC.MIB->isBranch(Inst))
501+
if (!BC.MIB->isIndirectCall(Inst) && !BC.MIB->isIndirectBranch(Inst))
502502
return nullptr;
503503

504504
bool IsAuthenticated = false;
505-
MCPhysReg DestReg = BC.MIB->getRegUsedAsCallDest(Inst, IsAuthenticated);
506-
if (IsAuthenticated || DestReg == BC.MIB->getNoRegister())
505+
MCPhysReg DestReg =
506+
BC.MIB->getRegUsedAsIndirectBranchDest(Inst, IsAuthenticated);
507+
if (IsAuthenticated)
507508
return nullptr;
508509

510+
assert(DestReg != BC.MIB->getNoRegister());
509511
LLVM_DEBUG({
510512
traceInst(BC, "Found call inst", Inst);
511513
traceReg(BC, "Call destination reg", DestReg);

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "AArch64InstrInfo.h"
1314
#include "AArch64MCSymbolizer.h"
1415
#include "MCTargetDesc/AArch64AddressingModes.h"
1516
#include "MCTargetDesc/AArch64FixupKinds.h"
@@ -277,15 +278,14 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
277278
}
278279
}
279280

280-
MCPhysReg
281-
getRegUsedAsCallDest(const MCInst &Inst,
282-
bool &IsAuthenticatedInternally) const override {
283-
assert(isCall(Inst) || isBranch(Inst));
284-
IsAuthenticatedInternally = false;
281+
MCPhysReg getRegUsedAsIndirectBranchDest(
282+
const MCInst &Inst, bool &IsAuthenticatedInternally) const override {
283+
assert(isIndirectCall(Inst) || isIndirectBranch(Inst));
285284

286285
switch (Inst.getOpcode()) {
287286
case AArch64::BR:
288287
case AArch64::BLR:
288+
IsAuthenticatedInternally = false;
289289
return Inst.getOperand(0).getReg();
290290
case AArch64::BRAA:
291291
case AArch64::BRAB:
@@ -298,9 +298,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
298298
IsAuthenticatedInternally = true;
299299
return Inst.getOperand(0).getReg();
300300
default:
301-
if (isIndirectCall(Inst) || isIndirectBranch(Inst))
302-
llvm_unreachable("Unhandled indirect branch");
303-
return getNoRegister();
301+
llvm_unreachable("Unhandled indirect branch or call");
304302
}
305303
}
306304

@@ -699,7 +697,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
699697
}
700698

701699
bool isIndirectCall(const MCInst &Inst) const override {
702-
return Inst.getOpcode() == AArch64::BLR;
700+
return isIndirectCallOpcode(Inst.getOpcode());
703701
}
704702

705703
MCPhysReg getSpRegister(int Size) const {

llvm/lib/Target/AArch64/AArch64InstrInfo.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,19 @@ static inline bool isIndirectBranchOpcode(int Opc) {
726726
return false;
727727
}
728728

729+
static inline bool isIndirectCallOpcode(unsigned Opc) {
730+
switch (Opc) {
731+
case AArch64::BLR:
732+
case AArch64::BLRAA:
733+
case AArch64::BLRAB:
734+
case AArch64::BLRAAZ:
735+
case AArch64::BLRABZ:
736+
return true;
737+
default:
738+
return false;
739+
}
740+
}
741+
729742
static inline bool isPTrueOpcode(unsigned Opc) {
730743
switch (Opc) {
731744
case AArch64::PTRUE_B:

0 commit comments

Comments
 (0)