[lld] [lld][AArch64][ELF][PAC] Support AUTH relocations and AUTH ELF marking (PR #72714)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 19 17:37:15 PST 2024


https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/72714

>From c493d78e6c482bb530189de05b79e7082a224fab Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 28 Sep 2023 03:14:35 +0300
Subject: [PATCH 01/13] [lld][AArch64][ELF][PAC] Support AUTH relocations and
 AUTH ELF marking

This patch adds lld support for:

- Dynamic R_AARCH64_AUTH_* relocations (including RELR compressed AUTH
  relocations) as described here:
  https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#auth-variant-dynamic-relocations

- .note.AARCH64-PAUTH-ABI-tag section as defined here
  https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#elf-marking

Co-authored-by: Peter Collingbourne <peter at pcc.me.uk>
---
 lld/ELF/Arch/AArch64.cpp             |   5 +
 lld/ELF/Config.h                     |   4 +
 lld/ELF/Driver.cpp                   |  57 +++++++++-
 lld/ELF/InputFiles.cpp               |  44 ++++++++
 lld/ELF/InputFiles.h                 |   1 +
 lld/ELF/Relocations.cpp              |  26 +++++
 lld/ELF/SyntheticSections.cpp        |  44 ++++++--
 lld/ELF/SyntheticSections.h          |  19 +++-
 lld/ELF/Writer.cpp                   |  17 +++
 lld/test/ELF/aarch64-feature-pauth.s |  83 ++++++++++++++
 lld/test/ELF/aarch64-ptrauth.s       | 156 +++++++++++++++++++++++++++
 11 files changed, 445 insertions(+), 11 deletions(-)
 create mode 100644 lld/test/ELF/aarch64-feature-pauth.s
 create mode 100644 lld/test/ELF/aarch64-ptrauth.s

diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 048f0ec30ebd28..6828d3f57c10e8 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -112,6 +112,7 @@ RelExpr AArch64::getRelExpr(RelType type, const Symbol &s,
   case R_AARCH64_MOVW_UABS_G2:
   case R_AARCH64_MOVW_UABS_G2_NC:
   case R_AARCH64_MOVW_UABS_G3:
+  case R_AARCH64_AUTH_ABS64:
     return R_ABS;
   case R_AARCH64_TLSDESC_ADR_PAGE21:
     return R_AARCH64_TLSDESC_PAGE;
@@ -395,6 +396,10 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
   case R_AARCH64_PREL64:
     write64(loc, val);
     break;
+  case R_AARCH64_AUTH_ABS64:
+    checkIntUInt(loc, val, 32, rel);
+    write32(loc, val);
+    break;
   case R_AARCH64_ADD_ABS_LO12_NC:
     or32AArch64Imm(loc, val);
     break;
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 56229334f9a44a..1b633a79842769 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -187,6 +187,7 @@ struct Config {
   llvm::StringRef cmseOutputLib;
   StringRef zBtiReport = "none";
   StringRef zCetReport = "none";
+  StringRef zPauthReport = "none";
   llvm::StringRef ltoBasicBlockSections;
   std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
   llvm::StringRef thinLTOPrefixReplaceOld;
@@ -275,6 +276,7 @@ struct Config {
   bool relocatable;
   bool relrGlibc = false;
   bool relrPackDynRelocs = false;
+  bool relrPackAuthDynRelocs = false;
   llvm::DenseSet<llvm::StringRef> saveTempsArgs;
   llvm::SmallVector<std::pair<llvm::GlobPattern, uint32_t>, 0> shuffleSections;
   bool singleRoRx;
@@ -492,6 +494,8 @@ struct Ctx {
   void reset();
 
   llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &);
+
+  SmallVector<uint8_t, 0> aarch64PauthAbiTag;
 };
 
 LLVM_LIBRARY_VISIBILITY extern Ctx ctx;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 6bef09eeca015a..4e8e9eb86ecf77 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -65,6 +65,7 @@
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
+#include <algorithm>
 #include <cstdlib>
 #include <tuple>
 #include <utility>
@@ -459,6 +460,8 @@ static void checkOptions() {
       error("-z force-bti only supported on AArch64");
     if (config->zBtiReport != "none")
       error("-z bti-report only supported on AArch64");
+    if (config->zPauthReport != "none")
+      error("-z pauth-report only supported on AArch64");
   }
 
   if (config->emachine != EM_386 && config->emachine != EM_X86_64 &&
@@ -558,6 +561,7 @@ constexpr const char *knownZFlags[] = {
     "nognustack",
     "nokeep-text-section-prefix",
     "nopack-relative-relocs",
+    "nopack-relative-auth-relocs",
     "norelro",
     "noseparate-code",
     "nostart-stop-gc",
@@ -566,6 +570,7 @@ constexpr const char *knownZFlags[] = {
     "origin",
     "pac-plt",
     "pack-relative-relocs",
+    "pack-relative-auth-relocs",
     "rel",
     "rela",
     "relro",
@@ -583,7 +588,7 @@ constexpr const char *knownZFlags[] = {
 static bool isKnownZFlag(StringRef s) {
   return llvm::is_contained(knownZFlags, s) ||
          s.starts_with("common-page-size=") || s.starts_with("bti-report=") ||
-         s.starts_with("cet-report=") ||
+         s.starts_with("cet-report=") || s.starts_with("pauth-report=") ||
          s.starts_with("dead-reloc-in-nonalloc=") ||
          s.starts_with("max-page-size=") || s.starts_with("stack-size=") ||
          s.starts_with("start-stop-visibility=");
@@ -1514,7 +1519,8 @@ static void readConfigs(opt::InputArgList &args) {
   }
 
   auto reports = {std::make_pair("bti-report", &config->zBtiReport),
-                  std::make_pair("cet-report", &config->zCetReport)};
+                  std::make_pair("cet-report", &config->zCetReport),
+                  std::make_pair("pauth-report", &config->zPauthReport)};
   for (opt::Arg *arg : args.filtered(OPT_z)) {
     std::pair<StringRef, StringRef> option =
         StringRef(arg->getValue()).split('=');
@@ -1671,6 +1677,9 @@ static void readConfigs(opt::InputArgList &args) {
         getPackDynRelocs(args);
   }
 
+  config->relrPackAuthDynRelocs = getZFlag(
+      args, "pack-relative-auth-relocs", "nopack-relative-auth-relocs", false);
+
   if (auto *arg = args.getLastArg(OPT_symbol_ordering_file)){
     if (args.hasArg(OPT_call_graph_ordering_file))
       error("--symbol-ordering-file and --call-graph-order-file "
@@ -2639,6 +2648,47 @@ static uint32_t getAndFeatures() {
   return ret;
 }
 
+static void getAarch64PauthInfo() {
+  if (ctx.objectFiles.empty())
+    return;
+
+  auto NonEmptyIt = std::find_if(
+      ctx.objectFiles.begin(), ctx.objectFiles.end(),
+      [](const ELFFileBase *f) { return !f->aarch64PauthAbiTag.empty(); });
+  if (NonEmptyIt == ctx.objectFiles.end())
+    return;
+
+  ctx.aarch64PauthAbiTag = (*NonEmptyIt)->aarch64PauthAbiTag;
+  StringRef F1 = (*NonEmptyIt)->getName();
+  for (ELFFileBase *F : ArrayRef(ctx.objectFiles)) {
+    StringRef F2 = F->getName();
+    const SmallVector<uint8_t, 0> &D1 = ctx.aarch64PauthAbiTag;
+    const SmallVector<uint8_t, 0> &D2 = F->aarch64PauthAbiTag;
+    if (D1.empty() != D2.empty()) {
+      auto Helper = [](StringRef Report, const Twine &Msg) {
+        if (Report == "warning")
+          warn(Msg);
+        else if (Report == "error")
+          error(Msg);
+      };
+
+      Helper(config->zPauthReport,
+             (D1.empty() ? F1.str() : F2.str()) +
+                 " has no AArch64 PAuth compatibility info while " +
+                 (D1.empty() ? F2.str() : F1.str()) +
+                 " has one; either all or no input files must have it");
+    }
+
+    if (!D1.empty() && !D2.empty() &&
+        !std::equal(D1.begin(), D1.end(), D2.begin(), D2.end()))
+      errorOrWarn(
+          "incompatible values of AArch64 PAuth compatibility info found"
+          "\n" +
+          F1 + ": 0x" + toHex(ArrayRef(D1.data(), D1.size())) + "\n" + F2 +
+          ": 0x" + toHex(ArrayRef(D2.data(), D2.size())));
+  }
+}
+
 static void initSectionsAndLocalSyms(ELFFileBase *file, bool ignoreComdats) {
   switch (file->ekind) {
   case ELF32LEKind:
@@ -2976,6 +3026,9 @@ void LinkerDriver::link(opt::InputArgList &args) {
   // contain a hint to tweak linker's and loader's behaviors.
   config->andFeatures = getAndFeatures();
 
+  if (config->emachine == EM_AARCH64)
+    getAarch64PauthInfo();
+
   // The Target instance handles target-specific stuff, such as applying
   // relocations or writing a PLT section. It also contains target-dependent
   // values such as a default image base address.
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index cc2c5916e05c22..44c8050f2c967a 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -962,6 +962,44 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) {
   return featuresSet;
 }
 
+// Extract compatibility info for aarch64 pointer authentication from the
+// .note.AARCH64-PAUTH-ABI-tag section and write it to the corresponding ObjFile
+// field. See the following ABI documentation:
+// https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#elf-marking
+template <class ELFT>
+static void readAArch64PauthAbiTag(const InputSection &sec, ObjFile<ELFT> &f) {
+  using Elf_Nhdr = typename ELFT::Nhdr;
+  using Elf_Note = typename ELFT::Note;
+  ArrayRef<uint8_t> data = sec.content();
+  auto reportError = [&](const Twine &msg) {
+    errorOrWarn(toString(sec.file) + ":(" + sec.name + "): " + msg);
+  };
+
+  auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());
+  if (data.size() < sizeof(Elf_Nhdr) ||
+      data.size() < nhdr->getSize(sec.addralign)) {
+    reportError("section is too short");
+    return;
+  }
+
+  Elf_Note note(*nhdr);
+  if (nhdr->n_type != NT_ARM_TYPE_PAUTH_ABI_TAG)
+    reportError("invalid type field value " + Twine(nhdr->n_type) + " (" +
+                Twine(NT_ARM_TYPE_PAUTH_ABI_TAG) + " expected)");
+  if (note.getName() != "ARM")
+    reportError("invalid name field value " + note.getName() +
+                " (ARM expected)");
+
+  ArrayRef<uint8_t> desc = note.getDesc(sec.addralign);
+  if (desc.size() < 16) {
+    reportError("too short AArch64 PAuth compatibility info "
+                "(at least 16 bytes expected)");
+    return;
+  }
+
+  f.aarch64PauthAbiTag = SmallVector<uint8_t, 0>(iterator_range(desc));
+}
+
 template <class ELFT>
 InputSectionBase *ObjFile<ELFT>::getRelocTarget(uint32_t idx,
                                                 const Elf_Shdr &sec,
@@ -1020,6 +1058,12 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(uint32_t idx,
       return &InputSection::discarded;
     }
 
+    if (config->emachine == EM_AARCH64 &&
+        name == ".note.AARCH64-PAUTH-ABI-tag") {
+      readAArch64PauthAbiTag<ELFT>(InputSection(*this, sec, name), *this);
+      return &InputSection::discarded;
+    }
+
     // Split stacks is a feature to support a discontiguous stack,
     // commonly used in the programming language Go. For the details,
     // see https://gcc.gnu.org/wiki/SplitStacks. An object file compiled
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index ab98d78fcf1455..6a74ba7fb20998 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -218,6 +218,7 @@ class ELFFileBase : public InputFile {
 public:
   uint32_t andFeatures = 0;
   bool hasCommonSyms = false;
+  SmallVector<uint8_t, 0> aarch64PauthAbiTag;
 };
 
 // .o file.
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index fe3d7f419e84aa..5b5e6b154d52f4 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1444,6 +1444,32 @@ template <class ELFT, class RelTy> void RelocationScanner::scanOne(RelTy *&i) {
     }
   }
 
+  if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
+    // Assume relocations from relocatable objects are RELA.
+    assert(RelTy::IsRela);
+    std::lock_guard<std::mutex> lock(relocMutex);
+    // For a preemptible symbol, we can't use a relative relocation. For an
+    // undefined symbol, we can't compute offset at link-time and use a relative
+    // relocation. Use a symbolic relocation instead.
+    Partition &part = sec->getPartition();
+    if (sym.isPreemptible || sym.isUndefined()) {
+      part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
+    } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0 &&
+               isInt<32>(sym.getVA(addend))) {
+      // Implicit addend is below 32-bits so we can use the compressed
+      // relative relocation section. The R_AARCH64_AUTH_RELATIVE
+      // has a smaller addend fielf as bits [63:32] encode the signing-schema.
+      sec->addReloc({expr, type, offset, addend, &sym});
+      part.relrAuthDyn->relocsVec[parallel::getThreadIndex()].push_back(
+          {sec, offset});
+    } else {
+      part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
+                              DynamicReloc::AddendOnlyWithTargetVA, sym, addend,
+                              R_ABS});
+    }
+    return;
+  }
+
   // If the relocation does not emit a GOT or GOTPLT entry but its computation
   // uses their addresses, we need GOT or GOTPLT to be created.
   //
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 2b32eb3a0fe355..fa7589806a7b5b 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -331,6 +331,29 @@ void GnuPropertySection::writeTo(uint8_t *buf) {
 
 size_t GnuPropertySection::getSize() const { return config->is64 ? 32 : 28; }
 
+AArch64PauthAbiTag::AArch64PauthAbiTag()
+    : SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE,
+                       config->wordsize, ".note.AARCH64-PAUTH-ABI-tag") {}
+
+bool AArch64PauthAbiTag::isNeeded() const {
+  return !ctx.aarch64PauthAbiTag.empty();
+}
+
+void AArch64PauthAbiTag::writeTo(uint8_t *buf) {
+  const SmallVector<uint8_t, 0> &data = ctx.aarch64PauthAbiTag;
+  write32(buf, 4);                             // Name size
+  write32(buf + 4, data.size());               // Content size
+  write32(buf + 8, NT_ARM_TYPE_PAUTH_ABI_TAG); // Type
+  memcpy(buf + 12, "ARM", 4);                  // Name string
+  memcpy(buf + 16, data.data(), data.size());
+  memset(buf + 16 + data.size(), 0, getSize() - 16 - data.size()); // Padding
+}
+
+size_t AArch64PauthAbiTag::getSize() const {
+  return alignToPowerOf2(16 + ctx.aarch64PauthAbiTag.size(),
+                         config->is64 ? 8 : 4);
+}
+
 BuildIdSection::BuildIdSection()
     : SyntheticSection(SHF_ALLOC, SHT_NOTE, 4, ".note.gnu.build-id"),
       hashSize(getHashSize()) {}
@@ -1406,6 +1429,12 @@ DynamicSection<ELFT>::computeContents() {
     addInt(config->useAndroidRelrTags ? DT_ANDROID_RELRENT : DT_RELRENT,
            sizeof(Elf_Relr));
   }
+  if (part.relrAuthDyn && part.relrAuthDyn->getParent() &&
+      !part.relrAuthDyn->relocs.empty()) {
+    addInSec(DT_AARCH64_AUTH_RELR, *part.relrAuthDyn);
+    addInt(DT_AARCH64_AUTH_RELRSZ, part.relrAuthDyn->getParent()->size);
+    addInt(DT_AARCH64_AUTH_RELRENT, sizeof(Elf_Relr));
+  }
   // .rel[a].plt section usually consists of two parts, containing plt and
   // iplt relocations. It is possible to have only iplt relocations in the
   // output. In that case relaPlt is empty and have zero offset, the same offset
@@ -1717,10 +1746,13 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *buf) {
   }
 }
 
-RelrBaseSection::RelrBaseSection(unsigned concurrency)
-    : SyntheticSection(SHF_ALLOC,
-                       config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR,
-                       config->wordsize, ".relr.dyn"),
+RelrBaseSection::RelrBaseSection(unsigned concurrency, bool isAArch64Auth)
+    : SyntheticSection(
+          SHF_ALLOC,
+          isAArch64Auth
+              ? SHT_AARCH64_AUTH_RELR
+              : (config->useAndroidRelrTags ? SHT_ANDROID_RELR : SHT_RELR),
+          config->wordsize, isAArch64Auth ? ".relr.auth.dyn" : ".relr.dyn"),
       relocsVec(concurrency) {}
 
 void RelrBaseSection::mergeRels() {
@@ -1988,8 +2020,8 @@ bool AndroidPackedRelocationSection<ELFT>::updateAllocSize() {
 }
 
 template <class ELFT>
-RelrSection<ELFT>::RelrSection(unsigned concurrency)
-    : RelrBaseSection(concurrency) {
+RelrSection<ELFT>::RelrSection(unsigned concurrency, bool isAArch64Auth)
+    : RelrBaseSection(concurrency, isAArch64Auth) {
   this->entsize = config->wordsize;
 }
 
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 3a9f4ba886f6bb..d183a547c68205 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -144,6 +144,16 @@ class GnuPropertySection final : public SyntheticSection {
   size_t getSize() const override;
 };
 
+// .note.AARCH64-PAUTH-ABI-tag section. See
+// https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#elf-marking
+class AArch64PauthAbiTag final : public SyntheticSection {
+public:
+  AArch64PauthAbiTag();
+  void writeTo(uint8_t *buf) override;
+  size_t getSize() const override;
+  bool isNeeded() const override;
+};
+
 // .note.gnu.build-id section.
 class BuildIdSection : public SyntheticSection {
   // First 16 bytes are a header.
@@ -543,7 +553,8 @@ class RelocationBaseSection : public SyntheticSection {
   static bool classof(const SectionBase *d) {
     return SyntheticSection::classof(d) &&
            (d->type == llvm::ELF::SHT_RELA || d->type == llvm::ELF::SHT_REL ||
-            d->type == llvm::ELF::SHT_RELR);
+            d->type == llvm::ELF::SHT_RELR ||
+            d->type == llvm::ELF::SHT_AARCH64_AUTH_RELR);
   }
   int32_t dynamicTag, sizeDynamicTag;
   SmallVector<DynamicReloc, 0> relocs;
@@ -599,7 +610,7 @@ struct RelativeReloc {
 
 class RelrBaseSection : public SyntheticSection {
 public:
-  RelrBaseSection(unsigned concurrency);
+  RelrBaseSection(unsigned concurrency, bool isAArch64Auth = false);
   void mergeRels();
   bool isNeeded() const override {
     return !relocs.empty() ||
@@ -617,7 +628,7 @@ template <class ELFT> class RelrSection final : public RelrBaseSection {
   using Elf_Relr = typename ELFT::Relr;
 
 public:
-  RelrSection(unsigned concurrency);
+  RelrSection(unsigned concurrency, bool isAArch64Auth = false);
 
   bool updateAllocSize() override;
   size_t getSize() const override { return relrRelocs.size() * this->entsize; }
@@ -1319,6 +1330,7 @@ struct Partition {
   std::unique_ptr<PackageMetadataNote> packageMetadataNote;
   std::unique_ptr<RelocationBaseSection> relaDyn;
   std::unique_ptr<RelrBaseSection> relrDyn;
+  std::unique_ptr<RelrBaseSection> relrAuthDyn;
   std::unique_ptr<VersionDefinitionSection> verDef;
   std::unique_ptr<SyntheticSection> verNeed;
   std::unique_ptr<VersionTableSection> verSym;
@@ -1363,6 +1375,7 @@ struct InStruct {
   std::unique_ptr<StringTableSection> strTab;
   std::unique_ptr<SymbolTableBaseSection> symTab;
   std::unique_ptr<SymtabShndxSection> symTabShndx;
+  std::unique_ptr<AArch64PauthAbiTag> aarch64PauthAbiTag;
 
   void reset();
 };
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index a84e4864ab0e5a..f1b569daada663 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -445,6 +445,12 @@ template <class ELFT> void elf::createSyntheticSections() {
       add(*part.relrDyn);
     }
 
+    if (config->relrPackAuthDynRelocs) {
+      part.relrAuthDyn = std::make_unique<RelrSection<ELFT>>(
+          threadCount, /*isAArch64Auth=*/true);
+      add(*part.relrAuthDyn);
+    }
+
     if (!config->relocatable) {
       if (config->ehFrameHdr) {
         part.ehFrameHdr = std::make_unique<EhFrameHeader>();
@@ -566,6 +572,11 @@ template <class ELFT> void elf::createSyntheticSections() {
   if (config->andFeatures)
     add(*make<GnuPropertySection>());
 
+  if (!ctx.aarch64PauthAbiTag.empty()) {
+    in.aarch64PauthAbiTag = std::make_unique<AArch64PauthAbiTag>();
+    add(*in.aarch64PauthAbiTag);
+  }
+
   // .note.GNU-stack is always added when we are creating a re-linkable
   // object file. Other linkers are using the presence of this marker
   // section to control the executable-ness of the stack area, but that
@@ -1725,6 +1736,8 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
       changed |= part.relaDyn->updateAllocSize();
       if (part.relrDyn)
         changed |= part.relrDyn->updateAllocSize();
+      if (part.relrAuthDyn)
+        changed |= part.relrAuthDyn->updateAllocSize();
       if (part.memtagDescriptors)
         changed |= part.memtagDescriptors->updateAllocSize();
     }
@@ -2179,6 +2192,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
         part.relrDyn->mergeRels();
         finalizeSynthetic(part.relrDyn.get());
       }
+      if (part.relrAuthDyn) {
+        part.relrAuthDyn->mergeRels();
+        finalizeSynthetic(part.relrAuthDyn.get());
+      }
 
       finalizeSynthetic(part.dynSymTab.get());
       finalizeSynthetic(part.gnuHashTab.get());
diff --git a/lld/test/ELF/aarch64-feature-pauth.s b/lld/test/ELF/aarch64-feature-pauth.s
new file mode 100644
index 00000000000000..0520b2f28631e1
--- /dev/null
+++ b/lld/test/ELF/aarch64-feature-pauth.s
@@ -0,0 +1,83 @@
+# REQUIRES: aarch64
+
+# RUN: rm -rf %t && split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag1.s -o tag11.o
+# RUN: cp tag11.o tag12.o
+# RUN: ld.lld -shared tag11.o tag12.o -o tagok.so
+# RUN: llvm-readelf -n tagok.so | FileCheck --check-prefix OK %s
+
+# OK: AArch64 PAuth ABI tag: platform 0x2a, version 0x1
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag2.s -o tag2.o
+# RUN: not ld.lld tag11.o tag12.o tag2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR1 %s
+
+# ERR1: error: incompatible values of AArch64 PAuth compatibility info found
+# ERR1: {{.*}}: 0x2A000000000000000{{1|2}}00000000000000
+# ERR1: {{.*}}: 0x2A000000000000000{{1|2}}00000000000000
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-errs.s -o errs.o
+# RUN: not ld.lld errs.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR2 %s
+
+# ERR2:      error: {{.*}}: invalid type field value 42 (1 expected)
+# ERR2-NEXT: error: {{.*}}: invalid name field value XXX (ARM expected)
+# ERR2-NEXT: error: {{.*}}: too short AArch64 PAuth compatibility info (at least 16 bytes expected)
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-short.s -o short.o
+# RUN: not ld.lld short.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR3 %s
+
+# ERR3: error: {{.*}}: section is too short
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu no-info.s -o noinfo1.o
+# RUN: cp noinfo1.o noinfo2.o
+# RUN: not ld.lld -z pauth-report=error tag11.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR4 %s
+# RUN: ld.lld -z pauth-report=warning tag11.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix WARN %s
+# RUN: ld.lld -z pauth-report=none tag11.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix NONE %s
+
+# ERR4:      error: {{.*}}noinfo1.o has no AArch64 PAuth compatibility info while {{.*}}tag11.o has one; either all or no input files must have it
+# ERR4-NEXT: error: {{.*}}noinfo2.o has no AArch64 PAuth compatibility info while {{.*}}tag11.o has one; either all or no input files must have it
+# WARN:      warning: {{.*}}noinfo1.o has no AArch64 PAuth compatibility info while {{.*}}tag11.o has one; either all or no input files must have it
+# WARN-NEXT: warning: {{.*}}noinfo2.o has no AArch64 PAuth compatibility info while {{.*}}tag11.o has one; either all or no input files must have it
+# NONE-NOT:  {{.*}} has no AArch64 PAuth compatibility info while {{.*}} has one; either all or no input files must have it
+
+#--- abi-tag-short.s
+
+.section ".note.AARCH64-PAUTH-ABI-tag", "a"
+.long 4
+.long 8
+
+#--- abi-tag-errs.s
+
+.section ".note.AARCH64-PAUTH-ABI-tag", "a"
+.long 4
+.long 8
+.long 42
+.asciz "XXX"
+
+.quad 42
+
+#--- abi-tag1.s
+
+.section ".note.AARCH64-PAUTH-ABI-tag", "a"
+.long 4
+.long 16
+.long 1
+.asciz "ARM"
+
+.quad 42         // platform
+.quad 1          // version
+
+#--- abi-tag2.s
+
+.section ".note.AARCH64-PAUTH-ABI-tag", "a"
+.long 4
+.long 16
+.long 1
+.asciz "ARM"
+
+.quad 42         // platform
+.quad 2          // version
+
+#--- no-info.s
+
+.section ".test", "a"
diff --git a/lld/test/ELF/aarch64-ptrauth.s b/lld/test/ELF/aarch64-ptrauth.s
new file mode 100644
index 00000000000000..db946fc4c3e55c
--- /dev/null
+++ b/lld/test/ELF/aarch64-ptrauth.s
@@ -0,0 +1,156 @@
+// REQUIRES: aarch64
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared2.s -o %t.so.o
+// RUN: ld.lld -shared %t.so.o -soname=so -o %t.so
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: ld.lld -pie -z nopack-relative-auth-relocs %t.o %t.so -o %t2
+// RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=UNPACKED %s
+
+// UNPACKED:          Section ({{.+}}) .rela.dyn {
+// UNPACKED-NEXT:       0x30680 R_AARCH64_AUTH_RELATIVE - 0x1
+// UNPACKED-NEXT:       0x30688 R_AARCH64_AUTH_RELATIVE - 0x2
+// UNPACKED-NEXT:       0x30690 R_AARCH64_AUTH_RELATIVE - 0x3
+// UNPACKED-NEXT:       0x30698 R_AARCH64_AUTH_RELATIVE - 0x4
+// UNPACKED-NEXT:       0x306A0 R_AARCH64_AUTH_RELATIVE - 0x5
+// UNPACKED-NEXT:       0x306A8 R_AARCH64_AUTH_RELATIVE - 0x6
+// UNPACKED-NEXT:       0x306B0 R_AARCH64_AUTH_RELATIVE - 0x7
+// UNPACKED-NEXT:       0x306B8 R_AARCH64_AUTH_RELATIVE - 0x8
+// UNPACKED-NEXT:       0x306C8 R_AARCH64_AUTH_RELATIVE - 0x1
+// UNPACKED-NEXT:       0x306D0 R_AARCH64_AUTH_RELATIVE - 0x2
+// UNPACKED-NEXT:       0x306D8 R_AARCH64_AUTH_RELATIVE - 0x3
+// UNPACKED-NEXT:       0x306E0 R_AARCH64_AUTH_RELATIVE - 0x4
+// UNPACKED-NEXT:       0x306E8 R_AARCH64_AUTH_RELATIVE - 0x5
+// UNPACKED-NEXT:       0x306F0 R_AARCH64_AUTH_RELATIVE - 0x6
+// UNPACKED-NEXT:       0x306F8 R_AARCH64_AUTH_RELATIVE - 0x7
+// UNPACKED-NEXT:       0x30710 R_AARCH64_AUTH_RELATIVE - 0x1
+// UNPACKED-NEXT:       0x30718 R_AARCH64_AUTH_RELATIVE - 0x2
+// UNPACKED-NEXT:       0x30720 R_AARCH64_AUTH_RELATIVE - 0x3
+// UNPACKED-NEXT:       0x30728 R_AARCH64_AUTH_RELATIVE - 0x4
+// UNPACKED-NEXT:       0x30730 R_AARCH64_AUTH_RELATIVE - 0x5
+// UNPACKED-NEXT:       0x30738 R_AARCH64_AUTH_RELATIVE - 0x6
+// UNPACKED-NEXT:       0x30740 R_AARCH64_AUTH_RELATIVE - 0x7
+// UNPACKED-NEXT:       0x30748 R_AARCH64_AUTH_RELATIVE - 0x8
+// UNPACKED-NEXT:       0x30750 R_AARCH64_AUTH_RELATIVE - 0x9
+// UNPACKED-NEXT:       0x30759 R_AARCH64_AUTH_RELATIVE - 0xA
+// UNPACKED-NEXT:       0x306C0 R_AARCH64_AUTH_ABS64 bar2 0x1
+// UNPACKED-NEXT:       0x30708 R_AARCH64_AUTH_ABS64 bar2 0x0
+// UNPACKED-NEXT:       0x30761 R_AARCH64_AUTH_ABS64 bar2 0x0
+// UNPACKED-NEXT:       0x30769 R_AARCH64_AUTH_ABS64 bar2 0x0
+// UNPACKED-NEXT:       0x30771 R_AARCH64_AUTH_ABS64 bar2 0x1
+// UNPACKED-NEXT:       0x30779 R_AARCH64_AUTH_ABS64 bar2 0x1
+// UNPACKED-NEXT:       0x30781 R_AARCH64_AUTH_ABS64 bar2 0x0
+// UNPACKED-NEXT:       0x30700 R_AARCH64_AUTH_ABS64 zed2 0x0
+// UNPACKED-NEXT:     }
+
+// RUN: ld.lld -pie -z pack-relative-auth-relocs %t.o %t.so -o %t2
+// RUN: llvm-readobj -S --dynamic-table %t2 | FileCheck --check-prefix=RELR-HEADERS %s
+// RUN: llvm-readobj -r --raw-relr %t2 | FileCheck --check-prefix=RAW-RELR %s
+// RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=RELR %s
+
+// RELR-HEADERS:       Index: 1
+// RELR-HEADERS-NEXT:  Name: .dynsym
+
+// RELR-HEADERS:       Name: .relr.auth.dyn
+// RELR-HEADERS-NEXT:  Type: SHT_AARCH64_AUTH_RELR
+// RELR-HEADERS-NEXT:  Flags [ (0x2)
+// RELR-HEADERS-NEXT:    SHF_ALLOC (0x2)
+// RELR-HEADERS-NEXT:  ]
+// RELR-HEADERS-NEXT:  Address: [[ADDR:.*]]
+// RELR-HEADERS-NEXT:  Offset: [[ADDR]]
+// RELR-HEADERS-NEXT:  Size: 16
+// RELR-HEADERS-NEXT:  Link: 0
+// RELR-HEADERS-NEXT:  Info: 0
+// RELR-HEADERS-NEXT:  AddressAlignment: 8
+// RELR-HEADERS-NEXT:  EntrySize: 8
+
+// RELR-HEADERS:       0x0000000070000012 AARCH64_AUTH_RELR    [[ADDR]]
+// RELR-HEADERS:       0x0000000070000011 AARCH64_AUTH_RELRSZ  16 (bytes)
+// RELR-HEADERS:       0x0000000070000013 AARCH64_AUTH_RELRENT 8 (bytes)
+
+/// SHT_RELR section contains address/bitmap entries
+/// encoding the offsets for relative relocation.
+// RAW-RELR:           Section ({{.+}}) .relr.auth.dyn {
+// RAW-RELR-NEXT:      0x30480
+// RAW-RELR-NEXT:      0x7FCFEFF
+// RAW-RELR-NEXT:      }
+
+/// Decoded SHT_RELR section is same as UNPACKED,
+/// but contains only the relative relocations.
+/// Any relative relocations with odd offset stay in SHT_RELA.
+
+// RELR:      Section ({{.+}}) .rela.dyn {
+// RELR-NEXT:   0x30559 R_AARCH64_AUTH_RELATIVE - 0xA
+// RELR-NEXT:   0x304C0 R_AARCH64_AUTH_ABS64 bar2 0x1
+// RELR-NEXT:   0x30508 R_AARCH64_AUTH_ABS64 bar2 0x0
+// RELR-NEXT:   0x30561 R_AARCH64_AUTH_ABS64 bar2 0x0
+// RELR-NEXT:   0x30569 R_AARCH64_AUTH_ABS64 bar2 0x0
+// RELR-NEXT:   0x30571 R_AARCH64_AUTH_ABS64 bar2 0x1
+// RELR-NEXT:   0x30579 R_AARCH64_AUTH_ABS64 bar2 0x1
+// RELR-NEXT:   0x30581 R_AARCH64_AUTH_ABS64 bar2 0x0
+// RELR-NEXT:   0x30500 R_AARCH64_AUTH_ABS64 zed2 0x0
+// RELR-NEXT: }
+// RELR-NEXT: Section ({{.+}}) .relr.auth.dyn {
+// RELR-NEXT:   0x30480 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30488 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30490 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30498 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304A0 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304A8 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304B0 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304B8 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304C8 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304D0 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304D8 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304E0 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304E8 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304F0 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x304F8 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30510 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30518 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30520 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30528 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30530 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30538 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30540 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30548 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x30550 R_AARCH64_RELATIVE -
+// RELR-NEXT: }
+
+.section .test, "aw"
+.p2align 3
+.quad (__ehdr_start + 1)@AUTH(da,42)
+.quad (__ehdr_start + 2)@AUTH(da,42)
+.quad (__ehdr_start + 3)@AUTH(da,42)
+.quad (__ehdr_start + 4)@AUTH(da,42)
+.quad (__ehdr_start + 5)@AUTH(da,42)
+.quad (__ehdr_start + 6)@AUTH(da,42)
+.quad (__ehdr_start + 7)@AUTH(da,42)
+.quad (__ehdr_start + 8)@AUTH(da,42)
+.quad (bar2 + 1)@AUTH(ia,42)
+
+.quad (__ehdr_start + 1)@AUTH(da,65535)
+.quad (__ehdr_start + 2)@AUTH(da,65535)
+.quad (__ehdr_start + 3)@AUTH(da,65535)
+.quad (__ehdr_start + 4)@AUTH(da,65535)
+.quad (__ehdr_start + 5)@AUTH(da,65535)
+.quad (__ehdr_start + 6)@AUTH(da,65535)
+.quad (__ehdr_start + 7)@AUTH(da,65535)
+.quad zed2 at AUTH(da,42)
+.quad bar2 at AUTH(ia,42)
+
+.quad (__ehdr_start + 1)@AUTH(da,0)
+.quad (__ehdr_start + 2)@AUTH(da,0)
+.quad (__ehdr_start + 3)@AUTH(da,0)
+.quad (__ehdr_start + 4)@AUTH(da,0)
+.quad (__ehdr_start + 5)@AUTH(da,0)
+.quad (__ehdr_start + 6)@AUTH(da,0)
+.quad (__ehdr_start + 7)@AUTH(da,0)
+.quad (__ehdr_start + 8)@AUTH(da,0)
+.quad (__ehdr_start + 9)@AUTH(da,0)
+.byte 00
+.quad (__ehdr_start + 10)@AUTH(da,0)
+.quad bar2 at AUTH(ia,42)
+.quad bar2 at AUTH(ia,42)
+.quad (bar2 + 1)@AUTH(ia,42)
+.quad (bar2 + 1)@AUTH(ia,42)
+.quad bar2 at AUTH(ia,42)

>From 589c6455a929f41ed3a79fc7d91119586eb1ee7b Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 12 Dec 2023 09:05:38 +0300
Subject: [PATCH 02/13] Address trivial review comments

---
 lld/ELF/Driver.cpp                       | 46 ++++++++++++------------
 lld/ELF/InputFiles.cpp                   |  2 +-
 lld/test/ELF/aarch64-bti-pac-cli-error.s | 15 +++++---
 lld/test/ELF/aarch64-feature-pauth.s     |  2 +-
 4 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 4e8e9eb86ecf77..ca5a8b8d994a4b 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2648,44 +2648,44 @@ static uint32_t getAndFeatures() {
   return ret;
 }
 
-static void getAarch64PauthInfo() {
+static void getAArch64PauthInfo() {
   if (ctx.objectFiles.empty())
     return;
 
-  auto NonEmptyIt = std::find_if(
+  auto it = std::find_if(
       ctx.objectFiles.begin(), ctx.objectFiles.end(),
       [](const ELFFileBase *f) { return !f->aarch64PauthAbiTag.empty(); });
-  if (NonEmptyIt == ctx.objectFiles.end())
+  if (it == ctx.objectFiles.end())
     return;
 
-  ctx.aarch64PauthAbiTag = (*NonEmptyIt)->aarch64PauthAbiTag;
-  StringRef F1 = (*NonEmptyIt)->getName();
-  for (ELFFileBase *F : ArrayRef(ctx.objectFiles)) {
-    StringRef F2 = F->getName();
-    const SmallVector<uint8_t, 0> &D1 = ctx.aarch64PauthAbiTag;
-    const SmallVector<uint8_t, 0> &D2 = F->aarch64PauthAbiTag;
-    if (D1.empty() != D2.empty()) {
-      auto Helper = [](StringRef Report, const Twine &Msg) {
-        if (Report == "warning")
-          warn(Msg);
-        else if (Report == "error")
-          error(Msg);
+  ctx.aarch64PauthAbiTag = (*it)->aarch64PauthAbiTag;
+  StringRef f1 = (*it)->getName();
+  for (ELFFileBase *f : ArrayRef(ctx.objectFiles)) {
+    StringRef f2 = f->getName();
+    const SmallVector<uint8_t, 0> &d1 = ctx.aarch64PauthAbiTag;
+    const SmallVector<uint8_t, 0> &d2 = f->aarch64PauthAbiTag;
+    if (d1.empty() != d2.empty()) {
+      auto helper = [](StringRef report, const Twine &msg) {
+        if (report == "warning")
+          warn(msg);
+        else if (report == "error")
+          error(msg);
       };
 
-      Helper(config->zPauthReport,
-             (D1.empty() ? F1.str() : F2.str()) +
+      helper(config->zPauthReport,
+             (d1.empty() ? f1.str() : f2.str()) +
                  " has no AArch64 PAuth compatibility info while " +
-                 (D1.empty() ? F2.str() : F1.str()) +
+                 (d1.empty() ? f2.str() : f1.str()) +
                  " has one; either all or no input files must have it");
     }
 
-    if (!D1.empty() && !D2.empty() &&
-        !std::equal(D1.begin(), D1.end(), D2.begin(), D2.end()))
+    if (!d1.empty() && !d2.empty() &&
+        !std::equal(d1.begin(), d1.end(), d2.begin(), d2.end()))
       errorOrWarn(
           "incompatible values of AArch64 PAuth compatibility info found"
           "\n" +
-          F1 + ": 0x" + toHex(ArrayRef(D1.data(), D1.size())) + "\n" + F2 +
-          ": 0x" + toHex(ArrayRef(D2.data(), D2.size())));
+          f1 + ": 0x" + toHex(ArrayRef(d1.data(), d1.size())) + "\n" + f2 +
+          ": 0x" + toHex(ArrayRef(d2.data(), d2.size())));
   }
 }
 
@@ -3027,7 +3027,7 @@ void LinkerDriver::link(opt::InputArgList &args) {
   config->andFeatures = getAndFeatures();
 
   if (config->emachine == EM_AARCH64)
-    getAarch64PauthInfo();
+    getAArch64PauthInfo();
 
   // The Target instance handles target-specific stuff, such as applying
   // relocations or writing a PLT section. It also contains target-dependent
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 44c8050f2c967a..d7ceaf476cf9bf 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -992,7 +992,7 @@ static void readAArch64PauthAbiTag(const InputSection &sec, ObjFile<ELFT> &f) {
 
   ArrayRef<uint8_t> desc = note.getDesc(sec.addralign);
   if (desc.size() < 16) {
-    reportError("too short AArch64 PAuth compatibility info "
+    reportError("AArch64 PAuth compatibility info is too short "
                 "(at least 16 bytes expected)");
     return;
   }
diff --git a/lld/test/ELF/aarch64-bti-pac-cli-error.s b/lld/test/ELF/aarch64-bti-pac-cli-error.s
index b8ab1a28fa5a86..703c0aac6ea5ac 100644
--- a/lld/test/ELF/aarch64-bti-pac-cli-error.s
+++ b/lld/test/ELF/aarch64-bti-pac-cli-error.s
@@ -1,17 +1,22 @@
 # REQUIRES: x86
 # RUN: llvm-mc --triple=x86_64-pc-linux --filetype=obj -o %t.o %s
-# RUN: not ld.lld -z pac-plt -z force-bti -z bti-report=error %t.o -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld -z pac-plt -z force-bti -z bti-report=error   \
+# RUN:     -z pauth-report=error   %t.o -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld -z pac-plt -z force-bti -z bti-report=warning \
+# RUN:     -z pauth-report=warning %t.o -o /dev/null 2>&1 | FileCheck %s
 #
-## Check that we error if -z pac-plt, -z force-bti and -z bti-report=error are used when target is not
-## aarch64
+## Check that we error if -z pac-plt, -z force-bti are present and
+## -z bti-report and -z pauth-report are not none when target is not aarch64
 
 # CHECK: error: -z pac-plt only supported on AArch64
 # CHECK-NEXT: error: -z force-bti only supported on AArch64
 # CHECK-NEXT: error: -z bti-report only supported on AArch64
+# CHECK-NEXT: error: -z pauth-report only supported on AArch64
 
-# RUN: not ld.lld -z bti-report=something %t.o -o /dev/null 2>&1 | \
-# RUN:     FileCheck --check-prefix=REPORT_INVALID %s
+# RUN: not ld.lld -z bti-report=something -z pauth-report=something \
+# RUN:     %t.o -o /dev/null 2>&1 | FileCheck --check-prefix=REPORT_INVALID %s
 # REPORT_INVALID: error: -z bti-report= parameter something is not recognized
+# REPORT_INVALID: error: -z pauth-report= parameter something is not recognized
 # REPORT_INVALID-EMPTY:
 
         .globl start
diff --git a/lld/test/ELF/aarch64-feature-pauth.s b/lld/test/ELF/aarch64-feature-pauth.s
index 0520b2f28631e1..9060eb71f81757 100644
--- a/lld/test/ELF/aarch64-feature-pauth.s
+++ b/lld/test/ELF/aarch64-feature-pauth.s
@@ -21,7 +21,7 @@
 
 # ERR2:      error: {{.*}}: invalid type field value 42 (1 expected)
 # ERR2-NEXT: error: {{.*}}: invalid name field value XXX (ARM expected)
-# ERR2-NEXT: error: {{.*}}: too short AArch64 PAuth compatibility info (at least 16 bytes expected)
+# ERR2-NEXT: error: {{.*}}: AArch64 PAuth compatibility info is too short (at least 16 bytes expected)
 
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-short.s -o short.o
 # RUN: not ld.lld short.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR3 %s

>From d3411595fbbe37a14b0187ff0d134bd105892931 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 9 Jan 2024 21:53:00 +0300
Subject: [PATCH 03/13] Use `pack-relative-relocs` for both regular and auth
 relr relocs

---
 lld/ELF/Config.h               | 1 -
 lld/ELF/Driver.cpp             | 3 ---
 lld/ELF/Writer.cpp             | 3 ---
 lld/test/ELF/aarch64-ptrauth.s | 4 ++--
 4 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 1b633a79842769..e2a3cb2a61e936 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -276,7 +276,6 @@ struct Config {
   bool relocatable;
   bool relrGlibc = false;
   bool relrPackDynRelocs = false;
-  bool relrPackAuthDynRelocs = false;
   llvm::DenseSet<llvm::StringRef> saveTempsArgs;
   llvm::SmallVector<std::pair<llvm::GlobPattern, uint32_t>, 0> shuffleSections;
   bool singleRoRx;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index ca5a8b8d994a4b..6ab93c74bc6453 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1677,9 +1677,6 @@ static void readConfigs(opt::InputArgList &args) {
         getPackDynRelocs(args);
   }
 
-  config->relrPackAuthDynRelocs = getZFlag(
-      args, "pack-relative-auth-relocs", "nopack-relative-auth-relocs", false);
-
   if (auto *arg = args.getLastArg(OPT_symbol_ordering_file)){
     if (args.hasArg(OPT_call_graph_ordering_file))
       error("--symbol-ordering-file and --call-graph-order-file "
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index af2544c3fa0f7f..81e743d67dabd1 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -450,9 +450,6 @@ template <class ELFT> void elf::createSyntheticSections() {
     if (config->relrPackDynRelocs) {
       part.relrDyn = std::make_unique<RelrSection<ELFT>>(threadCount);
       add(*part.relrDyn);
-    }
-
-    if (config->relrPackAuthDynRelocs) {
       part.relrAuthDyn = std::make_unique<RelrSection<ELFT>>(
           threadCount, /*isAArch64Auth=*/true);
       add(*part.relrAuthDyn);
diff --git a/lld/test/ELF/aarch64-ptrauth.s b/lld/test/ELF/aarch64-ptrauth.s
index db946fc4c3e55c..26cc2d779e7482 100644
--- a/lld/test/ELF/aarch64-ptrauth.s
+++ b/lld/test/ELF/aarch64-ptrauth.s
@@ -3,7 +3,7 @@
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared2.s -o %t.so.o
 // RUN: ld.lld -shared %t.so.o -soname=so -o %t.so
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
-// RUN: ld.lld -pie -z nopack-relative-auth-relocs %t.o %t.so -o %t2
+// RUN: ld.lld -pie -z nopack-relative-relocs %t.o %t.so -o %t2
 // RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=UNPACKED %s
 
 // UNPACKED:          Section ({{.+}}) .rela.dyn {
@@ -42,7 +42,7 @@
 // UNPACKED-NEXT:       0x30700 R_AARCH64_AUTH_ABS64 zed2 0x0
 // UNPACKED-NEXT:     }
 
-// RUN: ld.lld -pie -z pack-relative-auth-relocs %t.o %t.so -o %t2
+// RUN: ld.lld -pie -z pack-relative-relocs %t.o %t.so -o %t2
 // RUN: llvm-readobj -S --dynamic-table %t2 | FileCheck --check-prefix=RELR-HEADERS %s
 // RUN: llvm-readobj -r --raw-relr %t2 | FileCheck --check-prefix=RAW-RELR %s
 // RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=RELR %s

>From b791da9dd02f8b3bf59d2d235181f945844d3039 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 9 Jan 2024 21:59:35 +0300
Subject: [PATCH 04/13] Rename aarch64-ptrauth.s to aarch64-reloc-pauth.s

---
 lld/test/ELF/{aarch64-ptrauth.s => aarch64-reloc-pauth.s} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename lld/test/ELF/{aarch64-ptrauth.s => aarch64-reloc-pauth.s} (100%)

diff --git a/lld/test/ELF/aarch64-ptrauth.s b/lld/test/ELF/aarch64-reloc-pauth.s
similarity index 100%
rename from lld/test/ELF/aarch64-ptrauth.s
rename to lld/test/ELF/aarch64-reloc-pauth.s

>From b95dcf8e7cd9c3c162a25c93a9c2b09ba8bb124c Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Tue, 9 Jan 2024 22:23:16 +0300
Subject: [PATCH 05/13] Remove unneeded test directives

---
 lld/test/ELF/aarch64-reloc-pauth.s | 114 +++--------------------------
 1 file changed, 12 insertions(+), 102 deletions(-)

diff --git a/lld/test/ELF/aarch64-reloc-pauth.s b/lld/test/ELF/aarch64-reloc-pauth.s
index 26cc2d779e7482..79e6e4246cc457 100644
--- a/lld/test/ELF/aarch64-reloc-pauth.s
+++ b/lld/test/ELF/aarch64-reloc-pauth.s
@@ -7,39 +7,10 @@
 // RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=UNPACKED %s
 
 // UNPACKED:          Section ({{.+}}) .rela.dyn {
-// UNPACKED-NEXT:       0x30680 R_AARCH64_AUTH_RELATIVE - 0x1
-// UNPACKED-NEXT:       0x30688 R_AARCH64_AUTH_RELATIVE - 0x2
-// UNPACKED-NEXT:       0x30690 R_AARCH64_AUTH_RELATIVE - 0x3
-// UNPACKED-NEXT:       0x30698 R_AARCH64_AUTH_RELATIVE - 0x4
-// UNPACKED-NEXT:       0x306A0 R_AARCH64_AUTH_RELATIVE - 0x5
-// UNPACKED-NEXT:       0x306A8 R_AARCH64_AUTH_RELATIVE - 0x6
-// UNPACKED-NEXT:       0x306B0 R_AARCH64_AUTH_RELATIVE - 0x7
-// UNPACKED-NEXT:       0x306B8 R_AARCH64_AUTH_RELATIVE - 0x8
-// UNPACKED-NEXT:       0x306C8 R_AARCH64_AUTH_RELATIVE - 0x1
-// UNPACKED-NEXT:       0x306D0 R_AARCH64_AUTH_RELATIVE - 0x2
-// UNPACKED-NEXT:       0x306D8 R_AARCH64_AUTH_RELATIVE - 0x3
-// UNPACKED-NEXT:       0x306E0 R_AARCH64_AUTH_RELATIVE - 0x4
-// UNPACKED-NEXT:       0x306E8 R_AARCH64_AUTH_RELATIVE - 0x5
-// UNPACKED-NEXT:       0x306F0 R_AARCH64_AUTH_RELATIVE - 0x6
-// UNPACKED-NEXT:       0x306F8 R_AARCH64_AUTH_RELATIVE - 0x7
-// UNPACKED-NEXT:       0x30710 R_AARCH64_AUTH_RELATIVE - 0x1
-// UNPACKED-NEXT:       0x30718 R_AARCH64_AUTH_RELATIVE - 0x2
-// UNPACKED-NEXT:       0x30720 R_AARCH64_AUTH_RELATIVE - 0x3
-// UNPACKED-NEXT:       0x30728 R_AARCH64_AUTH_RELATIVE - 0x4
-// UNPACKED-NEXT:       0x30730 R_AARCH64_AUTH_RELATIVE - 0x5
-// UNPACKED-NEXT:       0x30738 R_AARCH64_AUTH_RELATIVE - 0x6
-// UNPACKED-NEXT:       0x30740 R_AARCH64_AUTH_RELATIVE - 0x7
-// UNPACKED-NEXT:       0x30748 R_AARCH64_AUTH_RELATIVE - 0x8
-// UNPACKED-NEXT:       0x30750 R_AARCH64_AUTH_RELATIVE - 0x9
-// UNPACKED-NEXT:       0x30759 R_AARCH64_AUTH_RELATIVE - 0xA
-// UNPACKED-NEXT:       0x306C0 R_AARCH64_AUTH_ABS64 bar2 0x1
-// UNPACKED-NEXT:       0x30708 R_AARCH64_AUTH_ABS64 bar2 0x0
-// UNPACKED-NEXT:       0x30761 R_AARCH64_AUTH_ABS64 bar2 0x0
-// UNPACKED-NEXT:       0x30769 R_AARCH64_AUTH_ABS64 bar2 0x0
-// UNPACKED-NEXT:       0x30771 R_AARCH64_AUTH_ABS64 bar2 0x1
-// UNPACKED-NEXT:       0x30779 R_AARCH64_AUTH_ABS64 bar2 0x1
-// UNPACKED-NEXT:       0x30781 R_AARCH64_AUTH_ABS64 bar2 0x0
-// UNPACKED-NEXT:       0x30700 R_AARCH64_AUTH_ABS64 zed2 0x0
+// UNPACKED-NEXT:       0x303C8 R_AARCH64_AUTH_RELATIVE - 0x1
+// UNPACKED-NEXT:       0x303E1 R_AARCH64_AUTH_RELATIVE - 0x2
+// UNPACKED-NEXT:       0x303D0 R_AARCH64_AUTH_ABS64 zed2 0x0
+// UNPACKED-NEXT:       0x303D8 R_AARCH64_AUTH_ABS64 bar2 0x0
 // UNPACKED-NEXT:     }
 
 // RUN: ld.lld -pie -z pack-relative-relocs %t.o %t.so -o %t2
@@ -57,21 +28,20 @@
 // RELR-HEADERS-NEXT:  ]
 // RELR-HEADERS-NEXT:  Address: [[ADDR:.*]]
 // RELR-HEADERS-NEXT:  Offset: [[ADDR]]
-// RELR-HEADERS-NEXT:  Size: 16
+// RELR-HEADERS-NEXT:  Size: 8
 // RELR-HEADERS-NEXT:  Link: 0
 // RELR-HEADERS-NEXT:  Info: 0
 // RELR-HEADERS-NEXT:  AddressAlignment: 8
 // RELR-HEADERS-NEXT:  EntrySize: 8
 
 // RELR-HEADERS:       0x0000000070000012 AARCH64_AUTH_RELR    [[ADDR]]
-// RELR-HEADERS:       0x0000000070000011 AARCH64_AUTH_RELRSZ  16 (bytes)
+// RELR-HEADERS:       0x0000000070000011 AARCH64_AUTH_RELRSZ  8 (bytes)
 // RELR-HEADERS:       0x0000000070000013 AARCH64_AUTH_RELRENT 8 (bytes)
 
 /// SHT_RELR section contains address/bitmap entries
 /// encoding the offsets for relative relocation.
 // RAW-RELR:           Section ({{.+}}) .relr.auth.dyn {
-// RAW-RELR-NEXT:      0x30480
-// RAW-RELR-NEXT:      0x7FCFEFF
+// RAW-RELR-NEXT:      0x303E8
 // RAW-RELR-NEXT:      }
 
 /// Decoded SHT_RELR section is same as UNPACKED,
@@ -79,78 +49,18 @@
 /// Any relative relocations with odd offset stay in SHT_RELA.
 
 // RELR:      Section ({{.+}}) .rela.dyn {
-// RELR-NEXT:   0x30559 R_AARCH64_AUTH_RELATIVE - 0xA
-// RELR-NEXT:   0x304C0 R_AARCH64_AUTH_ABS64 bar2 0x1
-// RELR-NEXT:   0x30508 R_AARCH64_AUTH_ABS64 bar2 0x0
-// RELR-NEXT:   0x30561 R_AARCH64_AUTH_ABS64 bar2 0x0
-// RELR-NEXT:   0x30569 R_AARCH64_AUTH_ABS64 bar2 0x0
-// RELR-NEXT:   0x30571 R_AARCH64_AUTH_ABS64 bar2 0x1
-// RELR-NEXT:   0x30579 R_AARCH64_AUTH_ABS64 bar2 0x1
-// RELR-NEXT:   0x30581 R_AARCH64_AUTH_ABS64 bar2 0x0
-// RELR-NEXT:   0x30500 R_AARCH64_AUTH_ABS64 zed2 0x0
+// RELR-NEXT:   0x30401 R_AARCH64_AUTH_RELATIVE - 0x2
+// RELR-NEXT:   0x303F0 R_AARCH64_AUTH_ABS64 zed2 0x0
+// RELR-NEXT:   0x303F8 R_AARCH64_AUTH_ABS64 bar2 0x0
 // RELR-NEXT: }
 // RELR-NEXT: Section ({{.+}}) .relr.auth.dyn {
-// RELR-NEXT:   0x30480 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30488 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30490 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30498 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304A0 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304A8 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304B0 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304B8 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304C8 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304D0 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304D8 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304E0 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304E8 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304F0 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x304F8 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30510 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30518 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30520 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30528 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30530 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30538 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30540 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30548 R_AARCH64_RELATIVE -
-// RELR-NEXT:   0x30550 R_AARCH64_RELATIVE -
+// RELR-NEXT:   0x303E8 R_AARCH64_RELATIVE -
 // RELR-NEXT: }
 
 .section .test, "aw"
 .p2align 3
 .quad (__ehdr_start + 1)@AUTH(da,42)
-.quad (__ehdr_start + 2)@AUTH(da,42)
-.quad (__ehdr_start + 3)@AUTH(da,42)
-.quad (__ehdr_start + 4)@AUTH(da,42)
-.quad (__ehdr_start + 5)@AUTH(da,42)
-.quad (__ehdr_start + 6)@AUTH(da,42)
-.quad (__ehdr_start + 7)@AUTH(da,42)
-.quad (__ehdr_start + 8)@AUTH(da,42)
-.quad (bar2 + 1)@AUTH(ia,42)
-
-.quad (__ehdr_start + 1)@AUTH(da,65535)
-.quad (__ehdr_start + 2)@AUTH(da,65535)
-.quad (__ehdr_start + 3)@AUTH(da,65535)
-.quad (__ehdr_start + 4)@AUTH(da,65535)
-.quad (__ehdr_start + 5)@AUTH(da,65535)
-.quad (__ehdr_start + 6)@AUTH(da,65535)
-.quad (__ehdr_start + 7)@AUTH(da,65535)
 .quad zed2 at AUTH(da,42)
 .quad bar2 at AUTH(ia,42)
-
-.quad (__ehdr_start + 1)@AUTH(da,0)
-.quad (__ehdr_start + 2)@AUTH(da,0)
-.quad (__ehdr_start + 3)@AUTH(da,0)
-.quad (__ehdr_start + 4)@AUTH(da,0)
-.quad (__ehdr_start + 5)@AUTH(da,0)
-.quad (__ehdr_start + 6)@AUTH(da,0)
-.quad (__ehdr_start + 7)@AUTH(da,0)
-.quad (__ehdr_start + 8)@AUTH(da,0)
-.quad (__ehdr_start + 9)@AUTH(da,0)
 .byte 00
-.quad (__ehdr_start + 10)@AUTH(da,0)
-.quad bar2 at AUTH(ia,42)
-.quad bar2 at AUTH(ia,42)
-.quad (bar2 + 1)@AUTH(ia,42)
-.quad (bar2 + 1)@AUTH(ia,42)
-.quad bar2 at AUTH(ia,42)
+.quad (__ehdr_start + 2)@AUTH(da,42)

>From 594f8a0e8331b5d11f3efc58fcaa7eae4b9fd7b4 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 11 Jan 2024 03:19:14 +0300
Subject: [PATCH 06/13] Do not emit AUTH relocations in read-only sections

---
 lld/ELF/Relocations.cpp               | 85 +++++++++++++++++++--------
 lld/test/ELF/aarch64-reloc-pauth-ro.s | 21 +++++++
 2 files changed, 80 insertions(+), 26 deletions(-)
 create mode 100644 lld/test/ELF/aarch64-reloc-pauth-ro.s

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 166407d573252a..53f638ae2f854e 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1125,11 +1125,37 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
                     (isa<EhInputSection>(sec) && config->emachine != EM_MIPS));
   if (canWrite) {
     RelType rel = target->getDynRel(type);
+    if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
+      // Assume relocations from relocatable objects are RELA.
+      assert(config->isRela);
+      std::lock_guard<std::mutex> lock(relocMutex);
+      // For a preemptible symbol, we can't use a relative relocation. For an
+      // undefined symbol, we can't compute offset at link-time and use a
+      // relative relocation. Use a symbolic relocation instead.
+      Partition &part = sec->getPartition();
+      if (sym.isPreemptible || sym.isUndefined()) {
+        part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
+      } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0 &&
+                 isInt<32>(sym.getVA(addend))) {
+        // Implicit addend is below 32-bits so we can use the compressed
+        // relative relocation section. The R_AARCH64_AUTH_RELATIVE
+        // has a smaller addend field as bits [63:32] encode the signing-schema.
+        sec->addReloc({expr, type, offset, addend, &sym});
+        part.relrAuthDyn->relocsVec[parallel::getThreadIndex()].push_back(
+            {sec, offset});
+      } else {
+        part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
+                                DynamicReloc::AddendOnlyWithTargetVA, sym,
+                                addend, R_ABS});
+      }
+      return;
+    }
     if (oneof<R_GOT, R_LOONGARCH_GOT>(expr) ||
         (rel == target->symbolicRel && !sym.isPreemptible)) {
       addRelativeReloc<true>(*sec, offset, sym, addend, expr, type);
       return;
-    } else if (rel != 0) {
+    }
+    if (rel != 0) {
       if (config->emachine == EM_MIPS && rel == target->symbolicRel)
         rel = target->relativeRel;
       std::lock_guard<std::mutex> lock(relocMutex);
@@ -1157,6 +1183,12 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
     }
   }
 
+  if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
+    error("relocation " + toString(type) + " against symbol '" + toString(sym) +
+          "'" + " in read-only section" + getLocation(*sec, sym, offset));
+    return;
+  }
+
   // When producing an executable, we can perform copy relocations (for
   // STT_OBJECT) and canonical PLT (for STT_FUNC) if sym is defined by a DSO.
   if (!config->shared && sym.isShared()) {
@@ -1444,31 +1476,32 @@ template <class ELFT, class RelTy> void RelocationScanner::scanOne(RelTy *&i) {
     }
   }
 
-  if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
-    // Assume relocations from relocatable objects are RELA.
-    assert(RelTy::IsRela);
-    std::lock_guard<std::mutex> lock(relocMutex);
-    // For a preemptible symbol, we can't use a relative relocation. For an
-    // undefined symbol, we can't compute offset at link-time and use a relative
-    // relocation. Use a symbolic relocation instead.
-    Partition &part = sec->getPartition();
-    if (sym.isPreemptible || sym.isUndefined()) {
-      part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
-    } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0 &&
-               isInt<32>(sym.getVA(addend))) {
-      // Implicit addend is below 32-bits so we can use the compressed
-      // relative relocation section. The R_AARCH64_AUTH_RELATIVE
-      // has a smaller addend fielf as bits [63:32] encode the signing-schema.
-      sec->addReloc({expr, type, offset, addend, &sym});
-      part.relrAuthDyn->relocsVec[parallel::getThreadIndex()].push_back(
-          {sec, offset});
-    } else {
-      part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
-                              DynamicReloc::AddendOnlyWithTargetVA, sym, addend,
-                              R_ABS});
-    }
-    return;
-  }
+  // if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
+  //   // Assume relocations from relocatable objects are RELA.
+  //   assert(RelTy::IsRela);
+  //   std::lock_guard<std::mutex> lock(relocMutex);
+  //   // For a preemptible symbol, we can't use a relative relocation. For an
+  //   // undefined symbol, we can't compute offset at link-time and use a
+  //   relative
+  //   // relocation. Use a symbolic relocation instead.
+  //   Partition &part = sec->getPartition();
+  //   if (sym.isPreemptible || sym.isUndefined()) {
+  //     part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
+  //   } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0 &&
+  //              isInt<32>(sym.getVA(addend))) {
+  //     // Implicit addend is below 32-bits so we can use the compressed
+  //     // relative relocation section. The R_AARCH64_AUTH_RELATIVE
+  //     // has a smaller addend fielf as bits [63:32] encode the
+  //     signing-schema. sec->addReloc({expr, type, offset, addend, &sym});
+  //     part.relrAuthDyn->relocsVec[parallel::getThreadIndex()].push_back(
+  //         {sec, offset});
+  //   } else {
+  //     part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
+  //                             DynamicReloc::AddendOnlyWithTargetVA, sym,
+  //                             addend, R_ABS});
+  //   }
+  //   return;
+  // }
 
   // If the relocation does not emit a GOT or GOTPLT entry but its computation
   // uses their addresses, we need GOT or GOTPLT to be created.
diff --git a/lld/test/ELF/aarch64-reloc-pauth-ro.s b/lld/test/ELF/aarch64-reloc-pauth-ro.s
new file mode 100644
index 00000000000000..80afb921a5c26f
--- /dev/null
+++ b/lld/test/ELF/aarch64-reloc-pauth-ro.s
@@ -0,0 +1,21 @@
+// REQUIRES: aarch64
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared2.s -o %t.so.o
+// RUN: ld.lld -shared %t.so.o -soname=so -o %t.so
+// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+// RUN: not ld.lld -pie %t.o %t.so -o %t2 2>&1 | FileCheck %s
+
+// CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'zed2' in read-only section
+// CHECK-NEXT: defined in
+// CHECK-NEXT: referenced by
+// CHECK-SAME: :(.test+0x0)
+
+// CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'bar2' in read-only section
+// CHECK-NEXT: defined in
+// CHECK-NEXT: referenced by
+// CHECK-SAME: :(.test+0x8)
+
+.section .test, "a"
+.p2align 3
+.quad zed2 at AUTH(da,42)
+.quad bar2 at AUTH(ia,42)

>From acb1730e74ce0ca8c55960018318e9943ec66bfd Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Wed, 31 Jan 2024 21:38:05 +0300
Subject: [PATCH 07/13] Apply fix from 37efa70 accidently deleted in d793c0c

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

diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index f17ec7759482c2..faf7dcd2d5e81f 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -563,6 +563,7 @@ static void checkZOptions(opt::InputArgList &args) {
   // initialized yet. Claim them here.
   args::getZOptionValue(args, OPT_z, "max-page-size", 0);
   args::getZOptionValue(args, OPT_z, "common-page-size", 0);
+  getZFlag(args, "rel", "rela", false);
   for (auto *arg : args.filtered(OPT_z))
     if (!arg->isClaimed())
       warn("unknown -z value: " + StringRef(arg->getValue()));

>From de73eae53481bb805fbabe97a38055ebaad934de Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Wed, 31 Jan 2024 21:39:46 +0300
Subject: [PATCH 08/13] Address review comments

---
 lld/ELF/Relocations.cpp              | 27 ---------------------------
 lld/ELF/SyntheticSections.h          |  3 ++-
 lld/test/ELF/aarch64-feature-pauth.s | 20 ++++++++++----------
 3 files changed, 12 insertions(+), 38 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 6e8191f7b4f55e..16ab213b60234a 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1493,33 +1493,6 @@ template <class ELFT, class RelTy> void RelocationScanner::scanOne(RelTy *&i) {
     }
   }
 
-  // if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
-  //   // Assume relocations from relocatable objects are RELA.
-  //   assert(RelTy::IsRela);
-  //   std::lock_guard<std::mutex> lock(relocMutex);
-  //   // For a preemptible symbol, we can't use a relative relocation. For an
-  //   // undefined symbol, we can't compute offset at link-time and use a
-  //   relative
-  //   // relocation. Use a symbolic relocation instead.
-  //   Partition &part = sec->getPartition();
-  //   if (sym.isPreemptible || sym.isUndefined()) {
-  //     part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
-  //   } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0 &&
-  //              isInt<32>(sym.getVA(addend))) {
-  //     // Implicit addend is below 32-bits so we can use the compressed
-  //     // relative relocation section. The R_AARCH64_AUTH_RELATIVE
-  //     // has a smaller addend fielf as bits [63:32] encode the
-  //     signing-schema. sec->addReloc({expr, type, offset, addend, &sym});
-  //     part.relrAuthDyn->relocsVec[parallel::getThreadIndex()].push_back(
-  //         {sec, offset});
-  //   } else {
-  //     part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
-  //                             DynamicReloc::AddendOnlyWithTargetVA, sym,
-  //                             addend, R_ABS});
-  //   }
-  //   return;
-  // }
-
   // If the relocation does not emit a GOT or GOTPLT entry but its computation
   // uses their addresses, we need GOT or GOTPLT to be created.
   //
diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h
index 79fe636cc09ef3..c36f08e26c2a7b 100644
--- a/lld/ELF/SyntheticSections.h
+++ b/lld/ELF/SyntheticSections.h
@@ -554,7 +554,8 @@ class RelocationBaseSection : public SyntheticSection {
     return SyntheticSection::classof(d) &&
            (d->type == llvm::ELF::SHT_RELA || d->type == llvm::ELF::SHT_REL ||
             d->type == llvm::ELF::SHT_RELR ||
-            d->type == llvm::ELF::SHT_AARCH64_AUTH_RELR);
+            (config->emachine == llvm::ELF::EM_AARCH64 &&
+             d->type == llvm::ELF::SHT_AARCH64_AUTH_RELR));
   }
   int32_t dynamicTag, sizeDynamicTag;
   SmallVector<DynamicReloc, 0> relocs;
diff --git a/lld/test/ELF/aarch64-feature-pauth.s b/lld/test/ELF/aarch64-feature-pauth.s
index 9060eb71f81757..4d1b9d9164004f 100644
--- a/lld/test/ELF/aarch64-feature-pauth.s
+++ b/lld/test/ELF/aarch64-feature-pauth.s
@@ -13,20 +13,20 @@
 # RUN: not ld.lld tag11.o tag12.o tag2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR1 %s
 
 # ERR1: error: incompatible values of AArch64 PAuth compatibility info found
-# ERR1: {{.*}}: 0x2A000000000000000{{1|2}}00000000000000
-# ERR1: {{.*}}: 0x2A000000000000000{{1|2}}00000000000000
+# ERR1: tag11.o: 0x2A000000000000000{{1|2}}00000000000000
+# ERR1: tag2.o: 0x2A000000000000000{{1|2}}00000000000000
 
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-errs.s -o errs.o
 # RUN: not ld.lld errs.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR2 %s
 
-# ERR2:      error: {{.*}}: invalid type field value 42 (1 expected)
-# ERR2-NEXT: error: {{.*}}: invalid name field value XXX (ARM expected)
-# ERR2-NEXT: error: {{.*}}: AArch64 PAuth compatibility info is too short (at least 16 bytes expected)
+# ERR2:      error: errs.o:(.note.AARCH64-PAUTH-ABI-tag): invalid type field value 42 (1 expected)
+# ERR2-NEXT: error: errs.o:(.note.AARCH64-PAUTH-ABI-tag): invalid name field value XXX (ARM expected)
+# ERR2-NEXT: error: errs.o:(.note.AARCH64-PAUTH-ABI-tag): AArch64 PAuth compatibility info is too short (at least 16 bytes expected)
 
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-short.s -o short.o
 # RUN: not ld.lld short.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR3 %s
 
-# ERR3: error: {{.*}}: section is too short
+# ERR3: error: short.o:(.note.AARCH64-PAUTH-ABI-tag): section is too short
 
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu no-info.s -o noinfo1.o
 # RUN: cp noinfo1.o noinfo2.o
@@ -34,10 +34,10 @@
 # RUN: ld.lld -z pauth-report=warning tag11.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix WARN %s
 # RUN: ld.lld -z pauth-report=none tag11.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix NONE %s
 
-# ERR4:      error: {{.*}}noinfo1.o has no AArch64 PAuth compatibility info while {{.*}}tag11.o has one; either all or no input files must have it
-# ERR4-NEXT: error: {{.*}}noinfo2.o has no AArch64 PAuth compatibility info while {{.*}}tag11.o has one; either all or no input files must have it
-# WARN:      warning: {{.*}}noinfo1.o has no AArch64 PAuth compatibility info while {{.*}}tag11.o has one; either all or no input files must have it
-# WARN-NEXT: warning: {{.*}}noinfo2.o has no AArch64 PAuth compatibility info while {{.*}}tag11.o has one; either all or no input files must have it
+# ERR4:      error: noinfo1.o has no AArch64 PAuth compatibility info while tag11.o has one; either all or no input files must have it
+# ERR4-NEXT: error: noinfo2.o has no AArch64 PAuth compatibility info while tag11.o has one; either all or no input files must have it
+# WARN:      warning: noinfo1.o has no AArch64 PAuth compatibility info while tag11.o has one; either all or no input files must have it
+# WARN-NEXT: warning: noinfo2.o has no AArch64 PAuth compatibility info while tag11.o has one; either all or no input files must have it
 # NONE-NOT:  {{.*}} has no AArch64 PAuth compatibility info while {{.*}} has one; either all or no input files must have it
 
 #--- abi-tag-short.s

>From aff3a96d4383b6aa930d4d21db949b3b459f2163 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 15 Feb 2024 12:38:42 +0300
Subject: [PATCH 09/13] Address several review comments

---
 lld/ELF/Config.h                      |  2 +-
 lld/ELF/Driver.cpp                    | 21 ++++++++-------------
 lld/ELF/InputFiles.cpp                |  2 +-
 lld/ELF/InputFiles.h                  |  2 +-
 lld/ELF/Relocations.cpp               |  4 +---
 lld/ELF/SyntheticSections.cpp         |  2 +-
 lld/test/ELF/aarch64-reloc-pauth-ro.s | 12 +++++-------
 7 files changed, 18 insertions(+), 27 deletions(-)

diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index eb76f72f2196f7..22d706688334f2 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -497,7 +497,7 @@ struct Ctx {
 
   llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &);
 
-  SmallVector<uint8_t, 0> aarch64PauthAbiTag;
+  ArrayRef<uint8_t> aarch64PauthAbiTag;
 };
 
 LLVM_LIBRARY_VISIBILITY extern Ctx ctx;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 096b9b2de401c4..c1eb2df9e37161 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2624,9 +2624,6 @@ static uint32_t getAndFeatures() {
 }
 
 static void getAArch64PauthInfo() {
-  if (ctx.objectFiles.empty())
-    return;
-
   auto it = std::find_if(
       ctx.objectFiles.begin(), ctx.objectFiles.end(),
       [](const ELFFileBase *f) { return !f->aarch64PauthAbiTag.empty(); });
@@ -2635,11 +2632,11 @@ static void getAArch64PauthInfo() {
 
   ctx.aarch64PauthAbiTag = (*it)->aarch64PauthAbiTag;
   StringRef f1 = (*it)->getName();
-  for (ELFFileBase *f : ArrayRef(ctx.objectFiles)) {
+  for (ELFFileBase *f : ctx.objectFiles) {
     StringRef f2 = f->getName();
-    const SmallVector<uint8_t, 0> &d1 = ctx.aarch64PauthAbiTag;
-    const SmallVector<uint8_t, 0> &d2 = f->aarch64PauthAbiTag;
-    if (d1.empty() != d2.empty()) {
+    ArrayRef<uint8_t> d1 = ctx.aarch64PauthAbiTag;
+    ArrayRef<uint8_t> d2 = f->aarch64PauthAbiTag;
+    if (d2.empty()) {
       auto helper = [](StringRef report, const Twine &msg) {
         if (report == "warning")
           warn(msg);
@@ -2648,14 +2645,12 @@ static void getAArch64PauthInfo() {
       };
 
       helper(config->zPauthReport,
-             (d1.empty() ? f1.str() : f2.str()) +
-                 " has no AArch64 PAuth compatibility info while " +
-                 (d1.empty() ? f2.str() : f1.str()) +
+             f2.str() + " has no AArch64 PAuth compatibility info while " +
+                 f1.str() +
                  " has one; either all or no input files must have it");
+      continue;
     }
-
-    if (!d1.empty() && !d2.empty() &&
-        !std::equal(d1.begin(), d1.end(), d2.begin(), d2.end()))
+    if (!std::equal(d1.begin(), d1.end(), d2.begin(), d2.end()))
       errorOrWarn(
           "incompatible values of AArch64 PAuth compatibility info found"
           "\n" +
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 90480e142477ef..3f7ef755a83af8 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -997,7 +997,7 @@ static void readAArch64PauthAbiTag(const InputSection &sec, ObjFile<ELFT> &f) {
     return;
   }
 
-  f.aarch64PauthAbiTag = SmallVector<uint8_t, 0>(iterator_range(desc));
+  f.aarch64PauthAbiTag = desc;
 }
 
 template <class ELFT>
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index c881a801182806..51db76dae17307 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -218,7 +218,7 @@ class ELFFileBase : public InputFile {
 public:
   uint32_t andFeatures = 0;
   bool hasCommonSyms = false;
-  SmallVector<uint8_t, 0> aarch64PauthAbiTag;
+  ArrayRef<uint8_t> aarch64PauthAbiTag;
 };
 
 // .o file.
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index fafabc0caf9d03..157c6b734c493b 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1138,14 +1138,12 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
   if (canWrite) {
     RelType rel = target->getDynRel(type);
     if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
-      // Assume relocations from relocatable objects are RELA.
-      assert(config->isRela);
       std::lock_guard<std::mutex> lock(relocMutex);
       // For a preemptible symbol, we can't use a relative relocation. For an
       // undefined symbol, we can't compute offset at link-time and use a
       // relative relocation. Use a symbolic relocation instead.
       Partition &part = sec->getPartition();
-      if (sym.isPreemptible || sym.isUndefined()) {
+      if (sym.isPreemptible) {
         part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
       } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0 &&
                  isInt<32>(sym.getVA(addend))) {
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 2dcb81d6f95d12..eea77295ae1a4f 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -340,7 +340,7 @@ bool AArch64PauthAbiTag::isNeeded() const {
 }
 
 void AArch64PauthAbiTag::writeTo(uint8_t *buf) {
-  const SmallVector<uint8_t, 0> &data = ctx.aarch64PauthAbiTag;
+  ArrayRef<uint8_t> data = ctx.aarch64PauthAbiTag;
   write32(buf, 4);                             // Name size
   write32(buf + 4, data.size());               // Content size
   write32(buf + 8, NT_ARM_TYPE_PAUTH_ABI_TAG); // Type
diff --git a/lld/test/ELF/aarch64-reloc-pauth-ro.s b/lld/test/ELF/aarch64-reloc-pauth-ro.s
index 80afb921a5c26f..61a52a1e4f8af2 100644
--- a/lld/test/ELF/aarch64-reloc-pauth-ro.s
+++ b/lld/test/ELF/aarch64-reloc-pauth-ro.s
@@ -3,17 +3,15 @@
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared2.s -o %t.so.o
 // RUN: ld.lld -shared %t.so.o -soname=so -o %t.so
 // RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
-// RUN: not ld.lld -pie %t.o %t.so -o %t2 2>&1 | FileCheck %s
+// RUN: not ld.lld -pie %t.o %t.so -o %t2 2>&1 | FileCheck -DFILE=%t %s
 
 // CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'zed2' in read-only section
-// CHECK-NEXT: defined in
-// CHECK-NEXT: referenced by
-// CHECK-SAME: :(.test+0x0)
+// CHECK-NEXT: defined in [[FILE]].so
+// CHECK-NEXT: referenced by [[FILE]].o:(.test+0x0)
 
 // CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'bar2' in read-only section
-// CHECK-NEXT: defined in
-// CHECK-NEXT: referenced by
-// CHECK-SAME: :(.test+0x8)
+// CHECK-NEXT: defined in [[FILE]].so
+// CHECK-NEXT: referenced by [[FILE]].o:(.test+0x8)
 
 .section .test, "a"
 .p2align 3

>From 4e53afaa50e63466263d0697e0e2a335d281dbf6 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Thu, 15 Feb 2024 14:58:15 +0300
Subject: [PATCH 10/13] Address several review comments

---
 lld/ELF/InputFiles.cpp                |  17 ++---
 lld/ELF/Relocations.cpp               |   5 +-
 lld/test/ELF/aarch64-feature-pauth.s  |  29 +++----
 lld/test/ELF/aarch64-reloc-pauth-ro.s |  22 +++---
 lld/test/ELF/aarch64-reloc-pauth.s    | 105 ++++++++++++--------------
 5 files changed, 85 insertions(+), 93 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 3f7ef755a83af8..f8030d0f773695 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -971,28 +971,27 @@ static void readAArch64PauthAbiTag(const InputSection &sec, ObjFile<ELFT> &f) {
   using Elf_Nhdr = typename ELFT::Nhdr;
   using Elf_Note = typename ELFT::Note;
   ArrayRef<uint8_t> data = sec.content();
-  auto reportError = [&](const Twine &msg) {
-    errorOrWarn(toString(sec.file) + ":(" + sec.name + "): " + msg);
-  };
 
   auto *nhdr = reinterpret_cast<const Elf_Nhdr *>(data.data());
   if (data.size() < sizeof(Elf_Nhdr) ||
       data.size() < nhdr->getSize(sec.addralign)) {
-    reportError("section is too short");
+    errorOrWarn(toString(&sec) + ": section is too short");
     return;
   }
 
   Elf_Note note(*nhdr);
   if (nhdr->n_type != NT_ARM_TYPE_PAUTH_ABI_TAG)
-    reportError("invalid type field value " + Twine(nhdr->n_type) + " (" +
-                Twine(NT_ARM_TYPE_PAUTH_ABI_TAG) + " expected)");
+    errorOrWarn(toString(&sec) + ": invalid type field value " +
+                Twine(nhdr->n_type) + " (" + Twine(NT_ARM_TYPE_PAUTH_ABI_TAG) +
+                " expected)");
   if (note.getName() != "ARM")
-    reportError("invalid name field value " + note.getName() +
-                " (ARM expected)");
+    errorOrWarn(toString(&sec) + ": invalid name field value " +
+                note.getName() + " (ARM expected)");
 
   ArrayRef<uint8_t> desc = note.getDesc(sec.addralign);
   if (desc.size() < 16) {
-    reportError("AArch64 PAuth compatibility info is too short "
+    errorOrWarn(toString(&sec) +
+                ": AArch64 PAuth compatibility info is too short "
                 "(at least 16 bytes expected)");
     return;
   }
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 157c6b734c493b..f5e00e4a8de59e 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1194,8 +1194,9 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
   }
 
   if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
-    error("relocation " + toString(type) + " against symbol '" + toString(sym) +
-          "'" + " in read-only section" + getLocation(*sec, sym, offset));
+    errorOrWarn("relocation " + toString(type) + " against symbol '" +
+                toString(sym) + "'" + " in read-only section" +
+                getLocation(*sec, sym, offset));
     return;
   }
 
diff --git a/lld/test/ELF/aarch64-feature-pauth.s b/lld/test/ELF/aarch64-feature-pauth.s
index 4d1b9d9164004f..229b9203c4332f 100644
--- a/lld/test/ELF/aarch64-feature-pauth.s
+++ b/lld/test/ELF/aarch64-feature-pauth.s
@@ -2,18 +2,18 @@
 
 # RUN: rm -rf %t && split-file %s %t && cd %t
 
-# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag1.s -o tag11.o
-# RUN: cp tag11.o tag12.o
-# RUN: ld.lld -shared tag11.o tag12.o -o tagok.so
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag1.s -o tag1.o
+# RUN: cp tag1.o tag1a.o
+# RUN: ld.lld -shared tag1.o tag1a.o -o tagok.so
 # RUN: llvm-readelf -n tagok.so | FileCheck --check-prefix OK %s
 
 # OK: AArch64 PAuth ABI tag: platform 0x2a, version 0x1
 
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag2.s -o tag2.o
-# RUN: not ld.lld tag11.o tag12.o tag2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR1 %s
+# RUN: not ld.lld tag1.o tag1a.o tag2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR1 %s
 
 # ERR1: error: incompatible values of AArch64 PAuth compatibility info found
-# ERR1: tag11.o: 0x2A000000000000000{{1|2}}00000000000000
+# ERR1: tag1.o: 0x2A000000000000000{{1|2}}00000000000000
 # ERR1: tag2.o: 0x2A000000000000000{{1|2}}00000000000000
 
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu abi-tag-errs.s -o errs.o
@@ -30,15 +30,14 @@
 
 # RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu no-info.s -o noinfo1.o
 # RUN: cp noinfo1.o noinfo2.o
-# RUN: not ld.lld -z pauth-report=error tag11.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR4 %s
-# RUN: ld.lld -z pauth-report=warning tag11.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix WARN %s
-# RUN: ld.lld -z pauth-report=none tag11.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix NONE %s
+# RUN: not ld.lld -z pauth-report=error tag1.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix ERR4 %s
+# RUN: ld.lld -z pauth-report=warning tag1.o noinfo1.o noinfo2.o -o /dev/null 2>&1 | FileCheck --check-prefix WARN %s
+# RUN: ld.lld -z pauth-report=none tag1.o noinfo1.o noinfo2.o --fatal-warnings -o /dev/null
 
-# ERR4:      error: noinfo1.o has no AArch64 PAuth compatibility info while tag11.o has one; either all or no input files must have it
-# ERR4-NEXT: error: noinfo2.o has no AArch64 PAuth compatibility info while tag11.o has one; either all or no input files must have it
-# WARN:      warning: noinfo1.o has no AArch64 PAuth compatibility info while tag11.o has one; either all or no input files must have it
-# WARN-NEXT: warning: noinfo2.o has no AArch64 PAuth compatibility info while tag11.o has one; either all or no input files must have it
-# NONE-NOT:  {{.*}} has no AArch64 PAuth compatibility info while {{.*}} has one; either all or no input files must have it
+# ERR4:      error: noinfo1.o has no AArch64 PAuth compatibility info while tag1.o has one; either all or no input files must have it
+# ERR4-NEXT: error: noinfo2.o has no AArch64 PAuth compatibility info while tag1.o has one; either all or no input files must have it
+# WARN:      warning: noinfo1.o has no AArch64 PAuth compatibility info while tag1.o has one; either all or no input files must have it
+# WARN-NEXT: warning: noinfo2.o has no AArch64 PAuth compatibility info while tag1.o has one; either all or no input files must have it
 
 #--- abi-tag-short.s
 
@@ -80,4 +79,8 @@
 
 #--- no-info.s
 
+.globl _start;   // define _start to avoid missing entry warning and use --fatal-warnings to assert no diagnostic
+.weak _start;    // allow multiple definitions of _start for simplicity
+_start:
+
 .section ".test", "a"
diff --git a/lld/test/ELF/aarch64-reloc-pauth-ro.s b/lld/test/ELF/aarch64-reloc-pauth-ro.s
index 61a52a1e4f8af2..4e496d52ab548f 100644
--- a/lld/test/ELF/aarch64-reloc-pauth-ro.s
+++ b/lld/test/ELF/aarch64-reloc-pauth-ro.s
@@ -1,17 +1,17 @@
-// REQUIRES: aarch64
+# REQUIRES: aarch64
 
-// RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared2.s -o %t.so.o
-// RUN: ld.lld -shared %t.so.o -soname=so -o %t.so
-// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
-// RUN: not ld.lld -pie %t.o %t.so -o %t2 2>&1 | FileCheck -DFILE=%t %s
+# RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared2.s -o %t.so.o
+# RUN: ld.lld -shared %t.so.o -soname=so -o %t.so
+# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+# RUN: not ld.lld -pie %t.o %t.so -o %t2 2>&1 | FileCheck -DFILE=%t %s
 
-// CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'zed2' in read-only section
-// CHECK-NEXT: defined in [[FILE]].so
-// CHECK-NEXT: referenced by [[FILE]].o:(.test+0x0)
+# CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'zed2' in read-only section
+# CHECK-NEXT: defined in [[FILE]].so
+# CHECK-NEXT: referenced by [[FILE]].o:(.test+0x0)
 
-// CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'bar2' in read-only section
-// CHECK-NEXT: defined in [[FILE]].so
-// CHECK-NEXT: referenced by [[FILE]].o:(.test+0x8)
+# CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'bar2' in read-only section
+# CHECK-NEXT: defined in [[FILE]].so
+# CHECK-NEXT: referenced by [[FILE]].o:(.test+0x8)
 
 .section .test, "a"
 .p2align 3
diff --git a/lld/test/ELF/aarch64-reloc-pauth.s b/lld/test/ELF/aarch64-reloc-pauth.s
index 79e6e4246cc457..8c0f147d783c56 100644
--- a/lld/test/ELF/aarch64-reloc-pauth.s
+++ b/lld/test/ELF/aarch64-reloc-pauth.s
@@ -1,61 +1,50 @@
-// REQUIRES: aarch64
-
-// RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared2.s -o %t.so.o
-// RUN: ld.lld -shared %t.so.o -soname=so -o %t.so
-// RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
-// RUN: ld.lld -pie -z nopack-relative-relocs %t.o %t.so -o %t2
-// RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=UNPACKED %s
-
-// UNPACKED:          Section ({{.+}}) .rela.dyn {
-// UNPACKED-NEXT:       0x303C8 R_AARCH64_AUTH_RELATIVE - 0x1
-// UNPACKED-NEXT:       0x303E1 R_AARCH64_AUTH_RELATIVE - 0x2
-// UNPACKED-NEXT:       0x303D0 R_AARCH64_AUTH_ABS64 zed2 0x0
-// UNPACKED-NEXT:       0x303D8 R_AARCH64_AUTH_ABS64 bar2 0x0
-// UNPACKED-NEXT:     }
-
-// RUN: ld.lld -pie -z pack-relative-relocs %t.o %t.so -o %t2
-// RUN: llvm-readobj -S --dynamic-table %t2 | FileCheck --check-prefix=RELR-HEADERS %s
-// RUN: llvm-readobj -r --raw-relr %t2 | FileCheck --check-prefix=RAW-RELR %s
-// RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=RELR %s
-
-// RELR-HEADERS:       Index: 1
-// RELR-HEADERS-NEXT:  Name: .dynsym
-
-// RELR-HEADERS:       Name: .relr.auth.dyn
-// RELR-HEADERS-NEXT:  Type: SHT_AARCH64_AUTH_RELR
-// RELR-HEADERS-NEXT:  Flags [ (0x2)
-// RELR-HEADERS-NEXT:    SHF_ALLOC (0x2)
-// RELR-HEADERS-NEXT:  ]
-// RELR-HEADERS-NEXT:  Address: [[ADDR:.*]]
-// RELR-HEADERS-NEXT:  Offset: [[ADDR]]
-// RELR-HEADERS-NEXT:  Size: 8
-// RELR-HEADERS-NEXT:  Link: 0
-// RELR-HEADERS-NEXT:  Info: 0
-// RELR-HEADERS-NEXT:  AddressAlignment: 8
-// RELR-HEADERS-NEXT:  EntrySize: 8
-
-// RELR-HEADERS:       0x0000000070000012 AARCH64_AUTH_RELR    [[ADDR]]
-// RELR-HEADERS:       0x0000000070000011 AARCH64_AUTH_RELRSZ  8 (bytes)
-// RELR-HEADERS:       0x0000000070000013 AARCH64_AUTH_RELRENT 8 (bytes)
-
-/// SHT_RELR section contains address/bitmap entries
-/// encoding the offsets for relative relocation.
-// RAW-RELR:           Section ({{.+}}) .relr.auth.dyn {
-// RAW-RELR-NEXT:      0x303E8
-// RAW-RELR-NEXT:      }
-
-/// Decoded SHT_RELR section is same as UNPACKED,
-/// but contains only the relative relocations.
-/// Any relative relocations with odd offset stay in SHT_RELA.
-
-// RELR:      Section ({{.+}}) .rela.dyn {
-// RELR-NEXT:   0x30401 R_AARCH64_AUTH_RELATIVE - 0x2
-// RELR-NEXT:   0x303F0 R_AARCH64_AUTH_ABS64 zed2 0x0
-// RELR-NEXT:   0x303F8 R_AARCH64_AUTH_ABS64 bar2 0x0
-// RELR-NEXT: }
-// RELR-NEXT: Section ({{.+}}) .relr.auth.dyn {
-// RELR-NEXT:   0x303E8 R_AARCH64_RELATIVE -
-// RELR-NEXT: }
+# REQUIRES: aarch64
+
+# RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared2.s -o %t.so.o
+# RUN: ld.lld -shared %t.so.o -soname=so -o %t.so
+# RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+# RUN: ld.lld -pie -z nopack-relative-relocs %t.o %t.so -o %t2
+# RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=UNPACKED %s
+
+# UNPACKED:          Section ({{.+}}) .rela.dyn {
+# UNPACKED-NEXT:       0x303C8 R_AARCH64_AUTH_RELATIVE - 0x1
+# UNPACKED-NEXT:       0x303E1 R_AARCH64_AUTH_RELATIVE - 0x2
+# UNPACKED-NEXT:       0x303D0 R_AARCH64_AUTH_ABS64 zed2 0x0
+# UNPACKED-NEXT:       0x303D8 R_AARCH64_AUTH_ABS64 bar2 0x0
+# UNPACKED-NEXT:     }
+
+# RUN: ld.lld -pie -z pack-relative-relocs %t.o %t.so -o %t2
+# RUN: llvm-readelf -S --dynamic-table %t2 | FileCheck --check-prefix=RELR-HEADERS %s
+# RUN: llvm-readobj -r --raw-relr %t2 | FileCheck --check-prefix=RAW-RELR %s
+# RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=RELR %s
+
+# RELR-HEADERS:      Section Headers:
+# RELR-HEADERS-NEXT: Name Type Address Off Size ES Flg Lk Inf Al
+# RELR-HEADERS:      .relr.auth.dyn AARCH64_AUTH_RELR 0000000000[[ADDR:.*]] [[ADDR]] 000008 08 A 0 0 8
+
+# RELR-HEADERS:      Dynamic section at offset 0x2e8 contains 16 entries
+# RELR-HEADERS:      0x0000000070000012 (AARCH64_AUTH_RELR) 0x2e0
+# RELR-HEADERS-NEXT: 0x0000000070000011 (AARCH64_AUTH_RELRSZ) 8 (bytes)
+# RELR-HEADERS-NEXT: 0x0000000070000013 (AARCH64_AUTH_RELRENT) 8 (bytes)
+
+## SHT_RELR section contains address/bitmap entries
+## encoding the offsets for relative relocation.
+# RAW-RELR:           Section ({{.+}}) .relr.auth.dyn {
+# RAW-RELR-NEXT:      0x303E8
+# RAW-RELR-NEXT:      }
+
+## Decoded SHT_RELR section is same as UNPACKED,
+## but contains only the relative relocations.
+## Any relative relocations with odd offset stay in SHT_RELA.
+
+# RELR:      Section ({{.+}}) .rela.dyn {
+# RELR-NEXT:   0x30401 R_AARCH64_AUTH_RELATIVE - 0x2
+# RELR-NEXT:   0x303F0 R_AARCH64_AUTH_ABS64 zed2 0x0
+# RELR-NEXT:   0x303F8 R_AARCH64_AUTH_ABS64 bar2 0x0
+# RELR-NEXT: }
+# RELR-NEXT: Section ({{.+}}) .relr.auth.dyn {
+# RELR-NEXT:   0x303E8 R_AARCH64_RELATIVE -
+# RELR-NEXT: }
 
 .section .test, "aw"
 .p2align 3

>From ec1c6322341f3f25f3ad0070810c4a90d188c3b5 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <dkovalev at accesssoftek.com>
Date: Sat, 17 Feb 2024 04:13:30 +0300
Subject: [PATCH 11/13] Address review comments

---
 lld/test/ELF/aarch64-reloc-pauth.s | 95 ++++++++++++++++++++++++------
 1 file changed, 77 insertions(+), 18 deletions(-)

diff --git a/lld/test/ELF/aarch64-reloc-pauth.s b/lld/test/ELF/aarch64-reloc-pauth.s
index 8c0f147d783c56..aeed86f42e88f9 100644
--- a/lld/test/ELF/aarch64-reloc-pauth.s
+++ b/lld/test/ELF/aarch64-reloc-pauth.s
@@ -3,53 +3,112 @@
 # RUN: llvm-mc -filetype=obj -triple=aarch64 %p/Inputs/shared2.s -o %t.so.o
 # RUN: ld.lld -shared %t.so.o -soname=so -o %t.so
 # RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
+
 # RUN: ld.lld -pie -z nopack-relative-relocs %t.o %t.so -o %t2
 # RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=UNPACKED %s
 
 # UNPACKED:          Section ({{.+}}) .rela.dyn {
-# UNPACKED-NEXT:       0x303C8 R_AARCH64_AUTH_RELATIVE - 0x1
-# UNPACKED-NEXT:       0x303E1 R_AARCH64_AUTH_RELATIVE - 0x2
-# UNPACKED-NEXT:       0x303D0 R_AARCH64_AUTH_ABS64 zed2 0x0
-# UNPACKED-NEXT:       0x303D8 R_AARCH64_AUTH_ABS64 bar2 0x0
+# UNPACKED-NEXT:       0x30440 R_AARCH64_AUTH_RELATIVE - 0x1
+# UNPACKED-NEXT:       0x30448 R_AARCH64_AUTH_RELATIVE - 0x2
+# UNPACKED-NEXT:       0x30450 R_AARCH64_AUTH_RELATIVE - 0x3
+# UNPACKED-NEXT:       0x30458 R_AARCH64_AUTH_RELATIVE - 0x12345678
+# UNPACKED-NEXT:       0x30460 R_AARCH64_AUTH_RELATIVE - 0x123456789A
+# UNPACKED-NEXT:       0x30479 R_AARCH64_AUTH_RELATIVE - 0x4
+# UNPACKED-NEXT:       0x30482 R_AARCH64_AUTH_RELATIVE - 0x5
+# UNPACKED-NEXT:       0x30468 R_AARCH64_AUTH_ABS64 zed2 0x0
+# UNPACKED-NEXT:       0x30470 R_AARCH64_AUTH_ABS64 bar2 0x0
 # UNPACKED-NEXT:     }
 
 # RUN: ld.lld -pie -z pack-relative-relocs %t.o %t.so -o %t2
 # RUN: llvm-readelf -S --dynamic-table %t2 | FileCheck --check-prefix=RELR-HEADERS %s
-# RUN: llvm-readobj -r --raw-relr %t2 | FileCheck --check-prefix=RAW-RELR %s
-# RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=RELR %s
 
 # RELR-HEADERS:      Section Headers:
 # RELR-HEADERS-NEXT: Name Type Address Off Size ES Flg Lk Inf Al
-# RELR-HEADERS:      .relr.auth.dyn AARCH64_AUTH_RELR 0000000000[[ADDR:.*]] [[ADDR]] 000008 08 A 0 0 8
+# RELR-HEADERS:      .relr.auth.dyn AARCH64_AUTH_RELR {{0*}}[[ADDR:.*]] {{0*}}[[ADDR]] 000018 08 A 0 0 8
 
-# RELR-HEADERS:      Dynamic section at offset 0x2e8 contains 16 entries
-# RELR-HEADERS:      0x0000000070000012 (AARCH64_AUTH_RELR) 0x2e0
-# RELR-HEADERS-NEXT: 0x0000000070000011 (AARCH64_AUTH_RELRSZ) 8 (bytes)
+# RELR-HEADERS:      Dynamic section at offset 0x310 contains 16 entries
+# RELR-HEADERS:      0x0000000070000012 (AARCH64_AUTH_RELR) 0x[[ADDR]]
+# RELR-HEADERS-NEXT: 0x0000000070000011 (AARCH64_AUTH_RELRSZ) 24 (bytes)
 # RELR-HEADERS-NEXT: 0x0000000070000013 (AARCH64_AUTH_RELRENT) 8 (bytes)
 
+# RUN: llvm-readobj -r --raw-relr %t2 | FileCheck --check-prefix=RAW-RELR %s
+
 ## SHT_RELR section contains address/bitmap entries
 ## encoding the offsets for relative relocation.
+
 # RAW-RELR:           Section ({{.+}}) .relr.auth.dyn {
-# RAW-RELR-NEXT:      0x303E8
+# RAW-RELR-NEXT:      0x30410
+# RAW-RELR-NEXT:      0xF
+# RAW-RELR-NEXT:      0x30452
 # RAW-RELR-NEXT:      }
 
+# RUN: llvm-readobj -r %t2 | FileCheck --check-prefix=RELR %s
+
 ## Decoded SHT_RELR section is same as UNPACKED,
 ## but contains only the relative relocations.
 ## Any relative relocations with odd offset stay in SHT_RELA.
 
 # RELR:      Section ({{.+}}) .rela.dyn {
-# RELR-NEXT:   0x30401 R_AARCH64_AUTH_RELATIVE - 0x2
-# RELR-NEXT:   0x303F0 R_AARCH64_AUTH_ABS64 zed2 0x0
-# RELR-NEXT:   0x303F8 R_AARCH64_AUTH_ABS64 bar2 0x0
+# RELR-NEXT:   0x30430 R_AARCH64_AUTH_RELATIVE - 0x123456789A
+# RELR-NEXT:   0x30449 R_AARCH64_AUTH_RELATIVE - 0x4
+# RELR-NEXT:   0x30438 R_AARCH64_AUTH_ABS64 zed2 0x0
+# RELR-NEXT:   0x30440 R_AARCH64_AUTH_ABS64 bar2 0x0
 # RELR-NEXT: }
 # RELR-NEXT: Section ({{.+}}) .relr.auth.dyn {
-# RELR-NEXT:   0x303E8 R_AARCH64_RELATIVE -
+# RELR-NEXT:   0x30410 R_AARCH64_RELATIVE -
+# RELR-NEXT:   0x30418 R_AARCH64_RELATIVE -
+# RELR-NEXT:   0x30420 R_AARCH64_RELATIVE -
+# RELR-NEXT:   0x30428 R_AARCH64_RELATIVE -
+# RELR-NEXT:   0x30452 R_AARCH64_RELATIVE -
 # RELR-NEXT: }
 
+# RUN: llvm-readobj -x .test %t2 | FileCheck --check-prefix=HEX %s
+
+# HEX:      Hex dump of section '.test':
+# HEX-NEXT: 0x00030410 01000000 2a000020 02000000 2b000000
+##                     ^^^^^^^^ Addend = 1
+##                              ^^^^ Discr = 42
+##                                    ^^ Key (bits 5..6) = DA
+##                                       ^^^^^^^^ Addend = 2
+##                                                ^^^^ Discr = 43
+##                                                      ^^ Key (bits 5..6) = IA
+# HEX-NEXT: 0x00030420 03000000 2c000080 78563412 2d000020
+##                     ^^^^^^^^ Addend = 3
+##                              ^^^^ Discr = 44
+##                                    ^^ Key (bits 5..6) = IA
+##                                    ^^ Addr diversity (bit 7) = true
+##                                       ^^^^^^^^ Addend = 0x12345678
+##                                                ^^^^ Discr = 45
+##                                                      ^^ Key (bits 5..6) = DA
+# HEX-NEXT: 0x00030430 00000000 2e000020 00000000 2f000020
+##                     ^^^^^^^^ No implicit addend (rela reloc)
+##                              ^^^^ Discr = 46
+##                                    ^^ Key (bits 5..6) = DA
+##                                       ^^^^^^^^ Addend = 0
+##                                                ^^^^ Discr = 47
+##                                                      ^^ Key (bits 5..6) = DA
+# HEX-NEXT: 0x00030440 00000000 30000000 00000000 00310000
+##                     ^^^^^^^^ Addend = 0
+##                              ^^^^ Discr = 48
+##                                    ^^ Key (bits 5..6) = IA
+##                                         ^^^^^^ ^^ No implicit addend (rela reloc)
+##                                                  ^^^^ Discr = 49
+# HEX-NEXT: 0x00030450 20000500 00003200 0020{{\ }}
+##                     ^^ Key (bits 5..6) = DA
+##                         ^^^^ ^^^^ Addend = 5
+##                                  ^^^^ Discr = 48
+##                                         ^^ Key (bits 5..6) = DA
+
 .section .test, "aw"
 .p2align 3
 .quad (__ehdr_start + 1)@AUTH(da,42)
-.quad zed2 at AUTH(da,42)
-.quad bar2 at AUTH(ia,42)
+.quad (__ehdr_start + 2)@AUTH(ia,43)
+.quad (__ehdr_start + 3)@AUTH(ia,44,addr)
+.quad (__ehdr_start + 0x12345678)@AUTH(da,45)
+.quad (__ehdr_start + 0x123456789A)@AUTH(da,46)
+.quad zed2 at AUTH(da,47)
+.quad bar2 at AUTH(ia,48)
+.byte 00
+.quad (__ehdr_start + 4)@AUTH(da,49)
 .byte 00
-.quad (__ehdr_start + 2)@AUTH(da,42)
+.quad (__ehdr_start + 5)@AUTH(da,50)

>From 2136ad1f2c8e92d52fb0b96a77c4cbc7828916b3 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Mon, 19 Feb 2024 17:22:33 -0800
Subject: [PATCH 12/13] Simplify RelocationScanner::processAux

---
 lld/ELF/Arch/AArch64.cpp |  2 +-
 lld/ELF/Relocations.cpp  | 48 +++++++++++++++++++---------------------
 2 files changed, 24 insertions(+), 26 deletions(-)

diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 79318637d85e9d..20f637e49f1874 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -205,7 +205,7 @@ bool AArch64::usesOnlyLowPageBits(RelType type) const {
 }
 
 RelType AArch64::getDynRel(RelType type) const {
-  if (type == R_AARCH64_ABS64)
+  if (type == R_AARCH64_ABS64 || type == R_AARCH64_AUTH_ABS64)
     return type;
   return R_AARCH64_NONE;
 }
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index f5e00e4a8de59e..926de8748e72da 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1137,29 +1137,6 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
                     (isa<EhInputSection>(sec) && config->emachine != EM_MIPS));
   if (canWrite) {
     RelType rel = target->getDynRel(type);
-    if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
-      std::lock_guard<std::mutex> lock(relocMutex);
-      // For a preemptible symbol, we can't use a relative relocation. For an
-      // undefined symbol, we can't compute offset at link-time and use a
-      // relative relocation. Use a symbolic relocation instead.
-      Partition &part = sec->getPartition();
-      if (sym.isPreemptible) {
-        part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
-      } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0 &&
-                 isInt<32>(sym.getVA(addend))) {
-        // Implicit addend is below 32-bits so we can use the compressed
-        // relative relocation section. The R_AARCH64_AUTH_RELATIVE
-        // has a smaller addend field as bits [63:32] encode the signing-schema.
-        sec->addReloc({expr, type, offset, addend, &sym});
-        part.relrAuthDyn->relocsVec[parallel::getThreadIndex()].push_back(
-            {sec, offset});
-      } else {
-        part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
-                                DynamicReloc::AddendOnlyWithTargetVA, sym,
-                                addend, R_ABS});
-      }
-      return;
-    }
     if (oneof<R_GOT, R_LOONGARCH_GOT>(expr) ||
         (rel == target->symbolicRel && !sym.isPreemptible)) {
       addRelativeReloc<true>(*sec, offset, sym, addend, expr, type);
@@ -1169,8 +1146,29 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
       if (config->emachine == EM_MIPS && rel == target->symbolicRel)
         rel = target->relativeRel;
       std::lock_guard<std::mutex> lock(relocMutex);
-      sec->getPartition().relaDyn->addSymbolReloc(rel, *sec, offset, sym,
-                                                  addend, type);
+      Partition &part = sec->getPartition();
+      if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
+        // For a preemptible symbol, we can't use a relative relocation. For an
+        // undefined symbol, we can't compute offset at link-time and use a
+        // relative relocation. Use a symbolic relocation instead.
+        if (sym.isPreemptible) {
+          part.relaDyn->addSymbolReloc(type, *sec, offset, sym, addend, type);
+        } else if (part.relrAuthDyn && sec->addralign >= 2 && offset % 2 == 0 &&
+                   isInt<32>(sym.getVA(addend))) {
+          // Implicit addend is below 32-bits so we can use the compressed
+          // relative relocation section. The R_AARCH64_AUTH_RELATIVE has a
+          // smaller addend field as bits [63:32] encode the signing-schema.
+          sec->addReloc({expr, type, offset, addend, &sym});
+          part.relrAuthDyn->relocsVec[parallel::getThreadIndex()].push_back(
+              {sec, offset});
+        } else {
+          part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
+                                  DynamicReloc::AddendOnlyWithTargetVA, sym,
+                                  addend, R_ABS});
+        }
+        return;
+      }
+      part.relaDyn->addSymbolReloc(rel, *sec, offset, sym, addend, type);
 
       // MIPS ABI turns using of GOT and dynamic relocations inside out.
       // While regular ABI uses dynamic relocations to fill up GOT entries

>From 9ea8c5c45f5615f5c09e54cb23290ae174b7c82a Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Mon, 19 Feb 2024 17:32:21 -0800
Subject: [PATCH 13/13] Fix error message in a read-only section when the
 symbol is local

---
 lld/ELF/Relocations.cpp               | 12 ++++--------
 lld/test/ELF/aarch64-reloc-pauth-ro.s | 17 ++++++++++-------
 2 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 926de8748e72da..eb4b38a99c72f8 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1191,16 +1191,12 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
     }
   }
 
-  if (config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64) {
-    errorOrWarn("relocation " + toString(type) + " against symbol '" +
-                toString(sym) + "'" + " in read-only section" +
-                getLocation(*sec, sym, offset));
-    return;
-  }
-
   // When producing an executable, we can perform copy relocations (for
   // STT_OBJECT) and canonical PLT (for STT_FUNC) if sym is defined by a DSO.
-  if (!config->shared && sym.isShared()) {
+  // Copy relocations/canonical PLT entries are unsupported for
+  // R_AARCH64_AUTH_ABS64.
+  if (!config->shared && sym.isShared() &&
+      !(config->emachine == EM_AARCH64 && type == R_AARCH64_AUTH_ABS64)) {
     if (!canDefineSymbolInExecutable(sym)) {
       errorOrWarn("cannot preempt symbol: " + toString(sym) +
                   getLocation(*sec, sym, offset));
diff --git a/lld/test/ELF/aarch64-reloc-pauth-ro.s b/lld/test/ELF/aarch64-reloc-pauth-ro.s
index 4e496d52ab548f..5bc9d805b481a7 100644
--- a/lld/test/ELF/aarch64-reloc-pauth-ro.s
+++ b/lld/test/ELF/aarch64-reloc-pauth-ro.s
@@ -5,15 +5,18 @@
 # RUN: llvm-mc -filetype=obj -triple=aarch64 %s -o %t.o
 # RUN: not ld.lld -pie %t.o %t.so -o %t2 2>&1 | FileCheck -DFILE=%t %s
 
-# CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'zed2' in read-only section
-# CHECK-NEXT: defined in [[FILE]].so
-# CHECK-NEXT: referenced by [[FILE]].o:(.test+0x0)
+# CHECK:      error: relocation R_AARCH64_AUTH_ABS64 cannot be used against symbol 'zed2'; recompile with -fPIC
+# CHECK-NEXT: >>> defined in [[FILE]].so
+# CHECK-NEXT: >>> referenced by [[FILE]].o:(.ro+0x0)
 
-# CHECK:      error: relocation R_AARCH64_AUTH_ABS64 against symbol 'bar2' in read-only section
-# CHECK-NEXT: defined in [[FILE]].so
-# CHECK-NEXT: referenced by [[FILE]].o:(.test+0x8)
+# CHECK:      error: relocation R_AARCH64_AUTH_ABS64 cannot be used against symbol 'bar2'; recompile with -fPIC
+# CHECK:      error: relocation R_AARCH64_AUTH_ABS64 cannot be used against local symbol; recompile with -fPIC
 
-.section .test, "a"
+foo:
+.type foo, @function
+
+.section .ro, "a"
 .p2align 3
 .quad zed2 at AUTH(da,42)
 .quad bar2 at AUTH(ia,42)
+.quad foo at AUTH(ia,42)



More information about the llvm-commits mailing list