[lld] [llvm] [lld][AArch64][Build Attributes] Add support for converting AArch64 Build Attributes to GNU Properties (PR #131990)

via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 20 03:00:27 PDT 2025


https://github.com/sivan-shani updated https://github.com/llvm/llvm-project/pull/131990

>From f98c952a819a5f77648d2243276e5443053a8768 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Tue, 18 Mar 2025 18:55:26 +0000
Subject: [PATCH 01/19] [lld][AArch64][Build Attributes] Add support for
 converting AArch64 Build Attributes to GNU Properties

This patch enables `lld` to read AArch64 Build Attributes and convert them into
GNU Properties.

Changes:
- Parses AArch64 Build Attributes from input object files.
- Converts known attributes into corresponding GNU Properties.
- Merges attributes when linking multiple objects.
---
 lld/ELF/Config.h                              |   5 +
 lld/ELF/InputFiles.cpp                        | 243 +++++++++++++++++-
 lld/ELF/InputFiles.h                          |   3 +
 .../llvm/Support/ELFAttrParserExtended.h      |   5 +
 llvm/include/llvm/Support/ELFAttributes.h     |   8 +-
 .../build-attributes-to-gnu_properties-2.s    |  10 +
 .../build-attributes-to-gnu_properties-3.s    |  10 +
 .../build-attributes-to-gnu_properties-1.s    |  21 ++
 8 files changed, 292 insertions(+), 13 deletions(-)
 create mode 100644 llvm/test/tools/llvm-readobj/ELF/AArch64/Inputs/build-attributes-to-gnu_properties-2.s
 create mode 100644 llvm/test/tools/llvm-readobj/ELF/AArch64/Inputs/build-attributes-to-gnu_properties-3.s
 create mode 100644 llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-to-gnu_properties-1.s

diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index e07c7dd4ca1b6..9969a9dec5c35 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -24,6 +24,7 @@
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Compression.h"
+#include "llvm/Support/ELFAttributes.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/GlobPattern.h"
@@ -694,6 +695,10 @@ struct Ctx : CommonLinkerContext {
   llvm::raw_fd_ostream openAuxiliaryFile(llvm::StringRef, std::error_code &);
 
   ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
+
+  // AArch64 Build Attributes data
+  std::optional<llvm::BuildAttributeSubSection> mergedPauthSubSection;
+  std::optional<llvm::BuildAttributeSubSection> mergedFAndBSubSection;
 };
 
 // The first two elements of versionDefinitions represent VER_NDX_LOCAL and
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 5f6d2b6b647ee..7ae91729ee4df 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -20,16 +20,21 @@
 #include "lld/Common/DWARF.h"
 #include "llvm/ADT/CachedHashString.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/LTO/LTO.h"
 #include "llvm/Object/IRObjectFile.h"
+#include "llvm/Support/AArch64AttributeParser.h"
 #include "llvm/Support/ARMAttributeParser.h"
 #include "llvm/Support/ARMBuildAttributes.h"
+#include "llvm/Support/ELFAttributes.h"
 #include "llvm/Support/Endian.h"
+#include "llvm/Support/Errc.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/RISCVAttributeParser.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
+#include <cassert>
 #include <optional>
 
 using namespace llvm;
@@ -207,6 +212,166 @@ static void updateSupportedARMFeatures(Ctx &ctx,
   ctx.arg.armHasThumb2ISA |= thumb && *thumb >= ARMBuildAttrs::AllowThumb32;
 }
 
+// Sanitize pauth values
+static void sanitizePauthSubSection(
+    Ctx &ctx, std::optional<llvm::BuildAttributeSubSection> &pauthSubSection,
+    InputSection isec) {
+  /*
+    Incomplete data: ignore
+  */
+  if (!pauthSubSection)
+    return;
+  // Currently there are 2 known tags defined for the pauth subsection,
+  // however, user is allowed to add other, unknown tag. If such tags exists,
+  // remove them. (no need to check for duplicates, they should not be possible)
+  pauthSubSection->Content.erase(
+      std::remove_if(pauthSubSection->Content.begin(),
+                     pauthSubSection->Content.end(),
+                     [](const BuildAttributeItem &item) {
+                       return item.Tag != 1 && item.Tag != 2;
+                     }),
+      pauthSubSection->Content.end());
+
+  if (pauthSubSection->Content.size() < 2) {
+    if (0 == pauthSubSection->Content.size())
+      Warn(ctx) << &isec
+                << ": AArch64 Build Attributes: empty 'aeabi_pauthabi' "
+                   "subsection detected; ignoring subsection";
+    if (1 == pauthSubSection->Content.size()) {
+      if (1 == pauthSubSection->Content[0].Tag)
+        Warn(ctx)
+            << &isec
+            << ": AArch64 Build Attributes: 'aeabi_pauthabi' subsection "
+               "contains only an ID (scheme missing); ignoring subsection";
+      if (2 == pauthSubSection->Content[0].Tag)
+        Warn(ctx) << &isec
+                  << ": AArch64 Build Attributes: 'aeabi_pauthabi' subsection "
+                     "contains only a scheme (ID missing); ignoring subsection";
+    }
+    pauthSubSection = std::nullopt;
+    return;
+  }
+  // printvec(*pauthSubSection);
+  assert(2 == pauthSubSection->Content.size() && "vector size should be 2");
+  std::sort(pauthSubSection->Content.begin(), pauthSubSection->Content.end(),
+            [](const auto &a, const auto &b) { return a.Tag < b.Tag; });
+  assert(1 == pauthSubSection->Content[0].Tag && "first tag should be 1");
+  assert(2 == pauthSubSection->Content[1].Tag && "first tag should be 2");
+}
+
+// Sanitize features bits
+static void sanitizeFAndBSubSection(
+    std::optional<llvm::BuildAttributeSubSection> &fAndBSubSection) {
+  /*
+    Same as gnu properties: treat a missing 'aeabi_feature_and_bits' feature as
+    being set to 0
+  */
+  if (!fAndBSubSection) {
+    fAndBSubSection.emplace("aeabi_feature_and_bits", 1, 0,
+                            SmallVector<BuildAttributeItem, 64>());
+  } else {
+    // Currently there are 3 known tags defined for the features and bits
+    // subsection, however, user is allowed to add other, unknown tag. If such
+    // tags exists, remove them. (duplicates are not possible)
+    fAndBSubSection->Content.erase(
+        std::remove_if(fAndBSubSection->Content.begin(),
+                       fAndBSubSection->Content.end(),
+                       [](const BuildAttributeItem &item) {
+                         return item.Tag != 0 && item.Tag != 1 && item.Tag != 2;
+                       }),
+        fAndBSubSection->Content.end());
+  }
+
+  constexpr unsigned tagBTI = 0, tagPAC = 1, tagGCS = 2;
+  // Find missing tags
+  std::set<unsigned> requiredTags = {tagBTI, tagPAC, tagGCS};
+  for (const auto &item : fAndBSubSection->Content)
+    requiredTags.erase(item.Tag);
+
+  // Add missing tags
+  for (const auto &tag : requiredTags)
+    fAndBSubSection->Content.push_back(
+        BuildAttributeItem(BuildAttributeItem::NumericAttribute, tag, 0, ""));
+
+  assert(3 == fAndBSubSection->Content.size() && "vector size should be 3");
+  std::sort(fAndBSubSection->Content.begin(), fAndBSubSection->Content.end(),
+            [](const auto &a, const auto &b) { return a.Tag < b.Tag; });
+  assert(0 == fAndBSubSection->Content[0].Tag && "first tag should be 0");
+  assert(1 == fAndBSubSection->Content[1].Tag && "first tag should be 1");
+  assert(2 == fAndBSubSection->Content[2].Tag && "first tag should be 2");
+}
+
+static std::array<std::optional<llvm::BuildAttributeSubSection>, 2>
+extractBuildAttributesSubsection(
+    Ctx &ctx,
+    const SmallVector<llvm::BuildAttributeSubSection, 8>
+        &buildAttributesSubsections,
+    InputSection isec) {
+
+  std::optional<llvm::BuildAttributeSubSection> newPauthSubSection;
+  std::optional<llvm::BuildAttributeSubSection> newFAndBSubSection;
+
+  for (const auto &newSubSection : buildAttributesSubsections) {
+    if (newPauthSubSection && newFAndBSubSection)
+      break;
+    if ("aeabi_pauthabi" == newSubSection.Name) {
+      newPauthSubSection.emplace(newSubSection);
+      continue;
+    }
+    if ("aeabi_feature_and_bits" == newSubSection.Name) {
+      newFAndBSubSection.emplace(newSubSection);
+    }
+  }
+  sanitizePauthSubSection(ctx, newPauthSubSection, isec);
+  sanitizeFAndBSubSection(newFAndBSubSection);
+
+  return {std::move(newPauthSubSection), std::move(newFAndBSubSection)};
+}
+
+// Merge AArch64 Build Attributes subsection
+static void mergeAArch64BuildAttributes(
+    Ctx &ctx,
+    const std::array<std::optional<llvm::BuildAttributeSubSection>, 2>
+        &buildAttributesSubsections,
+    InputSection isec) {
+
+  auto [newPauthSubSection, newFAndBSubSection] = buildAttributesSubsections;
+
+  if (ctx.mergedPauthSubSection == std::nullopt) {
+    ctx.mergedPauthSubSection = newPauthSubSection;
+  }
+
+  if (ctx.mergedFAndBSubSection == std::nullopt)
+    ctx.mergedFAndBSubSection = newFAndBSubSection;
+
+  if (newPauthSubSection) {
+    // Since sanitizePauthSubSection sorts, we know that both vectors align.
+    // Merge pauth (values has to match)
+    if ((ctx.mergedPauthSubSection->Content[0].IntValue !=
+         newPauthSubSection->Content[0].IntValue) ||
+        ctx.mergedPauthSubSection->Content[1].IntValue !=
+            newPauthSubSection->Content[1].IntValue) {
+      ctx.mergedPauthSubSection->Content[0].IntValue =
+          std::numeric_limits<unsigned>::max();
+      ctx.mergedPauthSubSection->Content[1].IntValue =
+          std::numeric_limits<unsigned>::max();
+      Warn(ctx)
+          << &isec
+          << ": AArch64 Build Attributes: mismatch in 'aeabi_pauthabi' values "
+             "detected; marking 'aeabi_pauthabi' as invalid for this project";
+    }
+  }
+
+  // Since sanitizeFAndBSubSection sorts, we know that both vectors align.
+  // Merge Features and Bits
+  ctx.mergedFAndBSubSection->Content[0].IntValue &=
+      newFAndBSubSection->Content[0].IntValue;
+  ctx.mergedFAndBSubSection->Content[1].IntValue &=
+      newFAndBSubSection->Content[1].IntValue;
+  ctx.mergedFAndBSubSection->Content[2].IntValue &=
+      newFAndBSubSection->Content[2].IntValue;
+}
+
 InputFile::InputFile(Ctx &ctx, Kind k, MemoryBufferRef m)
     : ctx(ctx), mb(m), groupId(ctx.driver.nextGroupId), fileKind(k) {
   // All files within the same --{start,end}-group get the same group ID.
@@ -552,6 +717,7 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
   // done in parallel.
   ArrayRef<Elf_Shdr> objSections = getELFShdrs<ELFT>();
   StringRef shstrtab = CHECK2(obj.getSectionStringTable(objSections), this);
+  bool hasGnuProperties = false;
   uint64_t size = objSections.size();
   sections.resize(size);
   for (size_t i = 0; i != size; ++i) {
@@ -574,9 +740,12 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
                            .try_emplace(CachedHashStringRef(signature), this)
                            .second;
       if (keepGroup) {
-        if (!ctx.arg.resolveGroups)
-          sections[i] = createInputSection(
-              i, sec, check(obj.getSectionName(sec, shstrtab)));
+        if (!ctx.arg.resolveGroups) {
+          StringRef name = check(obj.getSectionName(sec, shstrtab));
+          if (name == ".note.gnu.property")
+            hasGnuProperties = true;
+          sections[i] = createInputSection(i, sec, name);
+        }
       } else {
         // Otherwise, discard group members.
         for (uint32_t secIndex : entries.slice(1)) {
@@ -638,27 +807,77 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
         }
       }
       break;
-    case EM_AARCH64:
-      // FIXME: BuildAttributes have been implemented in llvm, but not yet in
-      // lld. Remove the section so that it does not accumulate in the output
-      // file. When support is implemented we expect not to output a build
-      // attributes section in files of type ET_EXEC or ET_SHARED, but ld -r
-      // ouptut will need a single merged attributes section.
-      if (sec.sh_type == SHT_AARCH64_ATTRIBUTES)
+    case EM_AARCH64: {
+      // The specification states that if a file contains both GNU properties
+      // and AArch64 build attributes, they must be identical. Therefore, if a
+      // file contains GNU properties, the AArch64 build attributes are ignored.
+      // If a file does not contain GNU properties, we leverage the existing GNU
+      // properties mechanism by populating the corresponding data structures,
+      // which will later be handled by Driver.cpp::readSecurityNotes. This
+      // ensures that AArch64 build attributes are represented in the linked
+      // object file as GNU properties, which are already supported by the Linux
+      // kernel and the dynamic dispatcher.
+      if (sec.sh_type == SHT_AARCH64_ATTRIBUTES) {
+        StringRef name = check(obj.getSectionName(sec, shstrtab));
+        AArch64AttributeParser attributes;
+        ArrayRef<uint8_t> contents = check(obj.getSectionContents(sec));
+        if (Error e = attributes.parse(contents, ELFT::Endianness)) {
+          InputSection isec(*this, sec, name);
+          Warn(ctx) << &isec << ": " << std::move(e);
+        } else {
+          // for functions that has to warn/err/report
+          InputSection isec(*this, sec, name);
+          const SmallVector<llvm::BuildAttributeSubSection, 8>
+              buildAttributesSubSections =
+                  attributes.getBuildAttributesSection();
+          auto subsections = extractBuildAttributesSubsection(
+              ctx, buildAttributesSubSections, isec);
+          mergeAArch64BuildAttributes(ctx, subsections, isec);
+          if (!hasGnuProperties) {
+            ObjFile<ELFT> &f = *this;
+            auto [pauthSubSection, fAndBSubSection] = subsections;
+            if (pauthSubSection) {
+              assert(
+                  (pauthSubSection->Content.size() == 2) &&
+                  "pauthSubSection must contain exactly two build attributes");
+              // sanitizePauthSubSection already sorts
+              f.aarch64PauthAbiCoreInfoStorage =
+                  std::make_unique<std::array<uint8_t, 16>>();
+              uint64_t values[2] = {
+                  static_cast<uint64_t>(pauthSubSection->Content[0].IntValue),
+                  static_cast<uint64_t>(pauthSubSection->Content[1].IntValue)};
+              std::memcpy(f.aarch64PauthAbiCoreInfoStorage->data(), &values[0],
+                          sizeof(values));
+              f.aarch64PauthAbiCoreInfo = *f.aarch64PauthAbiCoreInfoStorage;
+            }
+            if (fAndBSubSection) {
+              assert((fAndBSubSection->Content.size() == 3) &&
+                     "fAndBSubSection must contain exactly three build "
+                     "attributes");
+              // sanitizeFAndBSubSection already sorts
+              f.andFeatures = 0;
+              f.andFeatures |= (fAndBSubSection->Content[0].IntValue) << 0;
+              f.andFeatures |= (fAndBSubSection->Content[1].IntValue) << 1;
+              f.andFeatures |= (fAndBSubSection->Content[2].IntValue) << 2;
+            }
+          }
+        }
         sections[i] = &InputSection::discarded;
       // Producing a static binary with MTE globals is not currently supported,
       // remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as they're unused
-      // medatada, and we don't want them to end up in the output file for
+      // metadata, and we don't want them to end up in the output file for
       // static executables.
       if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
           !canHaveMemtagGlobals(ctx))
         sections[i] = &InputSection::discarded;
-      break;
+      }
     }
+    break;
   }
 
   // Read a symbol table.
   initializeSymbols(obj);
+  }
 }
 
 // Sections with SHT_GROUP and comdat bits define comdat section groups.
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 808cb5d24079f..8164594e9c41a 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -19,6 +19,7 @@
 #include "llvm/Object/ELF.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/Threading.h"
