[clang] [clang-tools-extra] [llvm] [lld] [lld][AArch64][ELF][PAC] Support AUTH relocations and AUTH ELF marking (PR #72714)

Daniil Kovalev via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 31 11:24:45 PST 2024


https://github.com/kovdan01 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 1/8] [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 048f0ec30ebd2..6828d3f57c10e 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 56229334f9a44..1b633a7984276 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 6bef09eeca015..4e8e9eb86ecf7 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 cc2c5916e05c2..44c8050f2c967 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 ab98d78fcf145..6a74ba7fb2099 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 fe3d7f419e84a..5b5e6b154d52f 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 2b32eb3a0fe35..fa7589806a7b5 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 3a9f4ba886f6b..d183a547c6820 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 a84e4864ab0e5..f1b569daada66 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 0000000000000..0520b2f28631e
--- /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 0000000000000..db946fc4c3e55
--- /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 2/8] 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 4e8e9eb86ecf7..ca5a8b8d994a4 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 44c8050f2c967..d7ceaf476cf9b 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 b8ab1a28fa5a8..703c0aac6ea5a 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 0520b2f28631e..9060eb71f8175 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 3/8] 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 1b633a7984276..e2a3cb2a61e93 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 ca5a8b8d994a4..6ab93c74bc645 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 af2544c3fa0f7..81e743d67dabd 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 db946fc4c3e55..26cc2d779e748 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 4/8] 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 5/8] 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 26cc2d779e748..79e6e4246cc45 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 6/8] 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 166407d573252..53f638ae2f854 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 0000000000000..80afb921a5c26
--- /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 7/8] 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 f17ec7759482c..faf7dcd2d5e81 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 8/8] 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 6e8191f7b4f55..16ab213b60234 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 79fe636cc09ef..c36f08e26c2a7 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 9060eb71f8175..4d1b9d9164004 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



More information about the llvm-commits mailing list