Skip to content

[AArch64][PAC] Emit a fatal error when ptrauth target feature is missing #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: elf-pauth
Choose a base branch
from
11 changes: 11 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ExpandHardenedPseudos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ bool AArch64ExpandHardenedPseudos::expandPtrAuthPseudo(MachineInstr &MI) {
if (MI.getOpcode() == AArch64::LOADauthptrgot) {
LLVM_DEBUG(dbgs() << "Expanding: " << MI << "\n");

if (!STI.hasPAuth())
report_fatal_error("pac instructions require ptrauth target feature");

const TargetMachine &TM = MF.getTarget();
MachineModuleInfo &MMI = MF.getMMI();

Expand Down Expand Up @@ -223,6 +226,9 @@ bool AArch64ExpandHardenedPseudos::expandPtrAuthPseudo(MachineInstr &MI) {

LLVM_DEBUG(dbgs() << "Expanding: " << MI << "\n");

if (!STI.hasPAuth())
report_fatal_error("pac instructions require ptrauth target feature");

const bool IsGOTLoad = MI.getOpcode() == AArch64::LOADgotPAC;
MachineOperand GAOp = MI.getOperand(0);
auto Key = (AArch64PACKey::ID)MI.getOperand(1).getImm();
Expand Down Expand Up @@ -332,6 +338,11 @@ bool AArch64ExpandHardenedPseudos::expandAuthLoad(MachineInstr &MI) {

LLVM_DEBUG(dbgs() << "Expanding: " << MI << "\n");

// LDRA and LDRApre preudos are emitted in AArch64DAGToDAGISel::tryAuthLoad
// and AArch64InstructionSelector::selectAuthLoad with prior checks against
// ptrauth subtarget feature
assert(STI.hasPAuth());

bool IsPre = MI.getOpcode() == AArch64::LDRApre;

MachineOperand DstOp = MI.getOperand(0);
Expand Down
8 changes: 6 additions & 2 deletions llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1511,7 +1511,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// If we're saving LR, sign it first.
if (shouldAuthenticateLR(MF)) {
if (LLVM_UNLIKELY(!Subtarget.hasPAuth()))
report_fatal_error("arm64e LR authentication requires ptrauth");
report_fatal_error(
StringRef(Subtarget.isTargetMachO() ? "arm64e" : "aarch64") +
" LR authentication requires ptrauth");
for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
if (Info.getReg() != AArch64::LR)
continue;
Expand Down Expand Up @@ -2051,7 +2053,9 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
auto InsertAuthLROnExit = make_scope_exit([&]() {
if (shouldAuthenticateLR(MF)) {
if (LLVM_UNLIKELY(!Subtarget.hasPAuth()))
report_fatal_error("arm64e LR authentication requires ptrauth");
report_fatal_error(
StringRef(Subtarget.isTargetMachO() ? "arm64e" : "aarch64") +
" LR authentication requires ptrauth");
for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
if (Info.getReg() != AArch64::LR)
continue;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1723,6 +1723,9 @@ bool AArch64DAGToDAGISel::tryAuthLoad(SDNode *N) {
return false;
}

if (!Subtarget->hasPAuth())
report_fatal_error("pac instructions require ptrauth target feature");

// We have 2 main isel alternatives:
// - LDRAA/LDRAB, writeback or indexed. Zero disc, small offsets, D key.
// - LDRA/LDRApre. Pointer needs to be in X16.
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2856,6 +2856,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {

case AArch64::G_LDRA:
case AArch64::G_LDRApre:
// TODO: implement a test case for this error
if (!STI.hasPAuth())
report_fatal_error("pac instructions require ptrauth target feature");
return selectAuthLoad(I, MRI);

case TargetOpcode::G_ZEXTLOAD:
Expand Down
60 changes: 60 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-lowering-err-debug.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
; REQUIRES: asserts
; RUN: split-file %s %t && cd %t

;--- MOVaddrPAC.ll

; RUN: not --crash llc -debug-only=aarch64-expand-hardened-pseudos -mtriple aarch64-elf MOVaddrPAC.ll 2>&1 | \
; RUN: FileCheck MOVaddrPAC.ll

; CHECK: Expanding: MOVaddrPAC @foo
; CHECK-NEXT: {{^$}}
; CHECK-NEXT: LLVM ERROR: pac instructions require ptrauth target feature

@foo.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @foo, i32 0, i64 0, i64 0 }, section "llvm.ptrauth", align 8

define ptr @bar() #0 {
ret ptr @foo.ptrauth
}

define private void @foo() {
ret void
}

attributes #0 = { "ptrauth-calls" "target-cpu"="generic" }

;--- LOADgotPAC.ll

; RUN: not --crash llc -debug-only=aarch64-expand-hardened-pseudos -mtriple aarch64-elf LOADgotPAC.ll 2>&1 | \
; RUN: FileCheck LOADgotPAC.ll

; CHECK: Expanding: LOADgotPAC @foo
; CHECK-NEXT: {{^$}}
; CHECK-NEXT: LLVM ERROR: pac instructions require ptrauth target feature

@foo.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @foo, i32 0, i64 0, i64 0 }, section "llvm.ptrauth", align 8

define ptr @bar() #0 {
ret ptr @foo.ptrauth
}

declare void @foo()

attributes #0 = { "ptrauth-calls" "target-cpu"="generic" }

;--- LOADauthptrgot.ll

; RUN: not --crash llc -debug-only=aarch64-expand-hardened-pseudos -mtriple aarch64-elf LOADauthptrgot.ll 2>&1 | \
; RUN: FileCheck LOADauthptrgot.ll

; CHECK: Expanding: {{.*}}LOADauthptrgot @g_weak
; CHECK-NEXT: {{^$}}
; CHECK-NEXT: LLVM ERROR: pac instructions require ptrauth target feature

define ptr @foo() #0 {
ret ptr @g_weak.ptrauth
}

@g_weak = extern_weak global i32
@g_weak.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @g_weak, i32 0, i64 0, i64 0 }, section "llvm.ptrauth"

attributes #0 = { "ptrauth-calls" "target-cpu"="generic" }
102 changes: 102 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/ptrauth-lowering-err.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
; RUN: split-file %s %t && cd %t

;--- MOVaddrPAC.ll

; RUN: not --crash llc -mtriple aarch64-elf MOVaddrPAC.ll 2>&1 | \
; RUN: FileCheck MOVaddrPAC.ll

; CHECK: LLVM ERROR: pac instructions require ptrauth target feature

@foo.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @foo, i32 0, i64 0, i64 0 }, section "llvm.ptrauth", align 8

define ptr @bar() #0 {
ret ptr @foo.ptrauth
}

define private void @foo() {
ret void
}

attributes #0 = { "ptrauth-calls" "target-cpu"="generic" }

;--- LOADgotPAC.ll

; RUN: not --crash llc -mtriple aarch64-elf LOADgotPAC.ll 2>&1 | \
; RUN: FileCheck LOADgotPAC.ll

; CHECK: LLVM ERROR: pac instructions require ptrauth target feature

@foo.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @foo, i32 0, i64 0, i64 0 }, section "llvm.ptrauth", align 8

