[llvm] ee4661e - [AArch64][PAC] Emit auth call for Darwin tlv access thunk. (#97658)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 12 16:49:31 PDT 2024
Author: Ahmed Bougacha
Date: 2024-07-12T16:49:27-07:00
New Revision: ee4661e0f8eaff5da011e008187362f4ba947860
URL: https://github.com/llvm/llvm-project/commit/ee4661e0f8eaff5da011e008187362f4ba947860
DIFF: https://github.com/llvm/llvm-project/commit/ee4661e0f8eaff5da011e008187362f4ba947860.diff
LOG: [AArch64][PAC] Emit auth call for Darwin tlv access thunk. (#97658)
With ptrauth-calls, function pointers are supposed to be signed.
On Darwin that includes the TLS indirection accessor (`_tlv_get_addr`).
We simply sign it with the plain function-pointer schema (IA,0), which
lets us do a `blraaz` when calling it.
Note that this doesn't have any kind of diversity, even when function
pointer diversity is enabled in the frontend. On arm64e this accessor
is never signed that way, but the obvious alternative where this (or
another backend-generated) function pointer needs to be diversified
would need more than the "ptrauth-calls" attribute as it exists today.
Added:
llvm/test/CodeGen/AArch64/ptrauth-tls-darwin.ll
Modified:
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 1b67f2dbe1a3..7294da474c4b 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -9227,10 +9227,24 @@ AArch64TargetLowering::LowerDarwinGlobalTLSAddress(SDValue Op,
// normal AArch64 call node: x0 takes the address of the descriptor, and
// returns the address of the variable in this thread.
Chain = DAG.getCopyToReg(Chain, DL, AArch64::X0, DescAddr, SDValue());
- Chain =
- DAG.getNode(AArch64ISD::CALL, DL, DAG.getVTList(MVT::Other, MVT::Glue),
- Chain, FuncTLVGet, DAG.getRegister(AArch64::X0, MVT::i64),
- DAG.getRegisterMask(Mask), Chain.getValue(1));
+
+ unsigned Opcode = AArch64ISD::CALL;
+ SmallVector<SDValue, 8> Ops;
+ Ops.push_back(Chain);
+ Ops.push_back(FuncTLVGet);
+
+ // With ptrauth-calls, the tlv access thunk pointer is authenticated (IA, 0).
+ if (DAG.getMachineFunction().getFunction().hasFnAttribute("ptrauth-calls")) {
+ Opcode = AArch64ISD::AUTH_CALL;
+ Ops.push_back(DAG.getTargetConstant(AArch64PACKey::IA, DL, MVT::i32));
+ Ops.push_back(DAG.getTargetConstant(0, DL, MVT::i64)); // Integer Disc.
+ Ops.push_back(DAG.getRegister(AArch64::NoRegister, MVT::i64)); // Addr Disc.
+ }
+
+ Ops.push_back(DAG.getRegister(AArch64::X0, MVT::i64));
+ Ops.push_back(DAG.getRegisterMask(Mask));
+ Ops.push_back(Chain.getValue(1));
+ Chain = DAG.getNode(Opcode, DL, DAG.getVTList(MVT::Other, MVT::Glue), Ops);
return DAG.getCopyFromReg(Chain, DL, AArch64::X0, PtrVT, Chain.getValue(1));
}
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 517d0bd3047c..24d65624e09e 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -3653,7 +3653,15 @@ bool AArch64InstructionSelector::selectTLSGlobalValue(
// TLS calls preserve all registers except those that absolutely must be
// trashed: X0 (it takes an argument), LR (it's a call) and NZCV (let's not be
// silly).
- MIB.buildInstr(getBLRCallOpcode(MF), {}, {Load})
+ unsigned Opcode = getBLRCallOpcode(MF);
+
+ // With ptrauth-calls, the tlv access thunk pointer is authenticated (IA, 0).
+ if (MF.getFunction().hasFnAttribute("ptrauth-calls")) {
+ assert(Opcode == AArch64::BLR);
+ Opcode = AArch64::BLRAAZ;
+ }
+
+ MIB.buildInstr(Opcode, {}, {Load})
.addUse(AArch64::X0, RegState::Implicit)
.addDef(AArch64::X0, RegState::Implicit)
.addRegMask(TRI.getTLSCallPreservedMask());
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tls-darwin.ll b/llvm/test/CodeGen/AArch64/ptrauth-tls-darwin.ll
new file mode 100644
index 000000000000..e3cb0e818d16
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-tls-darwin.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=arm64e-apple-darwin %s -o - \
+; RUN: -aarch64-enable-collect-loh=0 | FileCheck %s
+
+; RUN: llc -mtriple=arm64e-apple-darwin %s -o - \
+; RUN: -global-isel -global-isel-abort=1 -verify-machineinstrs \
+; RUN: -aarch64-enable-collect-loh=0 | FileCheck %s
+
+ at var = thread_local global i8 0
+
+define i8 @get_var() #0 {
+; CHECK-LABEL: get_var:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; CHECK-NEXT: adrp x0, _var at TLVPPAGE
+; CHECK-NEXT: ldr x0, [x0, _var at TLVPPAGEOFF]
+; CHECK-NEXT: ldr x8, [x0]
+; CHECK-NEXT: blraaz x8
+; CHECK-NEXT: ldrb w0, [x0]
+; CHECK-NEXT: ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; CHECK-NEXT: ret
+
+ %val = load i8, ptr @var, align 1
+ ret i8 %val
+}
+
+attributes #0 = { nounwind "ptrauth-calls" }
More information about the llvm-commits
mailing list