Skip to content

Commit f0d8af8

Browse files
committed
[AArch64][PAC] Sign block addresses used in indirectbr.
Enabled in clang using: -fptrauth-indirect-gotos and at the IR level using function attribute: "ptrauth-indirect-gotos" Signing uses IA and a per-function integer discriminator. The discriminator isn't ABI-visible, and is currently: ptrauth_string_discriminator("<function_name> blockaddress") A sufficiently sophisticated frontend could benefit from per-indirectbr discrimination, which would need additional machinery, such as allowing "ptrauth" bundles on indirectbr. For our purposes, the simple scheme above is sufficient.
1 parent 4a1fdeb commit f0d8af8

20 files changed

+309
-11
lines changed

clang/include/clang/Basic/Features.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ FEATURE(ptrauth_calls, LangOpts.PointerAuthCalls)
108108
FEATURE(ptrauth_returns, LangOpts.PointerAuthReturns)
109109
FEATURE(ptrauth_vtable_pointer_address_discrimination, LangOpts.PointerAuthVTPtrAddressDiscrimination)
110110
FEATURE(ptrauth_vtable_pointer_type_discrimination, LangOpts.PointerAuthVTPtrTypeDiscrimination)
111+
FEATURE(ptrauth_indirect_gotos, LangOpts.PointerAuthIndirectGotos)
111112
FEATURE(ptrauth_member_function_pointer_type_discrimination, LangOpts.PointerAuthCalls)
112113
FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
113114
EXTENSION(swiftcc,

clang/include/clang/Basic/LangOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library fea
165165
LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics")
166166
LANGOPT(PointerAuthCalls , 1, 0, "function pointer authentication")
167167
LANGOPT(PointerAuthReturns, 1, 0, "return pointer authentication")
168+
LANGOPT(PointerAuthIndirectGotos, 1, 0, "indirect gotos pointer authentication")
168169
LANGOPT(PointerAuthAuthTraps, 1, 0, "pointer authentication failure traps")
169170
LANGOPT(PointerAuthVTPtrAddressDiscrimination, 1, 0, "incorporate address discrimination in authenticated vtable pointers")
170171
LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, "incorporate type discrimination in authenticated vtable pointers")

clang/include/clang/Basic/PointerAuthOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ class PointerAuthSchema {
154154
};
155155

156156
struct PointerAuthOptions {
157+
/// Do indirect goto label addresses need to be authenticated?
158+
bool IndirectGotos = false;
159+
157160
/// The ABI for C function pointers.
158161
PointerAuthSchema FunctionPointers;
159162

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4228,6 +4228,8 @@ defm ptrauth_vtable_pointer_address_discrimination :
42284228
defm ptrauth_vtable_pointer_type_discrimination :
42294229
OptInCC1FFlag<"ptrauth-vtable-pointer-type-discrimination", "Enable type discrimination of vtable pointers">;
42304230
defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">;
4231+
defm ptrauth_indirect_gotos : OptInCC1FFlag<"ptrauth-indirect-gotos",
4232+
"Enable signing and authentication of indirect goto targets">;
42314233
}
42324234

42334235
def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
865865
const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts();
866866
if (CodeGenOpts.PointerAuth.FunctionPointers)
867867
Fn->addFnAttr("ptrauth-calls");
868+
if (CodeGenOpts.PointerAuth.IndirectGotos)
869+
Fn->addFnAttr("ptrauth-indirect-gotos");
868870

869871
// Apply xray attributes to the function (as a string, for now)
870872
bool AlwaysXRayAttr = false;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,6 +1789,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
17891789
options::OPT_fno_ptrauth_vtable_pointer_type_discrimination);
17901790
Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini,
17911791
options::OPT_fno_ptrauth_init_fini);
1792+
1793+
Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_indirect_gotos,
1794+
options::OPT_fno_ptrauth_indirect_gotos);
17921795
}
17931796

17941797
void Clang::AddLoongArchTargetArgs(const ArgList &Args,

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1480,13 +1480,14 @@ void CompilerInvocation::setDefaultPointerAuthOptions(
14801480
Opts.CXXVirtualFunctionPointers = Opts.CXXVirtualVariadicFunctionPointers =
14811481
PointerAuthSchema(Key::ASIA, true, Discrimination::Decl);
14821482
}
1483+
Opts.IndirectGotos = LangOpts.PointerAuthIndirectGotos;
14831484
}
14841485

14851486
static void parsePointerAuthOptions(PointerAuthOptions &Opts,
14861487
const LangOptions &LangOpts,
14871488
const llvm::Triple &Triple,
14881489
DiagnosticsEngine &Diags) {
1489-
if (!LangOpts.PointerAuthCalls)
1490+
if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthIndirectGotos)
14901491
return;
14911492

14921493
CompilerInvocation::setDefaultPointerAuthOptions(Opts, LangOpts, Triple);
@@ -3390,6 +3391,8 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts,
33903391
GenerateArg(Consumer, OPT_fptrauth_calls);
33913392
if (Opts.PointerAuthReturns)
33923393
GenerateArg(Consumer, OPT_fptrauth_returns);
3394+
if (Opts.PointerAuthIndirectGotos)
3395+
GenerateArg(Consumer, OPT_fptrauth_indirect_gotos);
33933396
if (Opts.PointerAuthAuthTraps)
33943397
GenerateArg(Consumer, OPT_fptrauth_auth_traps);
33953398
if (Opts.PointerAuthVTPtrAddressDiscrimination)
@@ -3405,6 +3408,7 @@ static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
34053408
Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
34063409
Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
34073410
Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
3411+
Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);
34083412
Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
34093413
Opts.PointerAuthVTPtrAddressDiscrimination =
34103414
Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);

clang/test/CodeGen/ptrauth-function-attributes.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@
44
// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS
55
// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS
66

7+
// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS
8+
// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS
9+
710
// ALL: define {{(dso_local )?}}void @test() #0
811
void test() {
912
}
1013

1114
// CALLS: attributes #0 = {{{.*}} "ptrauth-calls" {{.*}}}
1215

16+
// GOTOS: attributes #0 = {{{.*}} "ptrauth-indirect-gotos" {{.*}}}
17+
1318
// OFF-NOT: attributes {{.*}} "ptrauth-