+#include <memory>
 
 namespace llvm {
 struct DILineInfo;
@@ -239,9 +240,11 @@ class ELFFileBase : public InputFile {
 public:
   // Name of source file obtained from STT_FILE, if present.
   StringRef sourceFile;
+  std::unique_ptr<std::string> sourceFileStorage;
   uint32_t andFeatures = 0;
   bool hasCommonSyms = false;
   ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;
+  std::unique_ptr<std::array<uint8_t, 16>> aarch64PauthAbiCoreInfoStorage;
 };
 
 // .o file.
diff --git a/llvm/include/llvm/Support/ELFAttrParserExtended.h b/llvm/include/llvm/Support/ELFAttrParserExtended.h
index 68f45fb7f368a..6ae43fb0ed75a 100644
--- a/llvm/include/llvm/Support/ELFAttrParserExtended.h
+++ b/llvm/include/llvm/Support/ELFAttrParserExtended.h
@@ -38,6 +38,11 @@ class ELFExtendedAttrParser : public ELFAttributeParser {
   virtual ~ELFExtendedAttrParser() { static_cast<void>(!Cursor.takeError()); }
   Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian) override;
 
+  const SmallVector<BuildAttributeSubSection, 8> &
+  getBuildAttributesSection() const {
+    return SubSectionVec;
+  }
+
   std::optional<unsigned> getAttributeValue(unsigned Tag) const override;
   std::optional<unsigned> getAttributeValue(StringRef BuildAttrSubsectionName,
                                             unsigned Tag) const override;
diff --git a/llvm/include/llvm/Support/ELFAttributes.h b/llvm/include/llvm/Support/ELFAttributes.h
index 6782aec6050ad..95e4598b2a2b4 100644
--- a/llvm/include/llvm/Support/ELFAttributes.h
+++ b/llvm/include/llvm/Support/ELFAttributes.h
@@ -32,14 +32,20 @@ struct BuildAttributeItem {
   unsigned Tag;
   unsigned IntValue;
   std::string StringValue;
+  BuildAttributeItem(){};
   BuildAttributeItem(Types Ty, unsigned Tg, unsigned IV, std::string SV)
       : Type(Ty), Tag(Tg), IntValue(IV), StringValue(std::move(SV)) {}
 };
 struct BuildAttributeSubSection {
-  StringRef Name;
+  std::string Name;
   unsigned IsOptional;
   unsigned ParameterType;
   SmallVector<BuildAttributeItem, 64> Content;
+  BuildAttributeSubSection(){};
+  BuildAttributeSubSection(const std::string &N, unsigned Opt, unsigned Type,
+                           SmallVector<BuildAttributeItem, 64> &&Content)
+      : Name(N), IsOptional(Opt), ParameterType(Type),
+        Content(std::move(Content)) {}
 };
 
 // Tag to string: ELF extended build attribute section
diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/Inputs/build-attributes-to-gnu_properties-2.s b/llvm/test/tools/llvm-readobj/ELF/AArch64/Inputs/build-attributes-to-gnu_properties-2.s
new file mode 100644
index 0000000000000..d3e677eee0360
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/Inputs/build-attributes-to-gnu_properties-2.s
@@ -0,0 +1,10 @@
+# REQUIRES: aarch64
+
+.section .note.gnu.property, "a"
+.aeabi_subsection aeabi_pauthabi, required, uleb128
+.aeabi_attribute Tag_PAuth_Platform, 49
+.aeabi_attribute Tag_PAuth_Schema, 19
+.aeabi_subsection aeabi_feature_and_bits, optional, uleb128
+.aeabi_attribute Tag_Feature_BTI, 1
+.aeabi_attribute Tag_Feature_PAC, 0
+.aeabi_attribute Tag_Feature_GCS, 1
diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/Inputs/build-attributes-to-gnu_properties-3.s b/llvm/test/tools/llvm-readobj/ELF/AArch64/Inputs/build-attributes-to-gnu_properties-3.s
new file mode 100644
index 0000000000000..8763000b786c0
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/Inputs/build-attributes-to-gnu_properties-3.s
@@ -0,0 +1,10 @@
+# REQUIRES: aarch64
+
+.section .note.gnu.property, "a"
+.aeabi_subsection aeabi_pauthabi, required, uleb128
+.aeabi_attribute Tag_PAuth_Platform, 49
+.aeabi_attribute Tag_PAuth_Schema, 19
+.aeabi_subsection aeabi_feature_and_bits, optional, uleb128
+.aeabi_attribute Tag_Feature_BTI, 1
+.aeabi_attribute Tag_Feature_PAC, 1
+.aeabi_attribute Tag_Feature_GCS, 0
diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-to-gnu_properties-1.s b/llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-to-gnu_properties-1.s
new file mode 100644
index 0000000000000..5ff5f12269333
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-to-gnu_properties-1.s
@@ -0,0 +1,21 @@
+# RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o %t1.o
+# RUN: llvm-mc -triple=aarch64 -filetype=obj %p/Inputs/build-attributes-to-gnu_properties-2.s -o %t2.o
+# RUN: llvm-mc -triple=aarch64 -filetype=obj %p/Inputs/build-attributes-to-gnu_properties-3.s -o %t3.o
+# RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t.merged.o
+# RUN: llvm-readelf -n %t.merged.o | FileCheck %s
+
+# CHECK: Displaying notes found in: .note.gnu.property
+# CHECK-NEXT:  Owner                Data size 	Description
+# CHECK-NEXT:  GNU                  0x00000028	NT_GNU_PROPERTY_TYPE_0 (property note)
+# CHECK-NEXT:    Properties:    aarch64 feature: BTI
+# CHECK-NEXT:        AArch64 PAuth ABI core info: platform 0x31 (unknown), version 0x13
+
+
+.section .note.gnu.property, "a"
+.aeabi_subsection aeabi_pauthabi, required, uleb128
+.aeabi_attribute Tag_PAuth_Platform, 49
+.aeabi_attribute Tag_PAuth_Schema, 19
+.aeabi_subsection aeabi_feature_and_bits, optional, uleb128
+.aeabi_attribute Tag_Feature_BTI, 1
+.aeabi_attribute Tag_Feature_PAC, 1
+.aeabi_attribute Tag_Feature_GCS, 1

>From d4299e93dc4ebd7de490d898d059d00809527b7a Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 19 Mar 2025 10:24:46 +0000
Subject: [PATCH 02/19] fix formatting

---
 lld/ELF/InputFiles.cpp | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 7ae91729ee4df..cada5c63549c7 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -863,16 +863,15 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
           }
         }
         sections[i] = &InputSection::discarded;
