[llvm] [PAC][CodeGen][ELF][AArch64] Support signed GOT (PR #96164)

Daniil Kovalev via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 8 00:30:29 PDT 2024


https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/96164

>From 1ac6a39ce64ffffe4436c341229113225b23a306 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 18 Jun 2024 15:43:50 +0300
Subject: [PATCH 1/3] [PAC][CodeGen][ELF][AArch64] Support signed GOT

Support the following relocations and assembly operators:

- `R_AARCH64_AUTH_ADR_GOT_PAGE` (`:got_auth:` for `adrp`)
- `R_AARCH64_AUTH_GOT_LO12_NC` (`:got_auth_lo12:` for `ldr`)
- `R_AARCH64_AUTH_GOT_ADD_LO12_NC` (`:got_auth_lo12:` for `add`)

`LOADgotAUTH` pseudo-instruction is introduced which is later expanded
to actual instruction sequence like the following.

```
adrp x16, :got_auth:sym
add x16, x16, :got_auth_lo12:sym
ldr x0, [x16]
autia x0, x16
```

Both SelectionDAG and GlobalISel are suppported. For FastISel, we fall
back to SelectionDAG.

Tests with 'auth' in name have corresponding variants w/o it.
---
 .../AArch64/AArch64ExpandPseudoInsts.cpp      | 33 ++++++++++
 llvm/lib/Target/AArch64/AArch64FastISel.cpp   |  3 +
 .../Target/AArch64/AArch64ISelLowering.cpp    |  5 ++
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   |  4 ++
 .../lib/Target/AArch64/AArch64MCInstLower.cpp | 10 ++-
 .../AArch64/AArch64MachineFunctionInfo.cpp    | 21 ++++++
 .../AArch64/AArch64MachineFunctionInfo.h      | 10 +++
 .../AArch64/AsmParser/AArch64AsmParser.cpp    | 32 +++++----
 .../GISel/AArch64InstructionSelector.cpp      |  4 +-
 .../MCTargetDesc/AArch64ELFObjectWriter.cpp   | 34 ++++++++--
 .../AArch64/MCTargetDesc/AArch64MCExpr.cpp    |  5 ++
 .../AArch64/MCTargetDesc/AArch64MCExpr.h      |  5 ++
 llvm/test/CodeGen/AArch64/basic-pic-auth.ll   | 39 +++++++++++
 .../CodeGen/AArch64/elf-globals-pic-auth.ll   | 23 +++++++
 llvm/test/CodeGen/AArch64/extern-weak-auth.ll | 36 ++++++++++
 llvm/test/CodeGen/AArch64/got-abuse-auth.ll   | 44 +++++++++++++
 .../AArch64/tagged-globals-pic-auth.ll        | 66 +++++++++++++++++++
 llvm/test/MC/AArch64/adrp-auth-relocation.s   | 12 ++++
 llvm/test/MC/AArch64/arm64-elf-relocs.s       | 20 +++++-
 llvm/test/MC/AArch64/ilp32-diagnostics.s      |  8 +++
 20 files changed, 389 insertions(+), 25 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/basic-pic-auth.ll
 create mode 100644 llvm/test/CodeGen/AArch64/elf-globals-pic-auth.ll
 create mode 100644 llvm/test/CodeGen/AArch64/extern-weak-auth.ll
 create mode 100644 llvm/test/CodeGen/AArch64/got-abuse-auth.ll
 create mode 100644 llvm/test/CodeGen/AArch64/tagged-globals-pic-auth.ll
 create mode 100644 llvm/test/MC/AArch64/adrp-auth-relocation.s

diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index 9b7fc228d5de80..72c767200b3805 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -1291,7 +1291,40 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
     MI.eraseFromParent();
     return true;
   }
+  case AArch64::LOADgotAUTH: {
+    Register DstReg = MI.getOperand(0).getReg();
+    const MachineOperand &MO1 = MI.getOperand(1);
+
+    MachineOperand GAHiOp(MO1);
+    MachineOperand GALoOp(MO1);
+    GAHiOp.addTargetFlag(AArch64II::MO_PAGE);
+    GALoOp.addTargetFlag(AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
+
+    DebugLoc DL = MI.getDebugLoc();
+    BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP), AArch64::X16)
+        .add(GAHiOp);
 