llvm/docs/PointerAuth.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ At the IR level, it is represented using:
1818
* a [set of intrinsics](#intrinsics) (to sign/authenticate pointers)
1919
* a [signed pointer constant](#constant) (to sign globals)
2020
* a [call operand bundle](#operand-bundle) (to authenticate called pointers)
21+
* a [set of function attributes](#function-attributes) (to describe what
22+
pointers are signed and how, to control implicit codegen in the backend, as
23+
well as preserve invariants in the mid-level optimizer)
2124

2225
The current implementation leverages the
2326
[Armv8.3-A PAuth/Pointer Authentication Code](#armv8-3-a-pauth-pointer-authentication-code)
@@ -287,6 +290,27 @@ but with the added guarantee that `%fp_i`, `%fp_auth`, and `%fp_auth_p`
287290
are not stored to (and reloaded from) memory.
288291

289292

293+
### Function Attributes
294+
295+
Some function attributes are used to describe other pointer authentication
296+
operations that are not otherwise explicitly expressed in IR.
297+
298+
#### ``ptrauth-indirect-gotos``
299+
300+
``ptrauth-indirect-gotos`` specifies that indirect gotos in this function
301+
should authenticate their target. At the IR level, no other change is needed.
302+
When lowering [``blockaddress`` constants](https://llvm.org/docs/LangRef.html#blockaddress),
303+
and [``indirectbr`` instructions](https://llvm.org/docs/LangRef.html#i-indirectbr),
304+
this tells the backend to respectively sign and authenticate the pointers.
305+
306+
The specific scheme isn't ABI-visible. Currently, the AArch64 backend
307+
signs blockaddresses using the `ASIA` key, with an integer discriminator
308+
derived from the parent function's name, using the SipHash stable discriminator:
309+
```
310+
ptrauth_string_discriminator("<function_name> blockaddress")
311+
```
312+
313+
290314
## AArch64 Support
291315

292316
AArch64 is currently the only architecture with full support of the pointer

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,9 @@ class AsmPrinter : public MachineFunctionPass {
577577
report_fatal_error("ptrauth constant lowering not implemented");
578578
}
579579

580+
/// Lower the specified BlockAddress to an MCExpr.
581+
virtual const MCExpr *lowerBlockAddressConstant(const BlockAddress &BA);
582+
580583
/// Return true if the basic block has exactly one predecessor and the control
581584
/// transfer mechanism between the predecessor and this block is a
582585
/// fall-through.

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3139,7 +3139,7 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
31393139
return MCSymbolRefExpr::create(getSymbol(GV), Ctx);
31403140

31413141
if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV))
3142-
return MCSymbolRefExpr::create(GetBlockAddressSymbol(BA), Ctx);
3142+
return lowerBlockAddressConstant(*BA);
31433143

31443144
if (const auto *Equiv = dyn_cast<DSOLocalEquivalent>(CV))
31453145
return getObjFileLowering().lowerDSOLocalEquivalent(Equiv, TM);
@@ -3821,6 +3821,10 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const {
38213821
return const_cast<AsmPrinter *>(this)->getAddrLabelSymbol(BB);
38223822
}
38233823

3824+
const MCExpr *AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
3825+
return MCSymbolRefExpr::create(GetBlockAddressSymbol(&BA), OutContext);
3826+
}
3827+
38243828
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
38253829
MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
38263830
if (getSubtargetInfo().getTargetTriple().isWindowsMSVCEnvironment()) {

llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class AArch64AsmPrinter : public AsmPrinter {
9393

9494
const MCExpr *lowerConstantPtrAuth(const ConstantPtrAuth &CPA) override;
9595

96+
const MCExpr *lowerBlockAddressConstant(const BlockAddress &BA) override;
97+
9698
void emitStartOfAsmFile(Module &M) override;
9799
void emitJumpTableInfo() override;
98100
std::tuple<const MCSymbol *, uint64_t, const MCSymbol *,
@@ -128,7 +130,7 @@ class AArch64AsmPrinter : public AsmPrinter {
128130

129131
void emitSled(const MachineInstr &MI, SledKind Kind);
130132

131-
// Emit the sequence for BLRA (authenticate + branch).
133+
// Emit the sequence for BRA/BLRA (authenticate + branch/call).
132134
void emitPtrauthBranch(const MachineInstr *MI);
133135
// Emit the sequence to compute a discriminator into x17, or reuse AddrDisc.
134136
unsigned emitPtrauthDiscriminator(uint16_t Disc, unsigned AddrDisc,
@@ -1581,6 +1583,7 @@ unsigned AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
15811583

15821584
void AArch64AsmPrinter::emitPtrauthBranch(const MachineInstr *MI) {
15831585
unsigned InstsEmitted = 0;
1586+
bool IsCall = MI->getOpcode() == AArch64::BLRA;
15841587
unsigned BrTarget = MI->getOperand(0).getReg();
15851588

15861589
auto Key = (AArch64PACKey::ID)MI->getOperand(1).getImm();
@@ -1597,10 +1600,17 @@ void AArch64AsmPrinter::emitPtrauthBranch(const MachineInstr *MI) {
15971600
bool IsZeroDisc = DiscReg == AArch64::XZR;
15981601

15991602
unsigned Opc;
1600-
if (Key == AArch64PACKey::IA)
1601-
Opc = IsZeroDisc ? AArch64::BLRAAZ : AArch64::BLRAA;
1602-
else
1603-
Opc = IsZeroDisc ? AArch64::BLRABZ : AArch64::BLRAB;
1603+
if (IsCall) {
1604+
if (Key == AArch64PACKey::IA)
1605+
Opc = IsZeroDisc ? AArch64::BLRAAZ : AArch64::BLRAA;
1606+
else
1607+
Opc = IsZeroDisc ? AArch64::BLRABZ : AArch64::BLRAB;
1608+
} else {
1609+
if (Key == AArch64PACKey::IA)
1610+
Opc = IsZeroDisc ? AArch64::BRAAZ : AArch64::BRAA;
1611+
else
1612+
Opc = IsZeroDisc ? AArch64::BRABZ : AArch64::BRAB;
1613+
}
16041614

16051615
MCInst BRInst;
16061616
BRInst.setOpcode(Opc);
@@ -1866,6 +1876,20 @@ void AArch64AsmPrinter::LowerMOVaddrPAC(const MachineInstr &MI) {
18661876
assert(STI->getInstrInfo()->getInstSizeInBytes(MI) >= InstsEmitted * 4);
18671877
}
18681878

1879+
const MCExpr *
1880+
AArch64AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {
1881+
const MCExpr *BAE = AsmPrinter::lowerBlockAddressConstant(BA);
1882+
const Function &Fn = *BA.getFunction();
1883+
1884+
if (std::optional<uint16_t> BADisc =
1885+
STI->getPtrAuthBlockAddressDiscriminator(Fn))
1886+
return AArch64AuthMCExpr::create(BAE, *BADisc, AArch64PACKey::IA,
1887+
/* HasAddressDiversity= */ false,
1888+
OutContext);
1889+
1890+
return BAE;
1891+
}
1892+
18691893
// Simple pseudo-instructions have their lowering (with expansion to real
18701894
// instructions) auto-generated.
18711895
#include "AArch64GenMCPseudoLowering.inc"
@@ -2010,6 +2034,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
20102034
LowerMOVaddrPAC(*MI);
20112035
return;
20122036

2037+
case AArch64::BRA:
20132038
case AArch64::BLRA:
20142039
emitPtrauthBranch(MI);
20152040
return;

llvm/lib/Target/AArch64/AArch64FastISel.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2516,6 +2516,10 @@ bool AArch64FastISel::selectIndirectBr(const Instruction *I) {
25162516
if (AddrReg == 0)
25172517
return false;
25182518

2519+
// Authenticated indirectbr is not implemented yet.
2520+
if (FuncInfo.MF->getFunction().hasFnAttribute("ptrauth-indirect-gotos"))
2521+
return false;
2522+
25192523
// Emit the indirect branch.
25202524
const MCInstrDesc &II = TII.get(AArch64::BR);
25212525
AddrReg = constrainOperandRegClass(II, AddrReg, II.getNumDefs());

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
#include "llvm/Support/InstructionCost.h"
8686
#include "llvm/Support/KnownBits.h"
8787
#include "llvm/Support/MathExtras.h"
88+
#include "llvm/Support/SipHash.h"
8889
#include "llvm/Support/raw_ostream.h"
8990
#include "llvm/Target/TargetMachine.h"
9091
#include "llvm/Target/TargetOptions.h"
@@ -509,6 +510,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
509510
setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
510511
setOperationAction(ISD::BR_JT, MVT::Other, Custom);
511512
setOperationAction(ISD::JumpTable, MVT::i64, Custom);
513+
setOperationAction(ISD::BRIND, MVT::Other, Custom);
512514
setOperationAction(ISD::SETCCCARRY, MVT::i64, Custom);
513515

514516
setOperationAction(ISD::PtrAuthGlobalAddress, MVT::i64, Custom);
@@ -6694,6 +6696,8 @@ SDValue AArch64TargetLowering::LowerOperation(SDValue Op,
66946696
return LowerJumpTable(Op, DAG);
66956697
case ISD::BR_JT:
66966698
return LowerBR_JT(Op, DAG);
6699+
case ISD::BRIND:
6700+
return LowerBRIND(Op, DAG);
66976701
case ISD::ConstantPool:
66986702
return LowerConstantPool(Op, DAG);
66996703
case ISD::BlockAddress:
@@ -10685,6 +10689,27 @@ SDValue AArch64TargetLowering::LowerBR_JT(SDValue Op,
1068510689
return DAG.getNode(ISD::BRIND, DL, MVT::Other, JTInfo, SDValue(Dest, 0));
1068610690
}
1068710691

10692+
SDValue AArch64TargetLowering::LowerBRIND(SDValue Op,
10693+
SelectionDAG &DAG) const {
10694+
MachineFunction &MF = DAG.getMachineFunction();
10695+
std::optional<uint16_t> BADisc =
10696+
Subtarget->getPtrAuthBlockAddressDiscriminator(MF.getFunction());
10697+
if (!BADisc)
10698+
return SDValue();
10699+
10700+
SDLoc DL(Op);
10701+
SDValue Chain = Op.getOperand(0);
10702+
SDValue Dest = Op.getOperand(1);
10703+
10704+
SDValue Disc = DAG.getTargetConstant(*BADisc, DL, MVT::i64);
10705+
SDValue Key = DAG.getTargetConstant(AArch64PACKey::IA, DL, MVT::i32);
10706+
SDValue AddrDisc = DAG.getRegister(AArch64::XZR, MVT::i64);
10707+
10708+
SDNode *BrA = DAG.getMachineNode(AArch64::BRA, DL, MVT::Other,
10709+
{Dest, Key, Disc, AddrDisc, Chain});
10710+
return SDValue(BrA, 0);
10711+
}
10712+
1068810713
SDValue AArch64TargetLowering::LowerConstantPool(SDValue Op,
1068910714
SelectionDAG &DAG) const {
1069010715
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
@@ -10704,15 +10729,36 @@ SDValue AArch64TargetLowering::LowerConstantPool(SDValue Op,
1070410729

1070510730
SDValue AArch64TargetLowering::LowerBlockAddress(SDValue Op,
1070610731
SelectionDAG &DAG) const {
10707-
BlockAddressSDNode *BA = cast<BlockAddressSDNode>(Op);
10732+
BlockAddressSDNode *BAN = cast<BlockAddressSDNode>(Op);
10733+
const BlockAddress *BA = BAN->getBlockAddress();
10734+
10735+
if (std::optional<uint16_t> BADisc =
10736+
Subtarget->getPtrAuthBlockAddressDiscriminator(*BA->getFunction())) {
10737+
SDLoc DL(Op);
10738+
10739+
// This isn't cheap, but BRIND is rare.
10740+
SDValue TargetBA = DAG.getTargetBlockAddress(BA, BAN->getValueType(0));
10741+
10742+
SDValue Disc = DAG.getTargetConstant(*BADisc, DL, MVT::i64);
10743+
10744+
SDValue Key = DAG.getTargetConstant(AArch64PACKey::IA, DL, MVT::i32);
10745+
SDValue AddrDisc = DAG.getRegister(AArch64::XZR, MVT::i64);
10746+
10747+
SDNode *MOV =
10748+
DAG.getMachineNode(AArch64::MOVaddrPAC, DL, {MVT::Other, MVT::Glue},
10749+
{TargetBA, Key, AddrDisc, Disc});
10750+
return DAG.getCopyFromReg(SDValue(MOV, 0), DL, AArch64::X16, MVT::i64,
10751+
SDValue(MOV, 1));
10752+
}
10753+
1070810754
CodeModel::Model CM = getTargetMachine().getCodeModel();
1070910755
if (CM == CodeModel::Large && !Subtarget->isTargetMachO()) {
1071010756
if (!getTargetMachine().isPositionIndependent())
10711-
return getAddrLarge(BA, DAG);
10757+
return getAddrLarge(BAN, DAG);
1071210758
} else if (CM == CodeModel::Tiny) {
10713-
return getAddrTiny(BA, DAG);
10759+
return getAddrTiny(BAN, DAG);
1071410760
}
10715-
return getAddr(BA, DAG);
10761+
return getAddr(BAN, DAG);
1071610762
}
1071710763

1071810764
SDValue AArch64TargetLowering::LowerDarwin_VASTART(SDValue Op,

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,7 @@ class AArch64TargetLowering : public TargetLowering {
11431143
SelectionDAG &DAG) const;
11441144
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
11451145
SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
1146+
SDValue LowerBRIND(SDValue Op, SelectionDAG &DAG) const;
11461147
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
11471148
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
11481149
SDValue LowerAAPCS_VASTART(SDValue Op, SelectionDAG &DAG) const;

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,24 @@ let Predicates = [HasPAuth] in {
17551755
let Uses = [SP];
17561756
}
17571757

1758+
// BRA pseudo, generalized version of BRAA/BRAB/Z.
1759+
// This directly manipulates x16/x17, which are the only registers the OS
1760+
// guarantees are safe to use for sensitive operations.
1761+
def BRA : Pseudo<(outs), (ins GPR64noip:$Rn, i32imm:$Key, i64imm:$Disc,
1762+
GPR64noip:$AddrDisc), []>, Sched<[]> {
1763+
let isCodeGenOnly = 1;
1764+
let hasNoSchedulingInfo = 1;
1765+
let hasSideEffects = 1;
1766+
let mayStore = 0;
1767+
let mayLoad = 0;
1768+
let isBranch = 1;
1769+
let isTerminator = 1;
1770+
let isBarrier = 1;
1771+
let isIndirectBranch = 1;
1772+
let Size = 12; // 4 fixed + 8 variable, to compute discriminator.
1773+
let Defs = [X17];
1774+
}
1775+
17581776
let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
17591777
def RETAA : AuthReturn<0b010, 0, "retaa">;
17601778
def RETAB : AuthReturn<0b010, 1, "retab">;

0 commit comments

Comments
 (0)