-      // Producing a static binary with MTE globals is not currently supported,
-      // remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as they're unused
-      // metadata, and we don't want them to end up in the output file for
-      // static executables.
-      if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
-          !canHaveMemtagGlobals(ctx))
-        sections[i] = &InputSection::discarded;
+        // Producing a static binary with MTE globals is not currently
+        // supported, remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as
+        // they're unused metadata, and we don't want them to end up in the
+        // output file for static executables.
+        if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
+            !canHaveMemtagGlobals(ctx))
+          sections[i] = &InputSection::discarded;
       }
-    }
-    break;
+    } break;
   }
 
   // Read a symbol table.

>From 783dbf97a61e01217a0a4415e164c9b658ea33eb Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 19 Mar 2025 10:31:32 +0000
Subject: [PATCH 03/19] remove stand alone condition out of braces of prevoius
 condition

---
 lld/ELF/InputFiles.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index cada5c63549c7..825da3c6923b3 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -863,14 +863,14 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
           }
         }
         sections[i] = &InputSection::discarded;
+      }
         // Producing a static binary with MTE globals is not currently
         // supported, remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as
         // they're unused metadata, and we don't want them to end up in the
         // output file for static executables.
-        if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
-            !canHaveMemtagGlobals(ctx))
-          sections[i] = &InputSection::discarded;
-      }
+      if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
+          !canHaveMemtagGlobals(ctx))
+        sections[i] = &InputSection::discarded;
     } break;
   }
 

>From 5dfca32cc8dd8ce358323d813bb4e2fefdd6a38b Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 19 Mar 2025 10:38:22 +0000
Subject: [PATCH 04/19] formatting

---
 lld/ELF/InputFiles.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 825da3c6923b3..5fdf0c20ae676 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -864,10 +864,10 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
         }
         sections[i] = &InputSection::discarded;
       }
-        // Producing a static binary with MTE globals is not currently
-        // supported, remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as
-        // they're unused metadata, and we don't want them to end up in the
-        // output file for static executables.
+      // Producing a static binary with MTE globals is not currently
+      // supported, remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as
+      // they're unused metadata, and we don't want them to end up in the
+      // output file for static executables.
       if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
           !canHaveMemtagGlobals(ctx))
         sections[i] = &InputSection::discarded;

>From 8b6377a1bd1e368c372031c8e573e892f86276c6 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 19 Mar 2025 10:49:51 +0000
Subject: [PATCH 05/19] formatting

---
 llvm/include/llvm/Support/ELFAttributes.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/Support/ELFAttributes.h b/llvm/include/llvm/Support/ELFAttributes.h
index 95e4598b2a2b4..8171043288713 100644
--- a/llvm/include/llvm/Support/ELFAttributes.h
+++ b/llvm/include/llvm/Support/ELFAttributes.h
@@ -63,7 +63,8 @@ enum AttrType : unsigned { File = 1, Section = 2, Symbol = 3 };
 
 StringRef attrTypeAsString(unsigned attr, TagNameMap tagNameMap,
                            bool hasTagPrefix = true);
-std::optional<unsigned> attrTypeFromString(StringRef tag, TagNameMap tagNameMap);
+std::optional<unsigned> attrTypeFromString(StringRef tag,
+                                           TagNameMap tagNameMap);
 
 // Magic numbers for ELF attributes.
 enum AttrMagic { Format_Version = 0x41 };

>From 9d81bc014afdd72249f2c05be520980ec898755b Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 19 Mar 2025 10:57:50 +0000
Subject: [PATCH 06/19] formatting

---
 lld/ELF/Config.h       | 5 +++--
 lld/ELF/InputFiles.cpp | 6 +++---
 lld/ELF/InputFiles.h   | 3 +--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 9969a9dec5c35..ba99c386d91c6 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -132,7 +132,7 @@ enum class SeparateSegmentKind { None, Code, Loadable };
 enum class GnuStackKind { None, Exec, NoExec };
 
 // For --lto=
-enum LtoKind : uint8_t {UnifiedThin, UnifiedRegular, Default};
+enum LtoKind : uint8_t { UnifiedThin, UnifiedRegular, Default };
 
 // For -z gcs=
 enum class GcsPolicy { Implicit, Never, Always };
@@ -196,7 +196,8 @@ struct Config {
   uint8_t osabi = 0;
   uint32_t andFeatures = 0;
   llvm::CachePruningPolicy thinLTOCachePolicy;
-  llvm::SetVector<llvm::CachedHashString> dependencyFiles; // for --dependency-file
+  llvm::SetVector<llvm::CachedHashString>
+      dependencyFiles; // for --dependency-file
   llvm::StringMap<uint64_t> sectionStartMap;
   llvm::StringRef bfdname;
   llvm::StringRef chroot;
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 5fdf0c20ae676..5bb5aaad06aaf 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -872,10 +872,10 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
           !canHaveMemtagGlobals(ctx))
         sections[i] = &InputSection::discarded;
     } break;
-  }
+    }
 
-  // Read a symbol table.
-  initializeSymbols(obj);
+    // Read a symbol table.
+    initializeSymbols(obj);
   }
 }
 
diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 8164594e9c41a..e15632b6c8081 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -200,7 +200,7 @@ class ELFFileBase : public InputFile {
   }
   MutableArrayRef<Symbol *> getMutableGlobalSymbols() {
     return llvm::MutableArrayRef(symbols.get() + firstGlobal,
-                                     numSymbols - firstGlobal);
+                                 numSymbols - firstGlobal);
   }
 
   template <typename ELFT> typename ELFT::ShdrRange getELFShdrs() const {
@@ -271,7 +271,6 @@ template <class ELFT> class ObjFile : public ELFFileBase {
 
   uint32_t getSectionIndex(const Elf_Sym &sym) const;
 
-
   // Pointer to this input file's .llvm_addrsig section, if it has one.
   const Elf_Shdr *addrsigSec = nullptr;
 

>From 9c8f950b9dbab8cfe9157a6d86c48070c590de6e Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 19 Mar 2025 11:11:21 +0000
Subject: [PATCH 07/19] format

---
 llvm/include/llvm/Support/ELFAttributes.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/include/llvm/Support/ELFAttributes.h b/llvm/include/llvm/Support/ELFAttributes.h
index 8171043288713..1054ebccb9eef 100644
--- a/llvm/include/llvm/Support/ELFAttributes.h
+++ b/llvm/include/llvm/Support/ELFAttributes.h
@@ -36,6 +36,7 @@ struct BuildAttributeItem {
   BuildAttributeItem(Types Ty, unsigned Tg, unsigned IV, std::string SV)
       : Type(Ty), Tag(Tg), IntValue(IV), StringValue(std::move(SV)) {}
 };
+
 struct BuildAttributeSubSection {
   std::string Name;
   unsigned IsOptional;

>From 94bebe091d34e6fc43ad8a29c888d70e55f72599 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 19 Mar 2025 11:19:04 +0000
Subject: [PATCH 08/19] format

---
 llvm/include/llvm/Support/ELFAttributes.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/Support/ELFAttributes.h b/llvm/include/llvm/Support/ELFAttributes.h
index 1054ebccb9eef..f3a304babb0ec 100644
--- a/llvm/include/llvm/Support/ELFAttributes.h
+++ b/llvm/include/llvm/Support/ELFAttributes.h
@@ -32,7 +32,7 @@ struct BuildAttributeItem {
   unsigned Tag;
   unsigned IntValue;
   std::string StringValue;
-  BuildAttributeItem(){};
+  BuildAttributeItem() {};
   BuildAttributeItem(Types Ty, unsigned Tg, unsigned IV, std::string SV)
       : Type(Ty), Tag(Tg), IntValue(IV), StringValue(std::move(SV)) {}
 };
@@ -42,7 +42,7 @@ struct BuildAttributeSubSection {
   unsigned IsOptional;
   unsigned ParameterType;
   SmallVector<BuildAttributeItem, 64> Content;
-  BuildAttributeSubSection(){};
+  BuildAttributeSubSection() {};
   BuildAttributeSubSection(const std::string &N, unsigned Opt, unsigned Type,
                            SmallVector<BuildAttributeItem, 64> &&Content)
       : Name(N), IsOptional(Opt), ParameterType(Type),

>From e73a6bd8fce570feb8e55a0898a6dd6eea3ae4f5 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 19 Mar 2025 17:19:26 +0000
Subject: [PATCH 09/19] fix: readig symbol table should be done once per file,
 not per symbol section!

---
 lld/ELF/InputFiles.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 5bb5aaad06aaf..5c515940e94d6 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -873,10 +873,9 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
         sections[i] = &InputSection::discarded;
     } break;
     }
-
-    // Read a symbol table.
-    initializeSymbols(obj);
   }
+  // Read a symbol table.
+  initializeSymbols(obj);
 }
 
 // Sections with SHT_GROUP and comdat bits define comdat section groups.

>From 60a5eeae30ef6b1c60b05da7d88e9c4894551178 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 08:38:00 +0000
Subject: [PATCH 10/19] remove memory header

---
 lld/ELF/InputFiles.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index e15632b6c8081..70203a9ce6259 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -19,7 +19,6 @@
 #include "llvm/Object/ELF.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/Threading.h"
-#include <memory>
 
 namespace llvm {
 struct DILineInfo;

>From 9052abfb5ab54733ed021dd6be0695e40ce50469 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 08:42:53 +0000
Subject: [PATCH 11/19] undo unrealted formatting

---
 lld/ELF/InputFiles.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 5c515940e94d6..b228023c2bcc4 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -864,10 +864,10 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
         }
         sections[i] = &InputSection::discarded;
       }
-      // Producing a static binary with MTE globals is not currently
-      // supported, remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as
-      // they're unused metadata, and we don't want them to end up in the
-      // output file for static executables.
+      // Producing a static binary with MTE globals is not currently supported,
+      // remove all SHT_AARCH64_MEMTAG_GLOBALS_STATIC sections as they're unused
+      // medatada, and we don't want them to end up in the output file for
+      // static executables.
       if (sec.sh_type == SHT_AARCH64_MEMTAG_GLOBALS_STATIC &&
           !canHaveMemtagGlobals(ctx))
         sections[i] = &InputSection::discarded;

>From 52869a11f32dab527268559703fad9baab456124 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 08:49:25 +0000
Subject: [PATCH 12/19] remove unused variable

---
 lld/ELF/InputFiles.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 70203a9ce6259..09e1525394253 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -239,7 +239,6 @@ class ELFFileBase : public InputFile {
 public:
   // Name of source file obtained from STT_FILE, if present.
   StringRef sourceFile;
-  std::unique_ptr<std::string> sourceFileStorage;
   uint32_t andFeatures = 0;
   bool hasCommonSyms = false;
   ArrayRef<uint8_t> aarch64PauthAbiCoreInfo;

>From 534e55ef2d12d587bc02a9bfba22c9e103e0b3f0 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 08:53:44 +0000
Subject: [PATCH 13/19] clarify what is being sanitized in comments

---
 lld/ELF/InputFiles.cpp | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index b228023c2bcc4..4797b6ec21dac 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -212,7 +212,12 @@ static void updateSupportedARMFeatures(Ctx &ctx,
   ctx.arg.armHasThumb2ISA |= thumb && *thumb >= ARMBuildAttrs::AllowThumb32;
 }
 
-// Sanitize pauth values
+// Sanitize pauth values.
+// Ensure that pauthSubSection is either std::nullopt or contains exactly two build attributes: ID and Scheme.
+// - Content[0]: ID, Content[1]: Scheme.
+// - Remove build attributes with unknown tags.
+// - Set pauthSubSection to std::nullopt if any required attributes are missing.
+// - Sort the content vector so that ID is at Content[0] and Scheme at Content[1].
 static void sanitizePauthSubSection(
     Ctx &ctx, std::optional<llvm::BuildAttributeSubSection> &pauthSubSection,
     InputSection isec) {
@@ -259,7 +264,12 @@ static void sanitizePauthSubSection(
   assert(2 == pauthSubSection->Content[1].Tag && "first tag should be 2");
 }
 
-// Sanitize features bits
+// Sanitize feature bits.
+// Ensure that fAndBSubSection always contains exactly three build attributes: BTI, PAC, and GCS.
+// - Content[0]: BTI, Content[1]: PAC, Content[2]: GCS.
+// - Remove build attributes with unknown tags.
+// - If any attribute is missing, add it with its value set to `0`.
+// - Sort the content vector so that Content[0] is BTI, Content[1] is PAC, and Content[2] is GCS.
 static void sanitizeFAndBSubSection(
     std::optional<llvm::BuildAttributeSubSection> &fAndBSubSection) {
   /*

>From 02a1fa7c2a4cffa8f8bc3c4e46d3b9eccec7449d Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 09:00:44 +0000
Subject: [PATCH 14/19] change SmallVector to SmallVectorImpl

---
 lld/ELF/InputFiles.cpp | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 4797b6ec21dac..16fb4ac354071 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -213,11 +213,13 @@ static void updateSupportedARMFeatures(Ctx &ctx,
 }
 
 // Sanitize pauth values.
-// Ensure that pauthSubSection is either std::nullopt or contains exactly two build attributes: ID and Scheme.
+// Ensure that pauthSubSection is either std::nullopt or contains exactly two
+// build attributes: ID and Scheme.
 // - Content[0]: ID, Content[1]: Scheme.
 // - Remove build attributes with unknown tags.
 // - Set pauthSubSection to std::nullopt if any required attributes are missing.
-// - Sort the content vector so that ID is at Content[0] and Scheme at Content[1].
+// - Sort the content vector so that ID is at Content[0] and Scheme at
+// Content[1].
 static void sanitizePauthSubSection(
     Ctx &ctx, std::optional<llvm::BuildAttributeSubSection> &pauthSubSection,
     InputSection isec) {
@@ -265,11 +267,13 @@ static void sanitizePauthSubSection(
 }
 
 // Sanitize feature bits.
-// Ensure that fAndBSubSection always contains exactly three build attributes: BTI, PAC, and GCS.
+// Ensure that fAndBSubSection always contains exactly three build attributes:
+// BTI, PAC, and GCS.
 // - Content[0]: BTI, Content[1]: PAC, Content[2]: GCS.
 // - Remove build attributes with unknown tags.
 // - If any attribute is missing, add it with its value set to `0`.
-// - Sort the content vector so that Content[0] is BTI, Content[1] is PAC, and Content[2] is GCS.
+// - Sort the content vector so that Content[0] is BTI, Content[1] is PAC, and
+// Content[2] is GCS.
 static void sanitizeFAndBSubSection(
     std::optional<llvm::BuildAttributeSubSection> &fAndBSubSection) {
   /*
@@ -314,7 +318,7 @@ static void sanitizeFAndBSubSection(
 static std::array<std::optional<llvm::BuildAttributeSubSection>, 2>
 extractBuildAttributesSubsection(
     Ctx &ctx,
-    const SmallVector<llvm::BuildAttributeSubSection, 8>
+    const SmallVectorImpl<llvm::BuildAttributeSubSection>
         &buildAttributesSubsections,
     InputSection isec) {
 

>From ec89018e0434a17114343b153d5ea4721fa567b1 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 09:15:27 +0000
Subject: [PATCH 15/19] undo unrelated formatting

---
 lld/ELF/Config.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index ba99c386d91c6..dcabc21c1337e 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -123,7 +123,7 @@ enum class SortSectionPolicy {
 enum class Target2Policy { Abs, Rel, GotRel };
 
 // For tracking ARM Float Argument PCS
-enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
+enum class ARMVFPArgKind {Default, Base, VFP, ToolChain};
 
 // For -z noseparate-code, -z separate-code and -z separate-loadable-segments.
 enum class SeparateSegmentKind { None, Code, Loadable };
@@ -196,8 +196,7 @@ struct Config {
   uint8_t osabi = 0;
   uint32_t andFeatures = 0;
   llvm::CachePruningPolicy thinLTOCachePolicy;
-  llvm::SetVector<llvm::CachedHashString>
-      dependencyFiles; // for --dependency-file
+  llvm::SetVector<llvm::CachedHashString> dependencyFiles; // for --dependency-file
   llvm::StringMap<uint64_t> sectionStartMap;
   llvm::StringRef bfdname;
   llvm::StringRef chroot;

>From 7292c3616cb65db9432950f81b85a8aeab3b5213 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 09:33:46 +0000
Subject: [PATCH 16/19] fix formating fail

---
 lld/ELF/Config.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index dcabc21c1337e..7d83336e0d95d 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -123,7 +123,7 @@ enum class SortSectionPolicy {
 enum class Target2Policy { Abs, Rel, GotRel };
 
 // For tracking ARM Float Argument PCS
-enum class ARMVFPArgKind {Default, Base, VFP, ToolChain};
+enum class ARMVFPArgKind { Default, Base, VFP, ToolChain };
 
 // For -z noseparate-code, -z separate-code and -z separate-loadable-segments.
 enum class SeparateSegmentKind { None, Code, Loadable };

>From d0267260023252b4d7cba618baf1f969f6f48814 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 09:41:24 +0000
Subject: [PATCH 17/19] use  instead of asigning auto f =(*this)

---
 lld/ELF/InputFiles.cpp | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 16fb4ac354071..18f5288daec74 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -848,31 +848,34 @@ template <class ELFT> void ObjFile<ELFT>::parse(bool ignoreComdats) {
               ctx, buildAttributesSubSections, isec);
           mergeAArch64BuildAttributes(ctx, subsections, isec);
           if (!hasGnuProperties) {
-            ObjFile<ELFT> &f = *this;
             auto [pauthSubSection, fAndBSubSection] = subsections;
             if (pauthSubSection) {
               assert(
                   (pauthSubSection->Content.size() == 2) &&
                   "pauthSubSection must contain exactly two build attributes");
               // sanitizePauthSubSection already sorts
-              f.aarch64PauthAbiCoreInfoStorage =
+              (*this).aarch64PauthAbiCoreInfoStorage =
                   std::make_unique<std::array<uint8_t, 16>>();
               uint64_t values[2] = {
                   static_cast<uint64_t>(pauthSubSection->Content[0].IntValue),
                   static_cast<uint64_t>(pauthSubSection->Content[1].IntValue)};
-              std::memcpy(f.aarch64PauthAbiCoreInfoStorage->data(), &values[0],
-                          sizeof(values));
-              f.aarch64PauthAbiCoreInfo = *f.aarch64PauthAbiCoreInfoStorage;
+              std::memcpy((*this).aarch64PauthAbiCoreInfoStorage->data(),
+                          &values[0], sizeof(values));
+              (*this).aarch64PauthAbiCoreInfo =
+                  *(*this).aarch64PauthAbiCoreInfoStorage;
             }
             if (fAndBSubSection) {
               assert((fAndBSubSection->Content.size() == 3) &&
                      "fAndBSubSection must contain exactly three build "
                      "attributes");
               // sanitizeFAndBSubSection already sorts
-              f.andFeatures = 0;
-              f.andFeatures |= (fAndBSubSection->Content[0].IntValue) << 0;
-              f.andFeatures |= (fAndBSubSection->Content[1].IntValue) << 1;
-              f.andFeatures |= (fAndBSubSection->Content[2].IntValue) << 2;
+              (*this).andFeatures = 0;
+              (*this).andFeatures |= (fAndBSubSection->Content[0].IntValue)
+                                     << 0;
+              (*this).andFeatures |= (fAndBSubSection->Content[1].IntValue)
+                                     << 1;
+              (*this).andFeatures |= (fAndBSubSection->Content[2].IntValue)
+                                     << 2;
             }
           }
         }

>From 6709e9a44fa66be36a5a6809f91171c93eda0750 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 09:53:12 +0000
Subject: [PATCH 18/19] pass InputSection by reference

---
 lld/ELF/InputFiles.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 18f5288daec74..b93c9126bee56 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -222,7 +222,7 @@ static void updateSupportedARMFeatures(Ctx &ctx,
 // Content[1].
 static void sanitizePauthSubSection(
     Ctx &ctx, std::optional<llvm::BuildAttributeSubSection> &pauthSubSection,
-    InputSection isec) {
+    const InputSection &isec) {
   /*
     Incomplete data: ignore
   */

>From 04e2a16d905c8b3b5f5a712f76cdd103b6fa7bd1 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 20 Mar 2025 10:00:06 +0000
Subject: [PATCH 19/19] remove unnecessery headers

---
 lld/ELF/InputFiles.cpp | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index b93c9126bee56..213cb10c90725 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -20,21 +20,17 @@
 #include "lld/Common/DWARF.h"
 #include "llvm/ADT/CachedHashString.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
 #include "llvm/LTO/LTO.h"
 #include "llvm/Object/IRObjectFile.h"
 #include "llvm/Support/AArch64AttributeParser.h"
 #include "llvm/Support/ARMAttributeParser.h"
 #include "llvm/Support/ARMBuildAttributes.h"
-#include "llvm/Support/ELFAttributes.h"
 #include "llvm/Support/Endian.h"
-#include "llvm/Support/Errc.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/RISCVAttributeParser.h"
 #include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/raw_ostream.h"
-#include <cassert>
 #include <optional>
 
 using namespace llvm;



More information about the llvm-commits mailing list