-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[PAC][CodeGen][ELF][AArch64] Support signed GOT with tiny code model #114525
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
Conversation
Support the following relocations and assembly operators: - `R_AARCH64_AUTH_GOT_ADR_PREL_LO21` (`:got_auth:` for `adr`) - `R_AARCH64_AUTH_GOT_LD_PREL19` (`:got_auth:` for `ldr`) `LOADgotAUTH` pseudo-instruction is expanded to actual instruction sequence like the following. ``` adr x16, :got_auth:sym ldr x0, [x16] autia x0, x16 ``` Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall back to SelectionDAG. Tests starting with 'ptrauth-' have corresponding variants w/o this prefix.
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-aarch64 Author: Daniil Kovalev (kovdan01) ChangesSupport the following relocations and assembly operators:
Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall back to SelectionDAG. Tests starting with 'ptrauth-' have corresponding variants w/o this prefix. Patch is 21.16 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/114525.diff 8 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index e79457f925db66..2a3161a5c6b704 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -2277,28 +2277,39 @@ void AArch64AsmPrinter::LowerLOADgotAUTH(const MachineInstr &MI) {
const MachineOperand &GAMO = MI.getOperand(1);
assert(GAMO.getOffset() == 0);
- MachineOperand GAHiOp(GAMO);
- MachineOperand GALoOp(GAMO);
- GAHiOp.addTargetFlag(AArch64II::MO_PAGE);
- GALoOp.addTargetFlag(AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
+ if (MI.getMF()->getTarget().getCodeModel() == CodeModel::Tiny) {
+ MCOperand GAMC;
+ MCInstLowering.lowerOperand(GAMO, GAMC);
+ EmitToStreamer(
+ MCInstBuilder(AArch64::ADR).addReg(AArch64::X17).addOperand(GAMC));
+ EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
+ .addReg(AuthResultReg)
+ .addReg(AArch64::X17)
+ .addImm(0));
+ } else {
+ MachineOperand GAHiOp(GAMO);
+ MachineOperand GALoOp(GAMO);
+ GAHiOp.addTargetFlag(AArch64II::MO_PAGE);
+ GALoOp.addTargetFlag(AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
- MCOperand GAMCHi, GAMCLo;
- MCInstLowering.lowerOperand(GAHiOp, GAMCHi);
- MCInstLowering.lowerOperand(GALoOp, GAMCLo);
+ MCOperand GAMCHi, GAMCLo;
+ MCInstLowering.lowerOperand(GAHiOp, GAMCHi);
+ MCInstLowering.lowerOperand(GALoOp, GAMCLo);
- EmitToStreamer(
- MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).addOperand(GAMCHi));
+ EmitToStreamer(
+ MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).addOperand(GAMCHi));
- EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
- .addReg(AArch64::X17)
- .addReg(AArch64::X17)
- .addOperand(GAMCLo)
- .addImm(0));
+ EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
+ .addReg(AArch64::X17)
+ .addReg(AArch64::X17)
+ .addOperand(GAMCLo)
+ .addImm(0));
- EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
- .addReg(AuthResultReg)
- .addReg(AArch64::X17)
- .addImm(0));
+ EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
+ .addReg(AuthResultReg)
+ .addReg(AArch64::X17)
+ .addImm(0));
+ }
assert(GAMO.isGlobal());
MCSymbol *UndefWeakSym;
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 712f6de52941c9..4a792f7bddb220 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -3354,7 +3354,13 @@ ParseStatus AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
// No modifier was specified at all; this is the syntax for an ELF basic
// ADR relocation (unfortunately).
Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, getContext());
- } else {
+ } else if (ELFRefKind != AArch64MCExpr::VK_GOT_AUTH_PAGE) {
+ // For tiny code model, we use :got_auth: operator to fill 21-bit imm of
+ // adr. It's not actually GOT entry page address but the GOT address
+ // itself - we just share the same variant kind with :got_auth: operator
+ // applied for adrp.
+ // TODO: can we somehow get current TargetMachine object to call
+ // getCodeModel() on it to ensure we are using tiny code model?
return Error(S, "unexpected adr label");
}
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index b5f5a58d96288e..04f90e21bb3b1f 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -147,6 +147,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
}
return ELF::R_AARCH64_PREL64;
case AArch64::fixup_aarch64_pcrel_adr_imm21:
+ if (SymLoc == AArch64MCExpr::VK_GOT_AUTH) {
+ if (IsILP32) {
+ Ctx.reportError(Fixup.getLoc(),
+ "ILP32 ADR AUTH relocation not supported "
+ "(LP64 eqv: AUTH_GOT_ADR_PREL_LO21)");
+ return ELF::R_AARCH64_NONE;
+ }
+ return ELF::R_AARCH64_AUTH_GOT_ADR_PREL_LO21;
+ }
if (SymLoc != AArch64MCExpr::VK_ABS)
Ctx.reportError(Fixup.getLoc(),
"invalid symbol kind for ADR relocation");
@@ -190,6 +199,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
return R_CLS(TLSIE_LD_GOTTPREL_PREL19);
if (SymLoc == AArch64MCExpr::VK_GOT)
return R_CLS(GOT_LD_PREL19);
+ if (SymLoc == AArch64MCExpr::VK_GOT_AUTH) {
+ if (IsILP32) {
+ Ctx.reportError(Fixup.getLoc(),
+ "ILP32 LDR AUTH relocation not supported "
+ "(LP64 eqv: AUTH_GOT_LD_PREL19)");
+ return ELF::R_AARCH64_NONE;
+ }
+ return ELF::R_AARCH64_AUTH_GOT_LD_PREL19;
+ }
return R_CLS(LD_PREL_LO19);
case AArch64::fixup_aarch64_pcrel_branch14:
return R_CLS(TSTBR14);
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll
index 5d0a3f556c4c2e..141af917fa3e2c 100644
--- a/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll
+++ b/llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll
@@ -13,6 +13,11 @@
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=1 -global-isel-abort=1 -relocation-model=pic \
; RUN: -mattr=+pauth -o - %s | FileCheck --check-prefixes=CHECK,TRAP %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -code-model=tiny -mattr=+pauth -mattr=+fpac -o - %s | \
+; RUN: FileCheck --check-prefixes=CHECK-TINY,NOTRAP-TINY %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -code-model=tiny -mattr=+pauth -o - %s | \
+; RUN: FileCheck --check-prefixes=CHECK-TINY,TRAP-TINY %s
+
;; Note: for FastISel, we fall back to SelectionDAG
declare extern_weak dso_local i32 @var()
@@ -41,6 +46,24 @@ define ptr @foo() {
; TRAP-NEXT: .Lauth_success_0:
; TRAP-NEXT: mov x0, x16
; CHECK-NEXT: ret
+
+; CHECK-TINY-LABEL: foo:
+; CHECK-TINY: adr x17, :got_auth:var
+; NOTRAP-TINY-NEXT: ldr x0, [x17]
+; NOTRAP-TINY-NEXT: cbz x0, .Lundef_weak0
+; NOTRAP-TINY-NEXT: autia x0, x17
+; TRAP-TINY-NEXT: ldr x16, [x17]
+; TRAP-TINY-NEXT: cbz x16, .Lundef_weak0
+; TRAP-TINY-NEXT: autia x16, x17
+; CHECK-TINY-NEXT: .Lundef_weak0:
+; TRAP-TINY-NEXT: mov x17, x16
+; TRAP-TINY-NEXT: xpaci x17
+; TRAP-TINY-NEXT: cmp x16, x17
+; TRAP-TINY-NEXT: b.eq .Lauth_success_0
+; TRAP-TINY-NEXT: brk #0xc470
+; TRAP-TINY-NEXT: .Lauth_success_0:
+; TRAP-TINY-NEXT: mov x0, x16
+; CHECK-TINY-NEXT: ret
}
@arr_var = extern_weak global [10 x i32]
@@ -68,6 +91,25 @@ define ptr @bar() {
; TRAP-NEXT: mov x8, x16
; CHECK-NEXT: add x0, x8, #20
; CHECK-NEXT: ret
+
+; CHECK-TINY-LABEL: bar:
+; CHECK-TINY: adr x17, :got_auth:arr_var
+; NOTRAP-TINY-NEXT: ldr x8, [x17]
+; NOTRAP-TINY-NEXT: cbz x8, .Lundef_weak1
+; NOTRAP-TINY-NEXT: autda x8, x17
+; TRAP-TINY-NEXT: ldr x16, [x17]
+; TRAP-TINY-NEXT: cbz x16, .Lundef_weak1
+; TRAP-TINY-NEXT: autda x16, x17
+; CHECK-TINY-NEXT: .Lundef_weak1:
+; TRAP-TINY-NEXT: mov x17, x16
+; TRAP-TINY-NEXT: xpacd x17
+; TRAP-TINY-NEXT: cmp x16, x17
+; TRAP-TINY-NEXT: b.eq .Lauth_success_1
+; TRAP-TINY-NEXT: brk #0xc472
+; TRAP-TINY-NEXT: .Lauth_success_1:
+; TRAP-TINY-NEXT: mov x8, x16
+; CHECK-TINY-NEXT: add x0, x8, #20
+; CHECK-TINY-NEXT: ret
}
!llvm.module.flags = !{!0}
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll
new file mode 100644
index 00000000000000..93b21c93418a64
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll
@@ -0,0 +1,182 @@
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \
+; RUN: -relocation-model=pic < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \
+; RUN: -relocation-model=pic < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \
+; RUN: -relocation-model=pic -fast-isel < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \
+; RUN: -relocation-model=pic -fast-isel < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \
+; RUN: -relocation-model=pic -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -code-model=tiny \
+; RUN: -relocation-model=pic -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; Note: fast-isel tests here will fall back to isel
+
+@src = external local_unnamed_addr global [65536 x i8], align 1
+@dst = external global [65536 x i8], align 1
+@ptr = external local_unnamed_addr global ptr, align 8
+
+define dso_preemptable void @foo1() {
+; CHECK-LABEL: foo1:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:src
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_0
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_0:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: ldrb w8, [x8]
+; CHECK-NEXT: adr x17, :got_auth:dst
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_1
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_1:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: strb w8, [x9]
+; CHECK-NEXT: ret
+
+entry:
+ %0 = load i8, ptr @src, align 1
+ store i8 %0, ptr @dst, align 1
+ ret void
+}
+
+define dso_preemptable void @foo2() {
+; CHECK-LABEL: foo2:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:ptr
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_2
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_2:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: adr x17, :got_auth:dst
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_3
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_3:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: str x9, [x8]
+; CHECK-NEXT: ret
+
+entry:
+ store ptr @dst, ptr @ptr, align 8
+ ret void
+}
+
+define dso_preemptable void @foo3() {
+; CHECK-LABEL: foo3:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:src
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_4
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_4:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: ldrb w8, [x8]
+; CHECK-NEXT: adr x17, :got_auth:ptr
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_5
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_5:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: ldr x9, [x9]
+; CHECK-NEXT: strb w8, [x9]
+; CHECK-NEXT: ret
+
+entry:
+ %0 = load i8, ptr @src, align 1
+ %1 = load ptr, ptr @ptr, align 8
+ store i8 %0, ptr %1, align 1
+ ret void
+}
+
+@lsrc = internal global i8 0, align 4
+@ldst = internal global i8 0, align 4
+@lptr = internal global ptr null, align 8
+
+declare void @func(...)
+
+define dso_preemptable ptr @externfuncaddr() {
+; CHECK-LABEL: externfuncaddr:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:func
+; NOTRAP-NEXT: ldr x0, [x17]
+; NOTRAP-NEXT: autia x0, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autia x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpaci x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_6
+; TRAP-NEXT: brk #0xc470
+; TRAP-NEXT: .Lauth_success_6:
+; TRAP-NEXT: mov x0, x16
+; CHECK-NEXT: ret
+
+entry:
+ ret ptr @func
+}
+
+define dso_preemptable ptr @localfuncaddr() {
+; CHECK-LABEL: localfuncaddr:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:externfuncaddr
+; NOTRAP-NEXT: ldr x0, [x17]
+; NOTRAP-NEXT: autia x0, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autia x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpaci x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_7
+; TRAP-NEXT: brk #0xc470
+; TRAP-NEXT: .Lauth_success_7:
+; TRAP-NEXT: mov x0, x16
+; CHECK-NEXT: ret
+
+entry:
+ ret ptr @externfuncaddr
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
diff --git a/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll
new file mode 100644
index 00000000000000..2d098b70accccc
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll
@@ -0,0 +1,157 @@
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \
+; RUN: -code-model=tiny < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \
+; RUN: -code-model=tiny < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \
+; RUN: -code-model=tiny -fast-isel < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \
+; RUN: -code-model=tiny -fast-isel < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth -mattr=+fpac \
+; RUN: -code-model=tiny -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,NOTRAP %s
+; RUN: llc -verify-machineinstrs -o - -mtriple=aarch64-none-linux-gnu -mattr=+pauth \
+; RUN: -code-model=tiny -global-isel -global-isel-abort=1 < %s | FileCheck --check-prefixes=CHECK,TRAP %s
+
+; Note fast-isel tests here will fall back to isel
+
+@src = external local_unnamed_addr global [65536 x i8], align 1
+@dst = external global [65536 x i8], align 1
+@ptr = external local_unnamed_addr global ptr, align 8
+
+define dso_local void @foo1() {
+; CHECK-LABEL: foo1:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:src
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_0
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_0:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: ldrb w8, [x8]
+; CHECK-NEXT: adr x17, :got_auth:dst
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_1
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_1:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: strb w8, [x9]
+; CHECK-NEXT: ret
+
+entry:
+ %0 = load i8, ptr @src, align 1
+ store i8 %0, ptr @dst, align 1
+ ret void
+}
+
+define dso_local void @foo2() {
+; CHECK-LABEL: foo2:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:ptr
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_2
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_2:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: adr x17, :got_auth:dst
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_3
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_3:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: str x9, [x8]
+; CHECK-NEXT: ret
+
+entry:
+ store ptr @dst, ptr @ptr, align 8
+ ret void
+}
+
+define dso_local void @foo3() {
+; CHECK-LABEL: foo3:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:src
+; NOTRAP-NEXT: ldr x8, [x17]
+; NOTRAP-NEXT: autda x8, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_4
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_4:
+; TRAP-NEXT: mov x8, x16
+; CHECK-NEXT: ldrb w8, [x8]
+; CHECK-NEXT: adr x17, :got_auth:ptr
+; NOTRAP-NEXT: ldr x9, [x17]
+; NOTRAP-NEXT: autda x9, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autda x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpacd x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_5
+; TRAP-NEXT: brk #0xc472
+; TRAP-NEXT: .Lauth_success_5:
+; TRAP-NEXT: mov x9, x16
+; CHECK-NEXT: ldr x9, [x9]
+; CHECK-NEXT: strb w8, [x9]
+; CHECK-NEXT: ret
+
+entry:
+ %0 = load i8, ptr @src, align 1
+ %1 = load ptr, ptr @ptr, align 8
+ store i8 %0, ptr %1, align 1
+ ret void
+}
+
+declare void @func(...)
+
+define dso_local ptr @externfuncaddr() {
+; CHECK-LABEL: externfuncaddr:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: adr x17, :got_auth:func
+; NOTRAP-NEXT: ldr x0, [x17]
+; NOTRAP-NEXT: autia x0, x17
+; TRAP-NEXT: ldr x16, [x17]
+; TRAP-NEXT: autia x16, x17
+; TRAP-NEXT: mov x17, x16
+; TRAP-NEXT: xpaci x17
+; TRAP-NEXT: cmp x16, x17
+; TRAP-NEXT: b.eq .Lauth_success_6
+; TRAP-NEXT: brk #0xc470
+; TRAP-NEXT: .Lauth_success_6:
+; TRAP-NEXT: mov x0, x16
+; CHECK-NEXT: ret
+
+entry:
+ ret ptr @func
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 8, !"ptrauth-elf-got", i32 1}
diff --git a/llvm/test/MC/AArch64/arm64-elf-relocs.s b/llvm/test/MC/AArch64/arm64-elf-relocs.s
index f679bb4c82827b..5c04e899a7b22e 100644
--- a/llvm/test/MC/AArch64/arm64-elf-relocs.s
+++ b/llvm/test/MC/AArch64/arm64-elf-relocs.s
@@ -331,6 +331,19 @@ trickQuestion:
// CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym
// CHECK-OBJ-LP64: R_AARCH64_GOT_LD_PREL19 sym
+ adr x24, #:got_auth:sym
+ adr x24, :got_auth:sym
+ ldr x24, #:got_auth:sym
+ ldr x24, :got_auth:sym
+// CHECK: adr x24, :got_auth:sy...
[truncated]
|
Re-opened #113812 after accidentally cluttering that with wrong merge commit and auto-requesting review from a lot of reviewers as code owners. |
Would be glad to see everyone's feedback on the changes. |
1 similar comment
Would be glad to see everyone's feedback on the changes. |
@@ -0,0 +1,182 @@ | |||
; RUN: llc -verify-machineinstrs -mtriple=aarch64 -mattr=+pauth -mattr=+fpac -code-model=tiny \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps combine pic and static .ll tests and just use update_llc_test_checks.py
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps combine pic and static .ll tests
While we can do this, I'm not sure if it would give that much value: RUN lines are different (-relocation-model=pic
is used in ptrauth-tiny-model-pic.ll) so we'll have x2 RUN lines when combined to one file which might be overwhelming IMHO, and also we'll have to change check prefixes so they don't overlap
and just use update_llc_test_checks.py
I was unable to make update_llc_test_checks.py produce nice output which shows that there are common CHECK lines and different TRAP and NOTRAP lines for -mattr=+fpac
missing and present correspondingly. We can have duplicate check lines for both cases, but it consumes more space and doesn't explicitly show that the only difference between fpac and no-fpac case is the absence/presence of trap sequence.
Please let me know if I miss smth and update_llc_test_checks.py is capable of generating such outputs (and I'm just missing smth)
@@ -87,3 +87,9 @@ ldr x24, [x23, #:got_lo12:sym] | |||
|
|||
ldr x24, [x23, :gottprel_lo12:sym] | |||
// ERROR: [[#@LINE-1]]:1: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: TLSIE_LD64_GOTTPREL_LO12_NC) | |||
|
|||
ldr x24, :got_auth:sym | |||
// ERROR: error: ILP32 LDR AUTH relocation not supported (LP64 eqv: AUTH_GOT_LD_PREL19) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test [[#@LINE-1]]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, thanks, see f8a3c3a
@MaskRay Please see replies to your comments above |
Would be glad to see everyone's feedback on the changes. |
Support the following relocations and assembly operators:
R_AARCH64_AUTH_GOT_ADR_PREL_LO21
(:got_auth:
foradr
)R_AARCH64_AUTH_GOT_LD_PREL19
(:got_auth:
forldr
)LOADgotAUTH
pseudo-instruction is expanded to actual instruction sequence like the following.Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall back to SelectionDAG.
Tests starting with 'ptrauth-' have corresponding variants w/o this prefix.