+    BuildMI(MBB, MBBI, DL, TII->get(AArch64::ADDXri), AArch64::X16)
+        .addReg(AArch64::X16)
+        .add(GALoOp)
+        .addImm(0);
+
+    BuildMI(MBB, MBBI, DL, TII->get(AArch64::LDRXui), DstReg)
+        .addReg(AArch64::X16)
+        .addImm(0);
+
+    assert(MO1.isGlobal());
+    assert(MO1.getGlobal()->getValueType() != nullptr);
+    unsigned AuthOpcode = MO1.getGlobal()->getValueType()->isFunctionTy()
+                              ? AArch64::AUTIA
+                              : AArch64::AUTDA;
+    BuildMI(MBB, MBBI, DL, TII->get(AuthOpcode), DstReg)
+        .addReg(DstReg)
+        .addReg(AArch64::X16);
+
+    MI.eraseFromParent();
+    return true;
+  }
   case AArch64::LOADgot: {
     MachineFunction *MF = MBB.getParent();
     Register DstReg = MI.getOperand(0).getReg();
diff --git a/llvm/lib/Target/AArch64/AArch64FastISel.cpp b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
index 56fd15f23363d1..0729a63cf11f13 100644
--- a/llvm/lib/Target/AArch64/AArch64FastISel.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FastISel.cpp
@@ -452,6 +452,9 @@ unsigned AArch64FastISel::materializeGV(const GlobalValue *GV) {
   if (!Subtarget->useSmallAddressing() && !Subtarget->isTargetMachO())
     return 0;
 
+  if (FuncInfo.MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT())
+    return 0;
+
   unsigned OpFlags = Subtarget->ClassifyGlobalReference(GV, TM);
 
   EVT DestEVT = TLI.getValueType(DL, GV->getType(), true);
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index c790209cc221f7..a37fc580af5ce3 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -9044,6 +9044,11 @@ SDValue AArch64TargetLowering::getGOT(NodeTy *N, SelectionDAG &DAG,
   SDValue GotAddr = getTargetNode(N, Ty, DAG, AArch64II::MO_GOT | Flags);
   // FIXME: Once remat is capable of dealing with instructions with register
   // operands, expand this into two nodes instead of using a wrapper node.
+  if (DAG.getMachineFunction()
+          .getInfo<AArch64FunctionInfo>()
+          ->hasELFSignedGOT())
+    return SDValue(DAG.getMachineNode(AArch64::LOADgotAUTH, DL, Ty, GotAddr),
+                   0);
   return DAG.getNode(AArch64ISD::LOADgot, DL, Ty, GotAddr);
 }
 
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 6afee9bd388a6d..a0206e0af44a76 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1785,6 +1785,10 @@ let Predicates = [HasPAuth] in {
               (AUTH_TCRETURN_BTI tcGPRx16x17:$dst, imm:$FPDiff, imm:$Key,
                                  imm:$Disc, tcGPR64:$AddrDisc)>;
 
+  def LOADgotAUTH : Pseudo<(outs GPR64common:$dst), (ins i64imm:$addr), []>,
+               Sched<[WriteI, ReadI]> {
+    let Defs = [X16];
+  }
 }
 
 // v9.5-A pointer authentication extensions
diff --git a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
index 37d621cd2f6580..1dc7b37e09caa6 100644
--- a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "AArch64MCInstLower.h"
+#include "AArch64MachineFunctionInfo.h"
 #include "MCTargetDesc/AArch64MCExpr.h"
 #include "Utils/AArch64BaseInfo.h"
 #include "llvm/CodeGen/AsmPrinter.h"
@@ -184,9 +185,12 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
                                                     MCSymbol *Sym) const {
   uint32_t RefFlags = 0;
 
-  if (MO.getTargetFlags() & AArch64II::MO_GOT)
-    RefFlags |= AArch64MCExpr::VK_GOT;
-  else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
+  if (MO.getTargetFlags() & AArch64II::MO_GOT) {
+    const MachineFunction *MF = MO.getParent()->getParent()->getParent();
+    RefFlags |= (MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
+                     ? AArch64MCExpr::VK_GOT_AUTH
+                     : AArch64MCExpr::VK_GOT);
+  } else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
     TLSModel::Model Model;
     if (MO.isGlobal()) {
       const GlobalValue *GV = MO.getGlobal();
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
index 957d7bc79b1874..61e5d9b35209fa 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
@@ -16,6 +16,7 @@
 #include "AArch64MachineFunctionInfo.h"
 #include "AArch64InstrInfo.h"
 #include "AArch64Subtarget.h"
+#include "llvm/BinaryFormat/ELF.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
@@ -82,6 +83,25 @@ static bool ShouldSignWithBKey(const Function &F, const AArch64Subtarget &STI) {
   return Key == "b_key";
 }
 
+static bool hasELFSignedGOTHelper(const Function &F,
+                                  const AArch64Subtarget *STI) {
+  if (!Triple(STI->getTargetTriple()).isOSBinFormatELF())
+    return false;
+  const Module *M = F.getParent();
+  uint64_t PAuthABIPlatform = -1;
+  if (const auto *PAP = mdconst::extract_or_null<ConstantInt>(
+          M->getModuleFlag("aarch64-elf-pauthabi-platform")))
+    PAuthABIPlatform = PAP->getZExtValue();
+  if (PAuthABIPlatform != ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX)
+    return false;
+  uint64_t PAuthABIVersion = -1;
+  if (const auto *PAV = mdconst::extract_or_null<ConstantInt>(
+          M->getModuleFlag("aarch64-elf-pauthabi-version")))
+    PAuthABIVersion = PAV->getZExtValue();
+  return (PAuthABIVersion &
+          (1 << ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT)) != 0;
+}
+
 AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
                                          const AArch64Subtarget *STI) {
   // If we already know that the function doesn't have a redzone, set
@@ -90,6 +110,7 @@ AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,
     HasRedZone = false;
   std::tie(SignReturnAddress, SignReturnAddressAll) = GetSignReturnAddress(F);
   SignWithBKey = ShouldSignWithBKey(F, *STI);
+  HasELFSignedGOT = hasELFSignedGOTHelper(F, STI);
   // TODO: skip functions that have no instrumented allocas for optimization
   IsMTETagged = F.hasFnAttribute(Attribute::SanitizeMemTag);
 
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
index 001521d1101eb5..d89ed5f8e56bf1 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
@@ -171,6 +171,14 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
   /// SignWithBKey modifies the default PAC-RET mode to signing with the B key.
   bool SignWithBKey = false;
 
+  /// HasELFSignedGOT is true if the target binary format is ELF and the IR
+  /// module containing the corresponding function has the following flags:
+  /// - aarch64-elf-pauthabi-platform flag equal to
+  ///   AARCH64_PAUTH_PLATFORM_LLVM_LINUX;
+  /// - aarch64-elf-pauthabi-version flag with
+  ///   AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT bit set.
+  bool HasELFSignedGOT = false;
+
   /// SigningInstrOffset captures the offset of the PAC-RET signing instruction
   /// within the prologue, so it can be re-used for authentication in the
   /// epilogue when using PC as a second salt (FEAT_PAuth_LR)
@@ -482,6 +490,8 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
 
   bool shouldSignWithBKey() const { return SignWithBKey; }
 
+  bool hasELFSignedGOT() const { return HasELFSignedGOT; }
+
   MCSymbol *getSigningInstrLabel() const { return SignInstrLabel; }
   void setSigningInstrLabel(MCSymbol *Label) { SignInstrLabel = Label; }
 
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 57e4f6d298d8db..7f9d115b865dac 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -875,6 +875,7 @@ class AArch64Operand : public MCParsedAsmOperand {
     if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
         ELFRefKind == AArch64MCExpr::VK_LO12 ||
         ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
+        ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
         ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
         ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
         ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
@@ -986,19 +987,20 @@ class AArch64Operand : public MCParsedAsmOperand {
     int64_t Addend;
     if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
                                           DarwinRefKind, Addend)) {
-      return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
-          || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
-          || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
-          || ELFRefKind == AArch64MCExpr::VK_LO12
-          || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
-          || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
-          || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
-          || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
-          || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
-          || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
-          || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12
-          || ELFRefKind == AArch64MCExpr::VK_SECREL_HI12
-          || ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
+      return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
+             DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF ||
+             (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0) ||
+             ELFRefKind == AArch64MCExpr::VK_LO12 ||
+             ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
+             ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
+             ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
+             ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
+             ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
+             ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
+             ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
+             ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
+             ELFRefKind == AArch64MCExpr::VK_SECREL_HI12 ||
+             ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
     }
 
     // If it's a constant, it should be a real immediate in range.
@@ -3250,6 +3252,7 @@ ParseStatus AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
                DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
                ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC &&
                ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
+               ELFRefKind != AArch64MCExpr::VK_GOT_AUTH_PAGE &&
                ELFRefKind != AArch64MCExpr::VK_GOT_PAGE_LO15 &&
                ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
                ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
@@ -4334,6 +4337,8 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
                   .Case("got", AArch64MCExpr::VK_GOT_PAGE)
                   .Case("gotpage_lo15", AArch64MCExpr::VK_GOT_PAGE_LO15)
                   .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
+                  .Case("got_auth", AArch64MCExpr::VK_GOT_AUTH_PAGE)
+                  .Case("got_auth_lo12", AArch64MCExpr::VK_GOT_AUTH_LO12)
                   .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
                   .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
                   .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
@@ -5708,6 +5713,7 @@ bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
 
         // Only allow these with ADDXri/ADDWri
         if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
+             ELFRefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 ||
              ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
              ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index d32007ec45fb65..accecd7b274460 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2827,7 +2827,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
     }
 
     if (OpFlags & AArch64II::MO_GOT) {
-      I.setDesc(TII.get(AArch64::LOADgot));
+      I.setDesc(TII.get(MF.getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
+                            ? AArch64::LOADgotAUTH
+                            : AArch64::LOADgot));
       I.getOperand(1).setTargetFlags(OpFlags);
     } else if (TM.getCodeModel() == CodeModel::Large &&
                !TM.isPositionIndependent()) {
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index b4c5cde5fd888d..d21408ddf844af 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -167,6 +167,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
       }
       if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
         return R_CLS(ADR_GOT_PAGE);
+      if (SymLoc == AArch64MCExpr::VK_GOT_AUTH && !IsNC) {
+        if (IsILP32) {
+          Ctx.reportError(Fixup.getLoc(),
+                          "ILP32 ADRP AUTH relocation not supported "
+                          "(LP64 eqv: AUTH_ADR_GOT_PAGE)");
+          return ELF::R_AARCH64_NONE;
+        }
+        return ELF::R_AARCH64_AUTH_ADR_GOT_PAGE;
+      }
       if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
         return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21);
       if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
@@ -237,6 +246,15 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
         return R_CLS(TLSLE_ADD_TPREL_LO12);
       if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
         return R_CLS(TLSDESC_ADD_LO12);
+      if (RefKind == AArch64MCExpr::VK_GOT_AUTH_LO12 && IsNC) {
+        if (IsILP32) {
+          Ctx.reportError(Fixup.getLoc(),
+                          "ILP32 ADD AUTH relocation not supported "
+                          "(LP64 eqv: AUTH_GOT_ADD_LO12_NC)");
+          return ELF::R_AARCH64_NONE;
+        }
+        return ELF::R_AARCH64_AUTH_GOT_ADD_LO12_NC;
+      }
       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
         return R_CLS(ADD_ABS_LO12_NC);
 
@@ -329,17 +347,23 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
     case AArch64::fixup_aarch64_ldst_imm12_scale8:
       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
         return R_CLS(LDST64_ABS_LO12_NC);
-      if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) {
+      if ((SymLoc == AArch64MCExpr::VK_GOT ||
+           SymLoc == AArch64MCExpr::VK_GOT_AUTH) &&
+          IsNC) {
         AArch64MCExpr::VariantKind AddressLoc =
             AArch64MCExpr::getAddressFrag(RefKind);
+        bool IsAuth = (SymLoc == AArch64MCExpr::VK_GOT_AUTH);
         if (!IsILP32) {
           if (AddressLoc == AArch64MCExpr::VK_LO15)
             return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
-          return ELF::R_AARCH64_LD64_GOT_LO12_NC;
+          return (IsAuth ? ELF::R_AARCH64_AUTH_GOT_LO12_NC
+                         : ELF::R_AARCH64_LD64_GOT_LO12_NC);
         }
-        Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store "
-                                        "relocation not supported (LP64 eqv: "
-                                        "LD64_GOT_LO12_NC)");
+        Ctx.reportError(Fixup.getLoc(),
+                        Twine("ILP32 64-bit load/store "
+                              "relocation not supported (LP64 eqv: ") +
+                            (IsAuth ? "AUTH_GOT_LO12_NC" : "LD64_GOT_LO12_NC") +
+                            Twine(')'));
         return ELF::R_AARCH64_NONE;
       }
       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
index 0c5a9d79f6cbc8..768170281a05fe 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp
@@ -30,6 +30,7 @@ const AArch64MCExpr *AArch64MCExpr::create(const MCExpr *Expr, VariantKind Kind,
 }
 
 StringRef AArch64MCExpr::getVariantKindName() const {
+  // clang-format off
   switch (static_cast<uint32_t>(getKind())) {
   case VK_CALL:                return "";
   case VK_LO12:                return ":lo12:";
@@ -82,9 +83,13 @@ StringRef AArch64MCExpr::getVariantKindName() const {
   case VK_TLSDESC_PAGE:        return ":tlsdesc:";
   case VK_SECREL_LO12:         return ":secrel_lo12:";
   case VK_SECREL_HI12:         return ":secrel_hi12:";
+  case VK_GOT_AUTH:            return ":got_auth:";
+  case VK_GOT_AUTH_PAGE:       return ":got_auth:";
+  case VK_GOT_AUTH_LO12:       return ":got_auth_lo12:";
   default:
     llvm_unreachable("Invalid ELF symbol kind");
   }
+  // clang-format on
 }
 
 void AArch64MCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
index 48235988869ca0..780ae39c15a73c 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
@@ -24,6 +24,7 @@ namespace llvm {
 class AArch64MCExpr : public MCTargetExpr {
 public:
   enum VariantKind {
+    // clang-format off
     // Symbol locations specifying (roughly speaking) what calculation should be
     // performed to construct the final address for the relocated
     // symbol. E.g. direct, via the GOT, ...
@@ -38,6 +39,7 @@ class AArch64MCExpr : public MCTargetExpr {
     VK_SECREL   = 0x009,
     VK_AUTH     = 0x00a,
     VK_AUTHADDR = 0x00b,
+    VK_GOT_AUTH = 0x00c,
     VK_SymLocBits = 0x00f,
 
     // Variants specifying which part of the final address calculation is
@@ -88,6 +90,8 @@ class AArch64MCExpr : public MCTargetExpr {
     VK_GOT_LO12          = VK_GOT      | VK_PAGEOFF | VK_NC,
     VK_GOT_PAGE          = VK_GOT      | VK_PAGE,
     VK_GOT_PAGE_LO15     = VK_GOT      | VK_LO15    | VK_NC,
+    VK_GOT_AUTH_LO12     = VK_GOT_AUTH | VK_PAGEOFF | VK_NC,
+    VK_GOT_AUTH_PAGE     = VK_GOT_AUTH | VK_PAGE,
     VK_DTPREL_G2         = VK_DTPREL   | VK_G2,
     VK_DTPREL_G1         = VK_DTPREL   | VK_G1,
     VK_DTPREL_G1_NC      = VK_DTPREL   | VK_G1      | VK_NC,
@@ -114,6 +118,7 @@ class AArch64MCExpr : public MCTargetExpr {
     VK_SECREL_HI12       = VK_SECREL   | VK_HI12,
 
     VK_INVALID  = 0xfff
+    // clang-format on
   };
 
 private:
diff --git a/llvm/test/CodeGen/AArch64/basic-pic-auth.ll b/llvm/test/CodeGen/AArch64/basic-pic-auth.ll
new file mode 100644
index 00000000000000..32d2098ee63ccc
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/basic-pic-auth.ll
@@ -0,0 +1,39 @@
+; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=0 -fast-isel=0 -verify-machineinstrs \
+; RUN:   -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s
+; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=0 -fast-isel=1 -verify-machineinstrs \
+; RUN:   -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s
+; RUN: llc -mtriple=aarch64-linux-gnu -global-isel=1              -verify-machineinstrs \
+; RUN:   -relocation-model=pic -mattr=+pauth %s -o - | FileCheck %s
+
+;; Note: for FastISel, we fall back to SelectionDAG
+
+ at var = global i32 0
+
+define i32 @get_globalvar() {
+; CHECK-LABEL: get_globalvar:
+
+  %val = load i32, ptr @var
+
+; CHECK: adrp x[[GOT:[0-9]+]], :got_auth:var
+; CHECK: add x[[GOT]], x[[GOT]], :got_auth_lo12:var
+; CHECK: ldr x[[SYM:[0-9]+]], [x[[GOT]]]
+; CHECK: autda x[[SYM]], x[[GOT]]
+; CHECK: ldr w0, [x[[SYM]]]
+  ret i32 %val
+}
+
+define ptr @get_globalvaraddr() {
+; CHECK-LABEL: get_globalvaraddr:
+
+  %val = load i32, ptr @var
+
+; CHECK: adrp x[[GOT:[0-9]+]], :got_auth:var
+; CHECK: add x[[GOT]], x[[GOT]], :got_auth_lo12:var
+; CHECK: ldr x0, [x[[GOT]]]
+; CHECK: autda x0, x[[GOT]]
+  ret ptr @var
+}
+
+!llvm.module.flags = !{!0, !1}
+!0 = !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+!1 = !{i32 1, !"aarch64-elf-pauthabi-version", i32 128}
diff --git a/llvm/test/CodeGen/AArch64/elf-globals-pic-auth.ll b/llvm/test/CodeGen/AArch64/elf-globals-pic-auth.ll
new file mode 100644
index 00000000000000..0bf76aeebd2c99
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/elf-globals-pic-auth.ll
@@ -0,0 +1,23 @@
+; RUN: llc -mtriple=arm64 -global-isel=0 -fast-isel=0 -relocation-model=pic -o - %s -mcpu=cyclone -mattr=+pauth | FileCheck %s
+; RUN: llc -mtriple=arm64 -global-isel=0 -fast-isel=1 -relocation-model=pic -o - %s -mcpu=cyclone -mattr=+pauth | FileCheck %s
+; RUN: llc -mtriple=arm64 -global-isel=1              -relocation-model=pic -o - %s -mcpu=cyclone -mattr=+pauth | FileCheck %s
+
+;; Note: for FastISel, we fall back to SelectionDAG
+
+ at var8 = external global i8, align 1
+
+define i8 @test_i8(i8 %new) {
+  %val = load i8, ptr @var8, align 1
+  store i8 %new, ptr @var8
+  ret i8 %val
+
+; CHECK: adrp x[[HIREG:[0-9]+]], :got_auth:var8
+; CHECK: add x[[HIREG]], x[[HIREG]], :got_auth_lo12:var8
+; CHECK: ldr x[[VAR_ADDR:[0-9]+]], [x[[HIREG]]]
+; CHECK: autda x[[VAR_ADDR]], x[[HIREG]]
+; CHECK: ldrb {{w[0-9]+}}, [x[[VAR_ADDR]]]
+}
+
+!llvm.module.flags = !{!0, !1}
+!0 = !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+!1 = !{i32 1, !"aarch64-elf-pauthabi-version", i32 128}
diff --git a/llvm/test/CodeGen/AArch64/extern-weak-auth.ll b/llvm/test/CodeGen/AArch64/extern-weak-auth.ll
new file mode 100644
index 00000000000000..a6184501363afe
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/extern-weak-auth.ll
@@ -0,0 +1,36 @@
+; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=0 -relocation-model=pic -mattr=+pauth -o - %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=1 -relocation-model=pic -mattr=+pauth -o - %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=1              -relocation-model=pic -mattr=+pauth -o - %s | FileCheck %s
+
+;; Note: for FastISel, we fall back to SelectionDAG
+
+declare extern_weak dso_local i32 @var()
+
+define ptr @foo() {
+; The usual ADRP/ADD pair can't be used for a weak reference because it must
+; evaluate to 0 if the symbol is undefined. We use a GOT entry for PIC
+; otherwise a litpool entry.
+  ret ptr @var
+
+; CHECK: adrp x[[ADDRHI:[0-9]+]], :got_auth:var
+; CHECK: add x[[ADDRHI]], x[[ADDRHI]], :got_auth_lo12:var
+; CHECK: ldr x0, [x[[ADDRHI]]]
+; CHECK: autia x0, x[[ADDRHI]]
+}
+
+ at arr_var = extern_weak global [10 x i32]
+
+define ptr @bar() {
+  %addr = getelementptr [10 x i32], ptr @arr_var, i32 0, i32 5
+
+; CHECK: adrp x[[ADDRHI:[0-9]+]], :got_auth:arr_var
+; CHECK: add x[[ADDRHI]], x[[ADDRHI]], :got_auth_lo12:arr_var
+; CHECK: ldr [[BASE:x[0-9]+]], [x[[ADDRHI]]]
+; CHECK: autda [[BASE]], x[[ADDRHI]]
+; CHECK: add x0, [[BASE]], #20
+  ret ptr %addr
+}
+
+!llvm.module.flags = !{!0, !1}
+!0 = !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+!1 = !{i32 1, !"aarch64-elf-pauthabi-version", i32 128}
diff --git a/llvm/test/CodeGen/AArch64/got-abuse-auth.ll b/llvm/test/CodeGen/AArch64/got-abuse-auth.ll
new file mode 100644
index 00000000000000..da0aa19ea6bb31
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/got-abuse-auth.ll
@@ -0,0 +1,44 @@
+; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=0 -relocation-model=pic -mattr=+pauth -o - %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=1 -relocation-model=pic -mattr=+pauth -o - %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=1              -relocation-model=pic -mattr=+pauth -o - %s | FileCheck %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=0 -relocation-model=pic -filetype=obj -mattr=+pauth -o /dev/null %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=0 -fast-isel=1 -relocation-model=pic -filetype=obj -mattr=+pauth -o /dev/null %s
+; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel=1              -relocation-model=pic -filetype=obj -mattr=+pauth -o /dev/null %s
+
+;; Note: for FastISel, we fall back to SelectionDAG
+
+declare void @consume(i32)
+declare void @func()
+
+define void @aliasee_func() {
+  ret void
+}
+ at alias_func = alias void (), ptr @aliasee_func
+
+ at aliasee_global = global i32 42
+ at alias_global = alias i32, ptr @aliasee_global
+
+define void @foo() nounwind {
+; CHECK-LABEL: foo:
+entry:
+  call void @consume(i32 ptrtoint (ptr @func to i32))
+; CHECK: adrp x[[ADDRHI:[0-9]+]], :got_auth:func
+; CHECK: add x[[ADDRHI]], x[[ADDRHI]], :got_auth_lo12:func
+; CHECK: ldr x[[SYM:[0-9]+]], [x[[ADDRHI]]]
+; CHECK: autia x[[SYM:[0-9]+]], x[[ADDRHI]]
+  call void @consume(i32 ptrtoint (ptr @alias_func to i32))
+; CHECK: adrp x[[ADDRHI:[0-9]+]], :got_auth:alias_func
+; CHECK: add x[[ADDRHI]], x[[ADDRHI]], :got_auth_lo12:alias_func
+; CHECK: ldr x[[SYM:[0-9]+]], [x[[ADDRHI]]]
+; CHECK: autia x[[SYM:[0-9]+]], x[[ADDRHI]]
+  call void @consume(i32 ptrtoint (ptr @alias_global to i32))
+; CHECK: adrp x[[ADDRHI:[0-9]+]], :got_auth:alias_global
+; CHECK: add x[[ADDRHI]], x[[ADDRHI]], :got_auth_lo12:alias_global
+; CHECK: ldr x[[SYM:[0-9]+]], [x[[ADDRHI]]]
+; CHECK: autda x[[SYM:[0-9]+]], x[[ADDRHI]]
+  ret void
+}
+
+!llvm.module.flags = !{!0, !1}
+!0 = !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+!1 = !{i32 1, !"aarch64-elf-pauthabi-version", i32 128}
diff --git a/llvm/test/CodeGen/AArch64/tagged-globals-pic-auth.ll b/llvm/test/CodeGen/AArch64/tagged-globals-pic-auth.ll
new file mode 100644
index 00000000000000..d0ba1c2bb9e28b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/tagged-globals-pic-auth.ll
@@ -0,0 +1,66 @@
+; RUN: llc --relocation-model=pic -mattr=+pauth < %s | FileCheck %s
+
+; RUN: llc -global-isel=0 -fast-isel=0 -O0 --relocation-model=pic < %s -mattr=+pauth | FileCheck %s --check-prefixes=CHECK,DAGISEL
+; RUN: llc -global-isel=0 -fast-isel=1 -O0 --relocation-model=pic < %s -mattr=+pauth | FileCheck %s --check-prefixes=CHECK,DAGISEL
+; RUN: llc -global-isel=1              -O0 --relocation-model=pic < %s -mattr=+pauth | FileCheck %s --check-prefixes=CHECK,GISEL
+
+;; Note: for FastISel, we fall back to SelectionDAG
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-android"
+
+ at global = external global i32
+declare void @func()
+
+define ptr @global_addr() #0 {
+  ; CHECK: global_addr:
+  ; CHECK: adrp  [[REG:x[0-9]+]], :got_auth:global
+  ; CHECK: add   [[REG]], [[REG]], :got_auth_lo12:global
+  ; CHECK: ldr   x0, [[[REG]]]
+  ; CHECK: autda x0, [[REG]]
+  ; CHECK: ret
+
+  ret ptr @global
+}
+
+define i32 @global_load() #0 {
+  ; CHECK: global_load:
+  ; CHECK: adrp  [[REG0:x[0-9]+]], :got_auth:global
+  ; CHECK: add   [[REG0]], [[REG0]], :got_auth_lo12:global
+  ; CHECK: ldr   [[REG1:x[0-9]+]], [[[REG0]]]
+  ; CHECK: autda [[REG1]], [[REG0]]
+  ; CHECK: ldr   w0, [[[REG1]]]
+  ; CHECK: ret
+  %load = load i32, ptr @global
+  ret i32 %load
+}
+
+define void @global_store() #0 {
+  ; CHECK:   global_store:
+  ; CHECK:   adrp  [[REG0:x[0-9]+]], :got_auth:global
+  ; CHECK:   add   [[REG0]], [[REG0]], :got_auth_lo12:global
+  ; CHECK:   ldr   [[REG1:x[0-9]+]], [[[REG0]]]
+  ; CHECK:   autda [[REG1]], [[REG0]]
+  ; GISEL:   str   wzr, [[[REG1]]]
+  ; DAGISEL: mov   w8, wzr
+  ; DAGISEL: str   w8, [[[REG1]]]
+  ; CHECK:   ret
+  store i32 0, ptr @global
+  ret void
+}
+
+define ptr @func_addr() #0 {
+  ; CHECK: func_addr:
+  ; CHECK: adrp  [[REG:x[0-9]+]], :got_auth:func
+  ; CHECK: add   [[REG]], [[REG]], :got_auth_lo12:func
+  ; CHECK: ldr   x0, [[[REG]]]
+  ; CHECK: autia x0, [[REG]]
+  ; CHECK: ret
+  ret ptr @func
+}
+
+attributes #0 = { "target-features"="+tagged-globals" }
+
+!llvm.module.flags = !{!0, !1}
+!0 = !{i32 1, !"aarch64-elf-pauthabi-platform", i32 268435458}
+!1 = !{i32 1, !"aarch64-elf-pauthabi-version", i32 128}
diff --git a/llvm/test/MC/AArch64/adrp-auth-relocation.s b/llvm/test/MC/AArch64/adrp-auth-relocation.s
new file mode 100644
index 00000000000000..57021c71632ff3
--- /dev/null
+++ b/llvm/test/MC/AArch64/adrp-auth-relocation.s
@@ -0,0 +1,12 @@
+// RUN: llvm-mc -triple=aarch64-linux-gnu -filetype=obj -o - %s | llvm-readobj -r - | FileCheck %s
+// RUN: not llvm-mc -triple=aarch64-linux-gnu_ilp32 -filetype=obj \
+// RUN:   -o /dev/null %s 2>&1 | FileCheck -check-prefix=CHECK-ILP32 %s
+
+.text
+adrp x0, :got_auth:sym
+
+.global sym
+sym:
+
+// CHECK: R_AARCH64_AUTH_ADR_GOT_PAGE sym
+// CHECK-ILP32: error: ILP32 ADRP AUTH relocation not supported (LP64 eqv: AUTH_ADR_GOT_PAGE)
diff --git a/llvm/test/MC/AArch64/arm64-elf-relocs.s b/llvm/test/MC/AArch64/arm64-elf-relocs.s
index 8813c4bd7d1aa1..b2d6d9fe9ae4b0 100644
--- a/llvm/test/MC/AArch64/arm64-elf-relocs.s
+++ b/llvm/test/MC/AArch64/arm64-elf-relocs.s
@@ -81,13 +81,17 @@
 // CHECK: adrp x15, :got:sym
 // CHECK-OBJ-LP64: 58 R_AARCH64_ADR_GOT_PAGE sym
 
+   adrp x15, :got_auth:sym
+// CHECK: adrp x15, :got_auth:sym
+// CHECK-OBJ-LP64: 5c R_AARCH64_AUTH_ADR_GOT_PAGE sym
+
    adrp x29, :gottprel:sym
 // CHECK: adrp x29, :gottprel:sym
-// CHECK-OBJ-LP64: 5c R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 sym
+// CHECK-OBJ-LP64: 60 R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 sym
 
    adrp x2, :tlsdesc:sym
 // CHECK: adrp x2, :tlsdesc:sym
-// CHECK-OBJ-LP64: 60 R_AARCH64_TLSDESC_ADR_PAGE21 sym
+// CHECK-OBJ-LP64: 64 R_AARCH64_TLSDESC_ADR_PAGE21 sym
 
    // LLVM is not competent enough to do this relocation because the
    // page boundary could occur anywhere after linking. A relocation
@@ -96,7 +100,7 @@
    .global trickQuestion
 trickQuestion:
 // CHECK: adrp x3, trickQuestion
-// CHECK-OBJ-LP64: 64 R_AARCH64_ADR_PREL_PG_HI21 trickQuestion
+// CHECK-OBJ-LP64: 68 R_AARCH64_ADR_PREL_PG_HI21 trickQuestion
 
    ldrb w2, [x3, :lo12:sym]
    ldrsb w5, [x7, #:lo12:sym]
@@ -245,6 +249,16 @@ trickQuestion:
 // CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym
 // CHECK-OBJ-LP64: R_AARCH64_LD64_GOT_LO12_NC sym+0x7
 
+   ldr x24, [x23, #:got_auth_lo12:sym]
+   ldr d22, [x21, :got_auth_lo12:sym]
+   ldr x24, [x23, :got_auth_lo12:sym+7]
+// CHECK: ldr x24, [x23, :got_auth_lo12:sym]
+// CHECK: ldr d22, [x21, :got_auth_lo12:sym]
+// CHECK: ldr x24, [x23, :got_auth_lo12:sym+7]
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LO12_NC sym
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LO12_NC sym
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LO12_NC sym+0x7
+
   ldr x24, [x23, #:gotpage_lo15:sym]
   ldr d22, [x21, :gotpage_lo15:sym]
   ldr d22, [x23, :gotpage_lo15:sym+7]
diff --git a/llvm/test/MC/AArch64/ilp32-diagnostics.s b/llvm/test/MC/AArch64/ilp32-diagnostics.s
index 4ca15f160418da..f2d0c8d2e37d67 100644
--- a/llvm/test/MC/AArch64/ilp32-diagnostics.s
+++ b/llvm/test/MC/AArch64/ilp32-diagnostics.s
@@ -85,6 +85,14 @@
 
    ldr x24, [x23, #:got_lo12:sym]
 // CHECK-ERROR: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: LD64_GOT_LO12_NC)
+// CHECK-ERROR: ^
+
+   ldr x24, [x23, #:got_auth_lo12:sym]
+// CHECK-ERROR: error: ILP32 64-bit load/store relocation not supported (LP64 eqv: AUTH_GOT_LO12_NC)
+// CHECK-ERROR: ^
+
+   add x24, x23, #:got_auth_lo12:sym
+// CHECK-ERROR: error: ILP32 ADD AUTH relocation not supported (LP64 eqv: AUTH_GOT_ADD_LO12_NC)
 // CHECK-ERROR: ^
 
    ldr x24, [x23, :gottprel_lo12:sym]

>From 8c0b4210e7484e05774b766cc96700bf0bfb67cb Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 8 Jul 2024 10:20:17 +0300
Subject: [PATCH 2/3] Fix relocs names according to #96158

---
 .../Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp  | 2 +-
 llvm/test/MC/AArch64/arm64-elf-relocs.s                     | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index d21408ddf844af..72671b0715f6e5 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -356,7 +356,7 @@ unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx,
         if (!IsILP32) {
           if (AddressLoc == AArch64MCExpr::VK_LO15)
             return ELF::R_AARCH64_LD64_GOTPAGE_LO15;
-          return (IsAuth ? ELF::R_AARCH64_AUTH_GOT_LO12_NC
+          return (IsAuth ? ELF::R_AARCH64_AUTH_LD64_GOT_LO12_NC
                          : ELF::R_AARCH64_LD64_GOT_LO12_NC);
         }
         Ctx.reportError(Fixup.getLoc(),
diff --git a/llvm/test/MC/AArch64/arm64-elf-relocs.s b/llvm/test/MC/AArch64/arm64-elf-relocs.s
index b2d6d9fe9ae4b0..f679bb4c82827b 100644
--- a/llvm/test/MC/AArch64/arm64-elf-relocs.s
+++ b/llvm/test/MC/AArch64/arm64-elf-relocs.s
@@ -255,9 +255,9 @@ trickQuestion:
 // CHECK: ldr x24, [x23, :got_auth_lo12:sym]
 // CHECK: ldr d22, [x21, :got_auth_lo12:sym]
 // CHECK: ldr x24, [x23, :got_auth_lo12:sym+7]
-// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LO12_NC sym
-// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LO12_NC sym
-// CHECK-OBJ-LP64: R_AARCH64_AUTH_GOT_LO12_NC sym+0x7
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_LD64_GOT_LO12_NC sym
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_LD64_GOT_LO12_NC sym
+// CHECK-OBJ-LP64: R_AARCH64_AUTH_LD64_GOT_LO12_NC sym+0x7
 
   ldr x24, [x23, #:gotpage_lo15:sym]
   ldr d22, [x21, :gotpage_lo15:sym]

>From 4c85d6c31cfc89e8543d4f8d78c9cd82dd33ca37 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 8 Jul 2024 10:28:42 +0300
Subject: [PATCH 3/3] Address review comments

---
 .../AArch64/AArch64MachineFunctionInfo.cpp    | 20 +++++++++----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
index 61e5d9b35209fa..0d4a723d315ff2 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
@@ -88,18 +88,16 @@ static bool hasELFSignedGOTHelper(const Function &F,
   if (!Triple(STI->getTargetTriple()).isOSBinFormatELF())
     return false;
   const Module *M = F.getParent();
-  uint64_t PAuthABIPlatform = -1;
-  if (const auto *PAP = mdconst::extract_or_null<ConstantInt>(
-          M->getModuleFlag("aarch64-elf-pauthabi-platform")))
-    PAuthABIPlatform = PAP->getZExtValue();
-  if (PAuthABIPlatform != ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX)
+  const auto *PAP = mdconst::extract_or_null<ConstantInt>(
+      M->getModuleFlag("aarch64-elf-pauthabi-platform"));
+  if (!PAP || PAP->getZExtValue() != ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX)
     return false;
-  uint64_t PAuthABIVersion = -1;
-  if (const auto *PAV = mdconst::extract_or_null<ConstantInt>(
-          M->getModuleFlag("aarch64-elf-pauthabi-version")))
-    PAuthABIVersion = PAV->getZExtValue();
-  return (PAuthABIVersion &
-          (1 << ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT)) != 0;
+  const auto *PAV = mdconst::extract_or_null<ConstantInt>(
+      M->getModuleFlag("aarch64-elf-pauthabi-version"));
+  if (!PAV)
+    return false;
+  return PAV->getZExtValue() &
+         (1 << ELF::AARCH64_PAUTH_PLATFORM_LLVM_LINUX_VERSION_GOT);
 }
 
 AArch64FunctionInfo::AArch64FunctionInfo(const Function &F,



More information about the llvm-commits mailing list