[lld] [PAC][lld][AArch64][ELF] Support signed GOT (PR #113815)

Daniil Kovalev via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 15 23:43:06 PST 2024


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

>From 126df1197e6049e6c50c3a78c72753adfa16570e Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 25 Oct 2024 12:23:12 +0300
Subject: [PATCH 01/15] [PAC][lld][AArch64][ELF] Support signed GOT

Support `R_AARCH64_AUTH_ADR_GOT_PAGE`, `R_AARCH64_AUTH_GOT_LO12_NC` and
`R_AARCH64_AUTH_GOT_ADD_LO12_NC` GOT-generating relocations. For preemptible
symbols, dynamic relocation `R_AARCH64_AUTH_GLOB_DAT` is emitted. Otherwise,
we unconditionally emit `R_AARCH64_AUTH_RELATIVE` dynamic relocation since
pointers in signed GOT needs to be signed during dynamic link time.
---
 lld/ELF/Arch/AArch64.cpp                     |  9 ++
 lld/ELF/InputSection.cpp                     |  2 +
 lld/ELF/Relocations.cpp                      | 40 +++++++--
 lld/ELF/Relocations.h                        |  2 +
 lld/ELF/Symbols.h                            |  1 +
 lld/ELF/SyntheticSections.cpp                | 17 ++++
 lld/ELF/SyntheticSections.h                  |  5 ++
 lld/test/ELF/aarch64-got-relocations-pauth.s | 94 ++++++++++++++++++++
 8 files changed, 163 insertions(+), 7 deletions(-)
 create mode 100644 lld/test/ELF/aarch64-got-relocations-pauth.s

diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 99fc750486e4b4..87374aab738f8b 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -202,11 +202,16 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
   case R_AARCH64_LD64_GOT_LO12_NC:
   case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
     return R_GOT;
+  case R_AARCH64_AUTH_LD64_GOT_LO12_NC:
+  case R_AARCH64_AUTH_GOT_ADD_LO12_NC:
+    return R_AARCH64_AUTH_GOT;
   case R_AARCH64_LD64_GOTPAGE_LO15:
     return RE_AARCH64_GOT_PAGE;
   case R_AARCH64_ADR_GOT_PAGE:
   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     return RE_AARCH64_GOT_PAGE_PC;
+  case R_AARCH64_AUTH_ADR_GOT_PAGE:
+    return RE_AARCH64_AUTH_GOT_PAGE_PC;
   case R_AARCH64_GOTPCREL32:
   case R_AARCH64_GOT_LD_PREL19:
     return R_GOT_PC;
@@ -258,6 +263,7 @@ int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const {
     return read64(ctx, buf + 8);
   case R_AARCH64_NONE:
   case R_AARCH64_GLOB_DAT:
+  case R_AARCH64_AUTH_GLOB_DAT:
   case R_AARCH64_JUMP_SLOT:
     return 0;
   case R_AARCH64_ABS16:
@@ -528,9 +534,11 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
       write32(ctx, loc, val);
     break;
   case R_AARCH64_ADD_ABS_LO12_NC:
+  case R_AARCH64_AUTH_GOT_ADD_LO12_NC:
     write32Imm12(loc, val);
     break;
   case R_AARCH64_ADR_GOT_PAGE:
+  case R_AARCH64_AUTH_ADR_GOT_PAGE:
   case R_AARCH64_ADR_PREL_PG_HI21:
   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
   case R_AARCH64_TLSDESC_ADR_PAGE21:
@@ -580,6 +588,7 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     break;
   case R_AARCH64_LDST64_ABS_LO12_NC:
   case R_AARCH64_LD64_GOT_LO12_NC:
+  case R_AARCH64_AUTH_LD64_GOT_LO12_NC:
   case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
   case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
   case R_AARCH64_TLSDESC_LD64_LO12:
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 7e76bae19fc6a2..940cb9d3264173 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -783,6 +783,7 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
   case RE_ARM_SBREL:
     return r.sym->getVA(ctx, a) - getARMStaticBase(*r.sym);
   case R_GOT:
+  case R_AARCH64_AUTH_GOT:
   case R_RELAX_TLS_GD_TO_IE_ABS:
     return r.sym->getGotVA(ctx) + a;
   case RE_LOONGARCH_GOT:
@@ -810,6 +811,7 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
   case R_RELAX_TLS_GD_TO_IE_GOT_OFF:
     return r.sym->getGotOffset(ctx) + a;
   case RE_AARCH64_GOT_PAGE_PC:
+  case RE_AARCH64_AUTH_GOT_PAGE_PC:
   case RE_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC:
     return getAArch64Page(r.sym->getGotVA(ctx) + a) - getAArch64Page(p);
   case RE_AARCH64_GOT_PAGE:
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 41c04b29034563..d481b873ff5ae0 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -197,8 +197,9 @@ static bool needsPlt(RelExpr expr) {
 }
 
 bool lld::elf::needsGot(RelExpr expr) {
-  return oneof<R_GOT, R_GOT_OFF, RE_MIPS_GOT_LOCAL_PAGE, RE_MIPS_GOT_OFF,
-               RE_MIPS_GOT_OFF32, RE_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,
+  return oneof<R_GOT, RE_AARCH64_AUTH_GOT, R_GOT_OFF, RE_MIPS_GOT_LOCAL_PAGE,
+               RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32, RE_AARCH64_GOT_PAGE_PC,
+               RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTPLT,
                RE_AARCH64_GOT_PAGE, RE_LOONGARCH_GOT, RE_LOONGARCH_GOT_PAGE_PC>(
       expr);
 }
@@ -895,14 +896,26 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
 
   // If preemptible, emit a GLOB_DAT relocation.
   if (sym.isPreemptible) {
-    ctx.mainPart->relaDyn->addReloc({ctx.target->gotRel, ctx.in.got.get(), off,
+    RelType gotRel = ctx.target->gotRel;
+    if (sym.hasFlag(NEEDS_GOT_AUTH)) {
+      assert(ctx.arg.emachine == EM_AARCH64);
+      gotRel = R_AARCH64_AUTH_GLOB_DAT;
+    }
+    ctx.mainPart->relaDyn->addReloc({gotRel, ctx.in.got.get(), off,
                                      DynamicReloc::AgainstSymbol, sym, 0,
                                      R_ABS});
     return;
   }
 
   // Otherwise, the value is either a link-time constant or the load base
-  // plus a constant.
+  // plus a constant. Signed GOT requires dynamic relocation.
+  if (sym.hasFlag(NEEDS_GOT_AUTH)) {
+    ctx.in.got->getPartition(ctx).relaDyn->addReloc(
+        {R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off,
+         DynamicReloc::AddendOnlyWithTargetVA, sym, 0, R_ABS});
+    return;
+  }
+
   if (!ctx.arg.isPic || isAbsolute(sym))
     ctx.in.got->addConstant({R_ABS, ctx.target->symbolicRel, off, 0, &sym});
   else
@@ -956,11 +969,12 @@ bool RelocationScanner::isStaticLinkTimeConstant(RelExpr e, RelType type,
   // These expressions always compute a constant
   if (oneof<R_GOTPLT, R_GOT_OFF, R_RELAX_HINT, RE_MIPS_GOT_LOCAL_PAGE,
             RE_MIPS_GOTREL, RE_MIPS_GOT_OFF, RE_MIPS_GOT_OFF32,
-            RE_MIPS_GOT_GP_PC, RE_AARCH64_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
+            RE_MIPS_GOT_GP_PC, RE_AARCH64_GOT_PAGE_PC,
+            RE_AARCH64_AUTH_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
             R_GOTPLTONLY_PC, R_PLT_PC, R_PLT_GOTREL, R_PLT_GOTPLT,
             R_GOTPLT_GOTREL, R_GOTPLT_PC, RE_PPC32_PLTREL, RE_PPC64_CALL_PLT,
             RE_PPC64_RELAX_TOC, RE_RISCV_ADD, RE_AARCH64_GOT_PAGE,
-            RE_LOONGARCH_PLT_PAGE_PC, RE_LOONGARCH_GOT,
+            RE_AARCH64_AUTH_GOT, RE_LOONGARCH_PLT_PAGE_PC, RE_LOONGARCH_GOT,
             RE_LOONGARCH_GOT_PAGE_PC>(e))
     return true;
 
@@ -1075,7 +1089,19 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
     } else if (!sym.isTls() || ctx.arg.emachine != EM_LOONGARCH) {
       // Many LoongArch TLS relocs reuse the RE_LOONGARCH_GOT type, in which
       // case the NEEDS_GOT flag shouldn't get set.
-      sym.setFlags(NEEDS_GOT);
+      bool needsGotAuth =
+          (expr == R_AARCH64_AUTH_GOT || expr == R_AARCH64_AUTH_GOT_PAGE_PC);
+      uint16_t flags = sym.flags.load(std::memory_order_relaxed);
+      if (!(flags & NEEDS_GOT)) {
+        if (needsGotAuth)
+          sym.setFlags(NEEDS_GOT | NEEDS_GOT_AUTH);
+        else
+          sym.setFlags(NEEDS_GOT);
+      } else if (needsGotAuth != static_cast<bool>(flags & NEEDS_GOT_AUTH)) {
+        fatal("both AUTH and non-AUTH GOT entries for '" + sym.getName() +
+              "' requested, but only one type of GOT entry per symbol is "
+              "supported");
+      }
     }
   } else if (needsPlt(expr)) {
     sym.setFlags(NEEDS_PLT);
diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h
index 7ca203257ea876..d993ab77adc3cc 100644
--- a/lld/ELF/Relocations.h
+++ b/lld/ELF/Relocations.h
@@ -92,7 +92,9 @@ enum RelExpr {
   // of a relocation type, there are some relocations whose semantics are
   // unique to a target. Such relocation are marked with RE_<TARGET_NAME>.
   RE_AARCH64_GOT_PAGE_PC,
+  RE_AARCH64_AUTH_GOT_PAGE_PC,
   RE_AARCH64_GOT_PAGE,
+  RE_AARCH64_AUTH_GOT,
   RE_AARCH64_PAGE_PC,
   RE_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC,
   RE_AARCH64_TLSDESC_PAGE,
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index fac957a7248856..ebc2fcf8e5eeb2 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -51,6 +51,7 @@ enum {
   NEEDS_TLSGD_TO_IE = 1 << 6,
   NEEDS_GOT_DTPREL = 1 << 7,
   NEEDS_TLSIE = 1 << 8,
+  NEEDS_GOT_AUTH = 1 << 9,
 };
 
 // The base class for real symbol classes.
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index c8a05e4b9c3cc6..2c5da0d37a9b43 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -668,6 +668,8 @@ void GotSection::addConstant(const Relocation &r) { relocations.push_back(r); }
 void GotSection::addEntry(const Symbol &sym) {
   assert(sym.auxIdx == ctx.symAux.size() - 1);
   ctx.symAux.back().gotIdx = numEntries++;
+  if (sym.hasFlag(NEEDS_GOT_AUTH))
+    authEntries.push_back({(numEntries - 1) * ctx.arg.wordsize, sym.isFunc()});
 }
 
 bool GotSection::addTlsDescEntry(const Symbol &sym) {
@@ -732,6 +734,21 @@ void GotSection::writeTo(uint8_t *buf) {
     return;
   ctx.target->writeGotHeader(buf);
   ctx.target->relocateAlloc(*this, buf);
+  for (const AuthEntryInfo &authEntry : authEntries) {
+    // https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#default-signing-schema
+    //   Signed GOT entries use the IA key for symbols of type STT_FUNC and the
+    //   DA key for all other symbol types, with the address of the GOT entry as
+    //   the modifier. The static linker must encode the signing schema into the
+    //   GOT slot.
+    //
+    // https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#encoding-the-signing-schema
+    //   If address diversity is set and the discriminator
+    //   is 0 then modifier = Place
+    uint8_t *dest = buf + authEntry.offset;
+    uint64_t key = authEntry.isSymbolFunc ? /*IA*/ 0b00 : /*DA*/ 0b10;
+    uint64_t addrDiversity = 1;
+    write64(ctx, dest, (addrDiversity << 63) | (key << 60));
+  }
 }
 
 static uint64_t getMipsPageAddr(uint64_t addr) {
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 132513cbd3b796..5d21d4e9779d30 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -131,6 +131,11 @@ class GotSection final : public SyntheticSection {
   size_t numEntries = 0;
   uint32_t tlsIndexOff = -1;
   uint64_t size = 0;
+  struct AuthEntryInfo {
+    size_t offset;
+    bool isSymbolFunc;
+  };
+  SmallVector<AuthEntryInfo, 0> authEntries;
 };
 
 // .note.GNU-stack section.
diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
new file mode 100644
index 00000000000000..f04e3d953388ce
--- /dev/null
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -0,0 +1,94 @@
+# REQUIRES: aarch64
+
+# RUN: rm -rf %t && split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %p/Inputs/shared.s -o a.o
+# RUN: ld.lld -shared a.o -o a.so
+
+#--- ok.s
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux ok.s -o ok.o
+
+# RUN: ld.lld ok.o a.so -pie -o external
+# RUN: llvm-readelf -r -S -x .got external | FileCheck %s --check-prefix=EXTERNAL
+
+# RUN: ld.lld ok.o a.o -pie -o local
+# RUN: llvm-readelf -r -S -x .got -s local | FileCheck %s --check-prefix=LOCAL
+
+# EXTERNAL:      Offset            Info             Type                    Symbol's Value   Symbol's Name + Addend
+# EXTERNAL-NEXT: 0000000000020380  000000010000e201 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0
+# EXTERNAL-NEXT: 0000000000020388  000000020000e201 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0
+
+## Symbol's values for bar and zed are equal since they contain no content (see Inputs/shared.s)
+# LOCAL:         Offset            Info             Type                    Symbol's Value   Symbol's Name + Addend
+# LOCAL-NEXT:    0000000000020320  0000000000000411 R_AARCH64_AUTH_RELATIVE 10260
+# LOCAL-NEXT:    0000000000020328  0000000000000411 R_AARCH64_AUTH_RELATIVE 10260
+
+# EXTERNAL:      Hex dump of section '.got':
+# EXTERNAL-NEXT: 0x00020380 00000000 00000080 00000000 000000a0
+#                                          ^^
+#                                          0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
+#                                                            ^^
+#                                                            0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
+
+# LOCAL: Symbol table '.symtab' contains {{.*}} entries:
+# LOCAL:    Num:    Value          Size Type    Bind   Vis       Ndx Name
+# LOCAL:         0000000000010260     0 FUNC    GLOBAL DEFAULT     6 bar
+# LOCAL:         0000000000010260     0 NOTYPE  GLOBAL DEFAULT     6 zed
+
+# LOCAL:         Hex dump of section '.got':
+# LOCAL-NEXT:    0x00020320 00000000 00000080 00000000 000000a0
+#                                          ^^
+#                                          0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
+#                                                            ^^
+#                                                            0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
+
+# RUN: llvm-objdump -d external | FileCheck %s --check-prefix=EXTERNAL-ASM
+
+# EXTERNAL-ASM:      <_start>:
+# EXTERNAL-ASM-NEXT: adrp x0, 0x20000
+# EXTERNAL-ASM-NEXT: ldr  x0, [x0, #0x380]
+# EXTERNAL-ASM-NEXT: adrp x1, 0x20000
+# EXTERNAL-ASM-NEXT: add  x1, x1, #0x380
+# EXTERNAL-ASM-NEXT: adrp x0, 0x20000
+# EXTERNAL-ASM-NEXT: ldr  x0, [x0, #0x388]
+# EXTERNAL-ASM-NEXT: adrp x1, 0x20000
+# EXTERNAL-ASM-NEXT: add  x1, x1, #0x388
+
+# RUN: llvm-objdump -d local | FileCheck %s --check-prefix=LOCAL-ASM
+
+# LOCAL-ASM:         <_start>:
+# LOCAL-ASM-NEXT:    adrp x0, 0x20000
+# LOCAL-ASM-NEXT:    ldr  x0, [x0, #0x320]
+# LOCAL-ASM-NEXT:    adrp x1, 0x20000
+# LOCAL-ASM-NEXT:    add  x1, x1, #0x320
+# LOCAL-ASM-NEXT:    adrp x0, 0x20000
+# LOCAL-ASM-NEXT:    ldr  x0, [x0, #0x328]
+# LOCAL-ASM-NEXT:    adrp x1, 0x20000
+# LOCAL-ASM-NEXT:    add  x1, x1, #0x328
+
+.globl _start
+_start:
+  adrp x0, :got_auth:bar
+  ldr  x0, [x0, :got_auth_lo12:bar]
+  adrp x1, :got_auth:bar
+  add  x1, x1, :got_auth_lo12:bar
+  adrp x0, :got_auth:zed
+  ldr  x0, [x0, :got_auth_lo12:zed]
+  adrp x1, :got_auth:zed
+  add  x1, x1, :got_auth_lo12:zed
+
+#--- err.s
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux err.s -o err.o
+
+# RUN: not ld.lld err.o a.so -pie -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
+
+# ERR: error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported
+
+.globl _start
+_start:
+  adrp x0, :got_auth:bar
+  ldr  x0, [x0, :got_auth_lo12:bar]
+  adrp x0, :got:bar
+  ldr  x0, [x0, :got_lo12:bar]

>From 2295d26de486acb1bce5ea88b661ba94792dfc66 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 1 Nov 2024 13:00:21 +0300
Subject: [PATCH 02/15] Address review comments

---
 lld/ELF/Relocations.cpp       | 5 +----
 lld/ELF/SyntheticSections.cpp | 4 ++--
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index d481b873ff5ae0..8b58a08e124e90 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1093,10 +1093,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
           (expr == R_AARCH64_AUTH_GOT || expr == R_AARCH64_AUTH_GOT_PAGE_PC);
       uint16_t flags = sym.flags.load(std::memory_order_relaxed);
       if (!(flags & NEEDS_GOT)) {
-        if (needsGotAuth)
-          sym.setFlags(NEEDS_GOT | NEEDS_GOT_AUTH);
-        else
-          sym.setFlags(NEEDS_GOT);
+        sym.setFlags(needsGotAuth ? (NEEDS_GOT | NEEDS_GOT_AUTH) : NEEDS_GOT);
       } else if (needsGotAuth != static_cast<bool>(flags & NEEDS_GOT_AUTH)) {
         fatal("both AUTH and non-AUTH GOT entries for '" + sym.getName() +
               "' requested, but only one type of GOT entry per symbol is "
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 2c5da0d37a9b43..3f1fb8f2df0579 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -735,13 +735,13 @@ void GotSection::writeTo(uint8_t *buf) {
   ctx.target->writeGotHeader(buf);
   ctx.target->relocateAlloc(*this, buf);
   for (const AuthEntryInfo &authEntry : authEntries) {
-    // https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#default-signing-schema
+    // https://github.com/ARM-software/abi-aa/blob/2024Q3/pauthabielf64/pauthabielf64.rst#default-signing-schema
     //   Signed GOT entries use the IA key for symbols of type STT_FUNC and the
     //   DA key for all other symbol types, with the address of the GOT entry as
     //   the modifier. The static linker must encode the signing schema into the
     //   GOT slot.
     //
-    // https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#encoding-the-signing-schema
+    // https://github.com/ARM-software/abi-aa/blob/2024Q3/pauthabielf64/pauthabielf64.rst#encoding-the-signing-schema
     //   If address diversity is set and the discriminator
     //   is 0 then modifier = Place
     uint8_t *dest = buf + authEntry.offset;

>From b8d3c5197b1f2a123257c07aa688a07f4417cec7 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Fri, 1 Nov 2024 13:01:29 +0300
Subject: [PATCH 03/15] Use `##` for comments in tests

---
 lld/test/ELF/aarch64-got-relocations-pauth.s | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
index f04e3d953388ce..ef089b61b6771c 100644
--- a/lld/test/ELF/aarch64-got-relocations-pauth.s
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -26,10 +26,10 @@
 
 # EXTERNAL:      Hex dump of section '.got':
 # EXTERNAL-NEXT: 0x00020380 00000000 00000080 00000000 000000a0
-#                                          ^^
-#                                          0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
-#                                                            ^^
-#                                                            0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
+##                                         ^^
+##                                         0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
+##                                                           ^^
+##                                                           0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
 
 # LOCAL: Symbol table '.symtab' contains {{.*}} entries:
 # LOCAL:    Num:    Value          Size Type    Bind   Vis       Ndx Name
@@ -38,10 +38,10 @@
 
 # LOCAL:         Hex dump of section '.got':
 # LOCAL-NEXT:    0x00020320 00000000 00000080 00000000 000000a0
-#                                          ^^
-#                                          0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
-#                                                            ^^
-#                                                            0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
+##                                         ^^
+##                                         0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
+##                                                           ^^
+##                                                           0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
 
 # RUN: llvm-objdump -d external | FileCheck %s --check-prefix=EXTERNAL-ASM
 

>From 7f7c95223972d4b6c95dcc5f60f6658e5ada21e6 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Sun, 10 Nov 2024 21:54:00 +0300
Subject: [PATCH 04/15] Use `Err(ctx)` instead of `fatal` and use `getLocation`
 in error message

---
 lld/ELF/Relocations.cpp                      | 7 ++++---
 lld/test/ELF/aarch64-got-relocations-pauth.s | 7 ++++++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 8b58a08e124e90..8cafb565d68a00 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1095,9 +1095,10 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
       if (!(flags & NEEDS_GOT)) {
         sym.setFlags(needsGotAuth ? (NEEDS_GOT | NEEDS_GOT_AUTH) : NEEDS_GOT);
       } else if (needsGotAuth != static_cast<bool>(flags & NEEDS_GOT_AUTH)) {
-        fatal("both AUTH and non-AUTH GOT entries for '" + sym.getName() +
-              "' requested, but only one type of GOT entry per symbol is "
-              "supported");
+        Err(ctx) << "both AUTH and non-AUTH GOT entries for '" << sym.getName()
+                 << "' requested, but only one type of GOT entry per symbol is "
+                    "supported"
+                 << getLocation(ctx, *sec, sym, offset);
       }
     }
   } else if (needsPlt(expr)) {
diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
index ef089b61b6771c..5760579bcb02e2 100644
--- a/lld/test/ELF/aarch64-got-relocations-pauth.s
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -84,7 +84,12 @@ _start:
 
 # RUN: not ld.lld err.o a.so -pie -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
 
-# ERR: error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported
+# ERR:      error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported
+# ERR-NEXT: >>> defined in a.so
+# ERR-NEXT: >>> referenced by err.o:(.text+0x8)
+# ERR:      error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported
+# ERR-NEXT: >>> defined in a.so
+# ERR-NEXT: >>> referenced by err.o:(.text+0xC)
 
 .globl _start
 _start:

>From 6d2bfb148b052798b4845bbabbd17cd142f5ec8d Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 18 Nov 2024 08:20:40 +0300
Subject: [PATCH 05/15] Use aarch64 triple in tests

---
 lld/test/ELF/aarch64-got-relocations-pauth.s | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
index 5760579bcb02e2..3fe73a086c729b 100644
--- a/lld/test/ELF/aarch64-got-relocations-pauth.s
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -2,12 +2,12 @@
 
 # RUN: rm -rf %t && split-file %s %t && cd %t
 
-# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %p/Inputs/shared.s -o a.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared.s -o a.o
 # RUN: ld.lld -shared a.o -o a.so
 
 #--- ok.s
 
-# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux ok.s -o ok.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64 ok.s -o ok.o
 
 # RUN: ld.lld ok.o a.so -pie -o external
 # RUN: llvm-readelf -r -S -x .got external | FileCheck %s --check-prefix=EXTERNAL
@@ -80,7 +80,7 @@ _start:
 
 #--- err.s
 
-# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux err.s -o err.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64 err.s -o err.o
 
 # RUN: not ld.lld err.o a.so -pie -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
 

>From 6d3b0d3762314d084a377f198149f0232cc18226 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 2 Dec 2024 01:09:41 +0300
Subject: [PATCH 06/15] Switch to `printLocation` from `getLocation`

---
 lld/ELF/Relocations.cpp                      | 9 +++++----
 lld/test/ELF/aarch64-got-relocations-pauth.s | 2 +-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 8cafb565d68a00..77168f09414cdf 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1095,10 +1095,11 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
       if (!(flags & NEEDS_GOT)) {
         sym.setFlags(needsGotAuth ? (NEEDS_GOT | NEEDS_GOT_AUTH) : NEEDS_GOT);
       } else if (needsGotAuth != static_cast<bool>(flags & NEEDS_GOT_AUTH)) {
-        Err(ctx) << "both AUTH and non-AUTH GOT entries for '" << sym.getName()
-                 << "' requested, but only one type of GOT entry per symbol is "
-                    "supported"
-                 << getLocation(ctx, *sec, sym, offset);
+        auto diag = Err(ctx);
+        diag << "both AUTH and non-AUTH GOT entries for '" << sym.getName()
+             << "' requested, but only one type of GOT entry per symbol is "
+                "supported";
+        printLocation(diag, *sec, sym, offset);
       }
     }
   } else if (needsPlt(expr)) {
diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
index 3fe73a086c729b..b91f0a5f0c830a 100644
--- a/lld/test/ELF/aarch64-got-relocations-pauth.s
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -89,7 +89,7 @@ _start:
 # ERR-NEXT: >>> referenced by err.o:(.text+0x8)
 # ERR:      error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported
 # ERR-NEXT: >>> defined in a.so
-# ERR-NEXT: >>> referenced by err.o:(.text+0xC)
+# ERR-NEXT: >>> referenced by err.o:(.text+0xc)
 
 .globl _start
 _start:

>From 1e8794324b797440b133e77f95648bbc83f106c9 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 2 Dec 2024 01:20:41 +0300
Subject: [PATCH 07/15] Address review comments

---
 lld/ELF/SyntheticSections.cpp                | 2 +-
 lld/test/ELF/aarch64-got-relocations-pauth.s | 4 +---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 3f1fb8f2df0579..7c79fd5a69025a 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -745,7 +745,7 @@ void GotSection::writeTo(uint8_t *buf) {
     //   If address diversity is set and the discriminator
     //   is 0 then modifier = Place
     uint8_t *dest = buf + authEntry.offset;
-    uint64_t key = authEntry.isSymbolFunc ? /*IA*/ 0b00 : /*DA*/ 0b10;
+    uint64_t key = authEntry.isSymbolFunc ? /*IA=*/0b00 : /*DA=*/0b10;
     uint64_t addrDiversity = 1;
     write64(ctx, dest, (addrDiversity << 63) | (key << 60));
   }
diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
index b91f0a5f0c830a..1b01318bf36ab6 100644
--- a/lld/test/ELF/aarch64-got-relocations-pauth.s
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -6,7 +6,6 @@
 # RUN: ld.lld -shared a.o -o a.so
 
 #--- ok.s
-
 # RUN: llvm-mc -filetype=obj -triple=aarch64 ok.s -o ok.o
 
 # RUN: ld.lld ok.o a.so -pie -o external
@@ -79,10 +78,9 @@ _start:
   add  x1, x1, :got_auth_lo12:zed
 
 #--- err.s
-
 # RUN: llvm-mc -filetype=obj -triple=aarch64 err.s -o err.o
 
-# RUN: not ld.lld err.o a.so -pie -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
+# RUN: not ld.lld err.o a.so -pie -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
 
 # ERR:      error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported
 # ERR-NEXT: >>> defined in a.so

>From b5b8ce9561c4d0d1d71e9d85bcfadc34453f8be3 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Wed, 4 Dec 2024 14:37:44 +0300
Subject: [PATCH 08/15] Fix build after #118424

---
 lld/ELF/Arch/AArch64.cpp | 2 +-
 lld/ELF/InputSection.cpp | 2 +-
 lld/ELF/Relocations.cpp  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 87374aab738f8b..9571e0e9566fc3 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -204,7 +204,7 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
     return R_GOT;
   case R_AARCH64_AUTH_LD64_GOT_LO12_NC:
   case R_AARCH64_AUTH_GOT_ADD_LO12_NC:
-    return R_AARCH64_AUTH_GOT;
+    return RE_AARCH64_AUTH_GOT;
   case R_AARCH64_LD64_GOTPAGE_LO15:
     return RE_AARCH64_GOT_PAGE;
   case R_AARCH64_ADR_GOT_PAGE:
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 940cb9d3264173..26dc5c606f57f9 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -783,7 +783,7 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
   case RE_ARM_SBREL:
     return r.sym->getVA(ctx, a) - getARMStaticBase(*r.sym);
   case R_GOT:
-  case R_AARCH64_AUTH_GOT:
+  case RE_AARCH64_AUTH_GOT:
   case R_RELAX_TLS_GD_TO_IE_ABS:
     return r.sym->getGotVA(ctx) + a;
   case RE_LOONGARCH_GOT:
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 77168f09414cdf..9c64688b0b0030 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1090,7 +1090,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
       // Many LoongArch TLS relocs reuse the RE_LOONGARCH_GOT type, in which
       // case the NEEDS_GOT flag shouldn't get set.
       bool needsGotAuth =
-          (expr == R_AARCH64_AUTH_GOT || expr == R_AARCH64_AUTH_GOT_PAGE_PC);
+          (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC);
       uint16_t flags = sym.flags.load(std::memory_order_relaxed);
       if (!(flags & NEEDS_GOT)) {
         sym.setFlags(needsGotAuth ? (NEEDS_GOT | NEEDS_GOT_AUTH) : NEEDS_GOT);

>From 401c1e473bf3f2c0db4d20b9aaec22460fc58bfc Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Wed, 4 Dec 2024 14:39:58 +0300
Subject: [PATCH 09/15] Change reloc codes in tests (see also #118214)

---
 lld/test/ELF/aarch64-got-relocations-pauth.s | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
index 1b01318bf36ab6..63538c3872b8f6 100644
--- a/lld/test/ELF/aarch64-got-relocations-pauth.s
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -15,8 +15,8 @@
 # RUN: llvm-readelf -r -S -x .got -s local | FileCheck %s --check-prefix=LOCAL
 
 # EXTERNAL:      Offset            Info             Type                    Symbol's Value   Symbol's Name + Addend
-# EXTERNAL-NEXT: 0000000000020380  000000010000e201 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0
-# EXTERNAL-NEXT: 0000000000020388  000000020000e201 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0
+# EXTERNAL-NEXT: 0000000000020380  0000000100000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0
+# EXTERNAL-NEXT: 0000000000020388  0000000200000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0
 
 ## Symbol's values for bar and zed are equal since they contain no content (see Inputs/shared.s)
 # LOCAL:         Offset            Info             Type                    Symbol's Value   Symbol's Name + Addend

>From 1078d052219488e519a2ac45ab80fd8fc14c0c0e Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Wed, 4 Dec 2024 23:02:26 +0300
Subject: [PATCH 10/15] Move pauth-specific code from `addGotEntry` to
 `addGotAuthEntry`

---
 lld/ELF/Relocations.cpp | 42 +++++++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 9c64688b0b0030..ad937aa0c8dc50 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -896,26 +896,14 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
 
   // If preemptible, emit a GLOB_DAT relocation.
   if (sym.isPreemptible) {
-    RelType gotRel = ctx.target->gotRel;
-    if (sym.hasFlag(NEEDS_GOT_AUTH)) {
-      assert(ctx.arg.emachine == EM_AARCH64);
-      gotRel = R_AARCH64_AUTH_GLOB_DAT;
-    }
-    ctx.mainPart->relaDyn->addReloc({gotRel, ctx.in.got.get(), off,
+    ctx.mainPart->relaDyn->addReloc({ctx.target->gotRel, ctx.in.got.get(), off,
                                      DynamicReloc::AgainstSymbol, sym, 0,
                                      R_ABS});
     return;
   }
 
   // Otherwise, the value is either a link-time constant or the load base
-  // plus a constant. Signed GOT requires dynamic relocation.
-  if (sym.hasFlag(NEEDS_GOT_AUTH)) {
-    ctx.in.got->getPartition(ctx).relaDyn->addReloc(
-        {R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off,
-         DynamicReloc::AddendOnlyWithTargetVA, sym, 0, R_ABS});
-    return;
-  }
-
+  // plus a constant.
   if (!ctx.arg.isPic || isAbsolute(sym))
     ctx.in.got->addConstant({R_ABS, ctx.target->symbolicRel, off, 0, &sym});
   else
@@ -923,6 +911,24 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
                      ctx.target->symbolicRel);
 }
 
+static void addGotAuthEntry(Ctx &ctx, Symbol &sym) {
+  ctx.in.got->addEntry(sym);
+  uint64_t off = sym.getGotOffset(ctx);
+
+  // If preemptible, emit a GLOB_DAT relocation.
+  if (sym.isPreemptible) {
+    ctx.mainPart->relaDyn->addReloc({R_AARCH64_AUTH_GLOB_DAT, ctx.in.got.get(),
+                                     off, DynamicReloc::AgainstSymbol, sym, 0,
+                                     R_ABS});
+    return;
+  }
+
+  // Signed GOT requires dynamic relocation.
+  ctx.in.got->getPartition(ctx).relaDyn->addReloc(
+      {R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off,
+       DynamicReloc::AddendOnlyWithTargetVA, sym, 0, R_ABS});
+}
+
 static void addTpOffsetGotEntry(Ctx &ctx, Symbol &sym) {
   ctx.in.got->addEntry(sym);
   uint64_t off = sym.getGotOffset(ctx);
@@ -1797,8 +1803,12 @@ void elf::postScanRelocations(Ctx &ctx) {
       return;
     sym.allocateAux(ctx);
 
-    if (flags & NEEDS_GOT)
-      addGotEntry(ctx, sym);
+    if (flags & NEEDS_GOT) {
+      if (flags & NEEDS_GOT_AUTH)
+        addGotAuthEntry(ctx, sym);
+      else
+        addGotEntry(ctx, sym);
+    }
     if (flags & NEEDS_PLT)
       addPltEntry(ctx, *ctx.in.plt, *ctx.in.gotPlt, *ctx.in.relaPlt,
                   ctx.target->pltRel, sym);

>From 2c9a0f7e93a44900fdf7f26bf4478089604cdcde Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Wed, 4 Dec 2024 23:07:57 +0300
Subject: [PATCH 11/15] Add an assertion against unsupported signed irelative

---
 lld/ELF/Relocations.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index ad937aa0c8dc50..8433d5579369ec 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1781,8 +1781,11 @@ static bool handleNonPreemptibleIfunc(Ctx &ctx, Symbol &sym, uint16_t flags) {
     // don't try to call the PLT as if it were an ifunc resolver.
     d.type = STT_FUNC;
 
-    if (flags & NEEDS_GOT)
+    if (flags & NEEDS_GOT) {
+      assert(!(flags & NEEDS_GOT_AUTH) &&
+             "R_AARCH64_AUTH_IRELATIVE is not supported yet");
       addGotEntry(ctx, sym);
+    }
   } else if (flags & NEEDS_GOT) {
     // Redirect GOT accesses to point to the Igot.
     sym.gotInIgot = true;

>From 81e4affbc452d618d356ca0f5fb9877149871196 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Sun, 8 Dec 2024 14:54:19 +0300
Subject: [PATCH 12/15] Address review comments

---
 lld/ELF/Relocations.cpp                      | 23 ++++++++++----------
 lld/ELF/Symbols.h                            |  1 +
 lld/ELF/SyntheticSections.cpp                |  6 +++--
 lld/ELF/SyntheticSections.h                  |  1 +
 lld/test/ELF/aarch64-got-relocations-pauth.s |  9 +-------
 5 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 8433d5579369ec..19570404823b45 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -913,6 +913,7 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
 
 static void addGotAuthEntry(Ctx &ctx, Symbol &sym) {
   ctx.in.got->addEntry(sym);
+  ctx.in.got->addAuthEntry(sym);
   uint64_t off = sym.getGotOffset(ctx);
 
   // If preemptible, emit a GLOB_DAT relocation.
@@ -1095,18 +1096,10 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
     } else if (!sym.isTls() || ctx.arg.emachine != EM_LOONGARCH) {
       // Many LoongArch TLS relocs reuse the RE_LOONGARCH_GOT type, in which
       // case the NEEDS_GOT flag shouldn't get set.
-      bool needsGotAuth =
-          (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC);
-      uint16_t flags = sym.flags.load(std::memory_order_relaxed);
-      if (!(flags & NEEDS_GOT)) {
-        sym.setFlags(needsGotAuth ? (NEEDS_GOT | NEEDS_GOT_AUTH) : NEEDS_GOT);
-      } else if (needsGotAuth != static_cast<bool>(flags & NEEDS_GOT_AUTH)) {
-        auto diag = Err(ctx);
-        diag << "both AUTH and non-AUTH GOT entries for '" << sym.getName()
-             << "' requested, but only one type of GOT entry per symbol is "
-                "supported";
-        printLocation(diag, *sec, sym, offset);
-      }
+      if (expr == RE_AARCH64_AUTH_GOT || expr == RE_AARCH64_AUTH_GOT_PAGE_PC)
+        sym.setFlags(NEEDS_GOT | NEEDS_GOT_AUTH);
+      else
+        sym.setFlags(NEEDS_GOT | NEEDS_GOT_NONAUTH);
     }
   } else if (needsPlt(expr)) {
     sym.setFlags(NEEDS_PLT);
@@ -1807,6 +1800,12 @@ void elf::postScanRelocations(Ctx &ctx) {
     sym.allocateAux(ctx);
 
     if (flags & NEEDS_GOT) {
+      if ((flags & NEEDS_GOT_AUTH) && (flags & NEEDS_GOT_NONAUTH)) {
+        auto diag = Err(ctx);
+        diag << "both AUTH and non-AUTH GOT entries for '" << sym.getName()
+             << "' requested, but only one type of GOT entry per symbol is "
+                "supported";
+      }
       if (flags & NEEDS_GOT_AUTH)
         addGotAuthEntry(ctx, sym);
       else
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index ebc2fcf8e5eeb2..a59faf1037cb2f 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -52,6 +52,7 @@ enum {
   NEEDS_GOT_DTPREL = 1 << 7,
   NEEDS_TLSIE = 1 << 8,
   NEEDS_GOT_AUTH = 1 << 9,
+  NEEDS_GOT_NONAUTH = 1 << 10,
 };
 
 // The base class for real symbol classes.
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 7c79fd5a69025a..baa7a083404fe7 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -668,8 +668,10 @@ void GotSection::addConstant(const Relocation &r) { relocations.push_back(r); }
 void GotSection::addEntry(const Symbol &sym) {
   assert(sym.auxIdx == ctx.symAux.size() - 1);
   ctx.symAux.back().gotIdx = numEntries++;
-  if (sym.hasFlag(NEEDS_GOT_AUTH))
-    authEntries.push_back({(numEntries - 1) * ctx.arg.wordsize, sym.isFunc()});
+}
+
+void GotSection::addAuthEntry(const Symbol &sym) {
+  authEntries.push_back({(numEntries - 1) * ctx.arg.wordsize, sym.isFunc()});
 }
 
 bool GotSection::addTlsDescEntry(const Symbol &sym) {
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 5d21d4e9779d30..9fcee3b481af08 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -112,6 +112,7 @@ class GotSection final : public SyntheticSection {
 
   void addConstant(const Relocation &r);
   void addEntry(const Symbol &sym);
+  void addAuthEntry(const Symbol &sym);
   bool addTlsDescEntry(const Symbol &sym);
   bool addDynTlsEntry(const Symbol &sym);
   bool addTlsIndex();
diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
index 63538c3872b8f6..548c1ccf0de97b 100644
--- a/lld/test/ELF/aarch64-got-relocations-pauth.s
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -79,15 +79,8 @@ _start:
 
 #--- err.s
 # RUN: llvm-mc -filetype=obj -triple=aarch64 err.s -o err.o
-
 # RUN: not ld.lld err.o a.so -pie -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR --implicit-check-not=error:
-
-# ERR:      error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported
-# ERR-NEXT: >>> defined in a.so
-# ERR-NEXT: >>> referenced by err.o:(.text+0x8)
-# ERR:      error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported
-# ERR-NEXT: >>> defined in a.so
-# ERR-NEXT: >>> referenced by err.o:(.text+0xc)
+# ERR: error: both AUTH and non-AUTH GOT entries for 'bar' requested, but only one type of GOT entry per symbol is supported
 
 .globl _start
 _start:

>From afe005357b7da680b5e9ca1b3973a251aea375e9 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Sun, 8 Dec 2024 16:39:03 +0300
Subject: [PATCH 13/15] Do not try to add got entry after emitting error
 diagnostic

---
 lld/ELF/Relocations.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 19570404823b45..07cbdb7806fde1 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1805,6 +1805,7 @@ void elf::postScanRelocations(Ctx &ctx) {
         diag << "both AUTH and non-AUTH GOT entries for '" << sym.getName()
              << "' requested, but only one type of GOT entry per symbol is "
                 "supported";
+        return;
       }
       if (flags & NEEDS_GOT_AUTH)
         addGotAuthEntry(ctx, sym);

>From 683249f8e11bf24c9d60f605ac5eaed7e37c6dc1 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Sun, 15 Dec 2024 18:49:26 +0300
Subject: [PATCH 14/15] Do not use terms 'external' and 'local'

---
 lld/test/ELF/aarch64-got-relocations-pauth.s | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
index 548c1ccf0de97b..a577e81ad0d035 100644
--- a/lld/test/ELF/aarch64-got-relocations-pauth.s
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -8,11 +8,11 @@
 #--- ok.s
 # RUN: llvm-mc -filetype=obj -triple=aarch64 ok.s -o ok.o
 
-# RUN: ld.lld ok.o a.so -pie -o external
-# RUN: llvm-readelf -r -S -x .got external | FileCheck %s --check-prefix=EXTERNAL
+# RUN: ld.lld ok.o a.so -pie -o ok1
+# RUN: llvm-readelf -r -S -x .got ok1 | FileCheck %s --check-prefix=EXTERNAL
 
-# RUN: ld.lld ok.o a.o -pie -o local
-# RUN: llvm-readelf -r -S -x .got -s local | FileCheck %s --check-prefix=LOCAL
+# RUN: ld.lld ok.o a.o -pie -o ok2
+# RUN: llvm-readelf -r -S -x .got -s ok2 | FileCheck %s --check-prefix=LOCAL
 
 # EXTERNAL:      Offset            Info             Type                    Symbol's Value   Symbol's Name + Addend
 # EXTERNAL-NEXT: 0000000000020380  0000000100000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0
@@ -42,7 +42,7 @@
 ##                                                           ^^
 ##                                                           0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
 
-# RUN: llvm-objdump -d external | FileCheck %s --check-prefix=EXTERNAL-ASM
+# RUN: llvm-objdump -d ok1 | FileCheck %s --check-prefix=EXTERNAL-ASM
 
 # EXTERNAL-ASM:      <_start>:
 # EXTERNAL-ASM-NEXT: adrp x0, 0x20000
@@ -54,7 +54,7 @@
 # EXTERNAL-ASM-NEXT: adrp x1, 0x20000
 # EXTERNAL-ASM-NEXT: add  x1, x1, #0x388
 
-# RUN: llvm-objdump -d local | FileCheck %s --check-prefix=LOCAL-ASM
+# RUN: llvm-objdump -d ok2 | FileCheck %s --check-prefix=LOCAL-ASM
 
 # LOCAL-ASM:         <_start>:
 # LOCAL-ASM-NEXT:    adrp x0, 0x20000

>From 03f9115ae4f3ea45edce60d2aec020bf76d4c2ff Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Mon, 16 Dec 2024 10:39:23 +0300
Subject: [PATCH 15/15] Fix check prefixes

---
 lld/test/ELF/aarch64-got-relocations-pauth.s | 78 ++++++++++----------
 1 file changed, 39 insertions(+), 39 deletions(-)

diff --git a/lld/test/ELF/aarch64-got-relocations-pauth.s b/lld/test/ELF/aarch64-got-relocations-pauth.s
index a577e81ad0d035..985ab302259ea3 100644
--- a/lld/test/ELF/aarch64-got-relocations-pauth.s
+++ b/lld/test/ELF/aarch64-got-relocations-pauth.s
@@ -9,62 +9,62 @@
 # RUN: llvm-mc -filetype=obj -triple=aarch64 ok.s -o ok.o
 
 # RUN: ld.lld ok.o a.so -pie -o ok1
-# RUN: llvm-readelf -r -S -x .got ok1 | FileCheck %s --check-prefix=EXTERNAL
+# RUN: llvm-readelf -r -S -x .got ok1 | FileCheck %s --check-prefix=OK1
 
 # RUN: ld.lld ok.o a.o -pie -o ok2
-# RUN: llvm-readelf -r -S -x .got -s ok2 | FileCheck %s --check-prefix=LOCAL
+# RUN: llvm-readelf -r -S -x .got -s ok2 | FileCheck %s --check-prefix=OK2
 
-# EXTERNAL:      Offset            Info             Type                    Symbol's Value   Symbol's Name + Addend
-# EXTERNAL-NEXT: 0000000000020380  0000000100000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0
-# EXTERNAL-NEXT: 0000000000020388  0000000200000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0
+# OK1:      Offset            Info             Type                    Symbol's Value   Symbol's Name + Addend
+# OK1-NEXT: 0000000000020380  0000000100000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 bar + 0
+# OK1-NEXT: 0000000000020388  0000000200000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 zed + 0
 
 ## Symbol's values for bar and zed are equal since they contain no content (see Inputs/shared.s)
-# LOCAL:         Offset            Info             Type                    Symbol's Value   Symbol's Name + Addend
-# LOCAL-NEXT:    0000000000020320  0000000000000411 R_AARCH64_AUTH_RELATIVE 10260
-# LOCAL-NEXT:    0000000000020328  0000000000000411 R_AARCH64_AUTH_RELATIVE 10260
+# OK2:         Offset            Info             Type                    Symbol's Value   Symbol's Name + Addend
+# OK2-NEXT:    0000000000020320  0000000000000411 R_AARCH64_AUTH_RELATIVE 10260
+# OK2-NEXT:    0000000000020328  0000000000000411 R_AARCH64_AUTH_RELATIVE 10260
 
-# EXTERNAL:      Hex dump of section '.got':
-# EXTERNAL-NEXT: 0x00020380 00000000 00000080 00000000 000000a0
+# OK1:      Hex dump of section '.got':
+# OK1-NEXT: 0x00020380 00000000 00000080 00000000 000000a0
 ##                                         ^^
 ##                                         0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
 ##                                                           ^^
 ##                                                           0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
 
-# LOCAL: Symbol table '.symtab' contains {{.*}} entries:
-# LOCAL:    Num:    Value          Size Type    Bind   Vis       Ndx Name
-# LOCAL:         0000000000010260     0 FUNC    GLOBAL DEFAULT     6 bar
-# LOCAL:         0000000000010260     0 NOTYPE  GLOBAL DEFAULT     6 zed
+# OK2: Symbol table '.symtab' contains {{.*}} entries:
+# OK2:    Num:    Value          Size Type    Bind   Vis       Ndx Name
+# OK2:         0000000000010260     0 FUNC    GLOBAL DEFAULT     6 bar
+# OK2:         0000000000010260     0 NOTYPE  GLOBAL DEFAULT     6 zed
 
-# LOCAL:         Hex dump of section '.got':
-# LOCAL-NEXT:    0x00020320 00000000 00000080 00000000 000000a0
+# OK2:         Hex dump of section '.got':
+# OK2-NEXT:    0x00020320 00000000 00000080 00000000 000000a0
 ##                                         ^^
 ##                                         0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
 ##                                                           ^^
 ##                                                           0b10100000 bit 63 address diversity = true, bits 61..60 key = DA
 
-# RUN: llvm-objdump -d ok1 | FileCheck %s --check-prefix=EXTERNAL-ASM
-
-# EXTERNAL-ASM:      <_start>:
-# EXTERNAL-ASM-NEXT: adrp x0, 0x20000
-# EXTERNAL-ASM-NEXT: ldr  x0, [x0, #0x380]
-# EXTERNAL-ASM-NEXT: adrp x1, 0x20000
-# EXTERNAL-ASM-NEXT: add  x1, x1, #0x380
-# EXTERNAL-ASM-NEXT: adrp x0, 0x20000
-# EXTERNAL-ASM-NEXT: ldr  x0, [x0, #0x388]
-# EXTERNAL-ASM-NEXT: adrp x1, 0x20000
-# EXTERNAL-ASM-NEXT: add  x1, x1, #0x388
-
-# RUN: llvm-objdump -d ok2 | FileCheck %s --check-prefix=LOCAL-ASM
-
-# LOCAL-ASM:         <_start>:
-# LOCAL-ASM-NEXT:    adrp x0, 0x20000
-# LOCAL-ASM-NEXT:    ldr  x0, [x0, #0x320]
-# LOCAL-ASM-NEXT:    adrp x1, 0x20000
-# LOCAL-ASM-NEXT:    add  x1, x1, #0x320
-# LOCAL-ASM-NEXT:    adrp x0, 0x20000
-# LOCAL-ASM-NEXT:    ldr  x0, [x0, #0x328]
-# LOCAL-ASM-NEXT:    adrp x1, 0x20000
-# LOCAL-ASM-NEXT:    add  x1, x1, #0x328
+# RUN: llvm-objdump -d ok1 | FileCheck %s --check-prefix=OK1-ASM
+
+# OK1-ASM:      <_start>:
+# OK1-ASM-NEXT: adrp x0, 0x20000
+# OK1-ASM-NEXT: ldr  x0, [x0, #0x380]
+# OK1-ASM-NEXT: adrp x1, 0x20000
+# OK1-ASM-NEXT: add  x1, x1, #0x380
+# OK1-ASM-NEXT: adrp x0, 0x20000
+# OK1-ASM-NEXT: ldr  x0, [x0, #0x388]
+# OK1-ASM-NEXT: adrp x1, 0x20000
+# OK1-ASM-NEXT: add  x1, x1, #0x388
+
+# RUN: llvm-objdump -d ok2 | FileCheck %s --check-prefix=OK2-ASM
+
+# OK2-ASM:         <_start>:
+# OK2-ASM-NEXT:    adrp x0, 0x20000
+# OK2-ASM-NEXT:    ldr  x0, [x0, #0x320]
+# OK2-ASM-NEXT:    adrp x1, 0x20000
+# OK2-ASM-NEXT:    add  x1, x1, #0x320
+# OK2-ASM-NEXT:    adrp x0, 0x20000
+# OK2-ASM-NEXT:    ldr  x0, [x0, #0x328]
+# OK2-ASM-NEXT:    adrp x1, 0x20000
+# OK2-ASM-NEXT:    add  x1, x1, #0x328
 
 .globl _start
 _start:



More information about the llvm-commits mailing list