define ptr @bar() #0 {
ret ptr @foo.ptrauth
}

declare void @foo()

attributes #0 = { "ptrauth-calls" "target-cpu"="generic" }

;--- LOADauthptrgot.ll

; RUN: not --crash llc -mtriple aarch64-elf LOADauthptrgot.ll 2>&1 | \
; RUN: FileCheck LOADauthptrgot.ll

; CHECK: LLVM ERROR: pac instructions require ptrauth target feature

define ptr @foo() #0 {
ret ptr @g_weak.ptrauth
}

@g_weak = extern_weak global i32
@g_weak.ptrauth = private constant { ptr, i32, i64, i64 } { ptr @g_weak, i32 0, i64 0, i64 0 }, section "llvm.ptrauth"

attributes #0 = { "ptrauth-calls" "target-cpu"="generic" }

;--- ptrauth-returns.ll

; RUN: not --crash llc -mtriple aarch64-elf ptrauth-returns.ll 2>&1 | \
; RUN: FileCheck ptrauth-returns.ll

; CHECK: LLVM ERROR: aarch64 LR authentication requires ptrauth

define i32 @bar() #0 {
ret i32 42
}

define i32 @foo() {
%tmp = call i32 @bar()
ret i32 %tmp
}

attributes #0 = { "ptrauth-returns" "target-cpu"="generic" }

;--- auth-call.ll

; RUN: not --crash llc -mtriple aarch64-elf auth-call.ll 2>&1 | \
; RUN: FileCheck auth-call.ll

; CHECK: LLVM ERROR: Cannot select:{{.*}}AArch64ISD::AUTH_CALL

define void @bar(ptr %foo) #0 {
call void %foo() [ "ptrauth"(i32 0, i64 0) ]
ret void
}

attributes #0 = { "ptrauth-calls" "target-cpu"="generic" }

;--- tryAuthLoad.ll

; RUN: not --crash llc -mtriple aarch64-elf tryAuthLoad.ll 2>&1 | \
; RUN: FileCheck tryAuthLoad.ll

; CHECK: LLVM ERROR: pac instructions require ptrauth target feature

define i64 @test(ptr %ptr) {
%tmp0 = ptrtoint ptr %ptr to i64
%tmp1 = call i64 @llvm.ptrauth.auth(i64 %tmp0, i32 2, i64 0)
%tmp2 = inttoptr i64 %tmp1 to ptr
%tmp3 = load i64, ptr %tmp2
ret i64 %tmp3
}

declare i64 @llvm.ptrauth.auth(i64, i32, i64)