Skip to content

[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

Merged
merged 4 commits into from
Dec 10, 2024

Conversation

kovdan01
Copy link
Contributor

@kovdan01 kovdan01 commented Nov 1, 2024

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.

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.
@kovdan01 kovdan01 self-assigned this Nov 1, 2024
@kovdan01 kovdan01 marked this pull request as ready for review November 1, 2024 09:30
@llvmbot llvmbot added backend:AArch64 mc Machine (object) code labels Nov 1, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 1, 2024

@llvm/pr-subscribers-mc

@llvm/pr-subscribers-backend-aarch64

Author: Daniil Kovalev (kovdan01)

Changes

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.


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:

  • (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+29-18)
  • (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+7-1)
  • (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp (+18)
  • (modified) llvm/test/CodeGen/AArch64/ptrauth-extern-weak.ll (+42)
  • (added) llvm/test/CodeGen/AArch64/ptrauth-tiny-model-pic.ll (+182)
  • (added) llvm/test/CodeGen/AArch64/ptrauth-tiny-model-static.ll (+157)
  • (modified) llvm/test/MC/AArch64/arm64-elf-relocs.s (+13)
  • (modified) llvm/test/MC/AArch64/ilp32-diagnostics.s (+6)
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]

@kovdan01
Copy link
Contributor Author

kovdan01 commented Nov 1, 2024

Re-opened #113812 after accidentally cluttering that with wrong merge commit and auto-requesting review from a lot of reviewers as code owners.

@kovdan01
Copy link
Contributor Author

Would be glad to see everyone's feedback on the changes.

1 similar comment
@kovdan01
Copy link
Contributor Author

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 \
Copy link
Member

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

Copy link
Contributor Author

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test [[#@LINE-1]]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks, see f8a3c3a

@kovdan01
Copy link
Contributor Author

@MaskRay Please see replies to your comments above

@kovdan01
Copy link
Contributor Author

kovdan01 commented Dec 8, 2024

Would be glad to see everyone's feedback on the changes.

@kovdan01 kovdan01 merged commit 0ed696e into llvm:main Dec 10, 2024
8 checks passed
kovdan01 added a commit that referenced this pull request Dec 18, 2024
…3816)

Depends on #114525

Support `R_AARCH64_AUTH_GOT_ADR_PREL_LO21` and `R_AARCH64_AUTH_GOT_LD_PREL19`
GOT-generating relocations. A corresponding `RE_AARCH64_AUTH_GOT_PC` member
of `RelExpr` is added, which is an AUTH-specific variant of `R_GOT_PC`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 mc Machine (object) code
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants