[llvm] [LLVM][Clang][AArch64] Implement AArch64 build attributes (PR #123990)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 22 11:23:15 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mc

Author: SivanShani-Arm (sivan-shani)

<details>
<summary>Changes</summary>

- Added support for AArch64-specific build attributes.
- Print AArch64 build attributes to assembly.
- Emit AArch64 build attributes to ELF.

Specification: https://github.com/ARM-software/abi-aa/pull/230

---

Patch is 73.06 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/123990.diff


28 Files Affected:

- (modified) llvm/include/llvm/BinaryFormat/ELF.h (+2) 
- (modified) llvm/include/llvm/MC/MCELFStreamer.h (+23-2) 
- (added) llvm/include/llvm/Support/AArch64BuildAttributes.h (+75) 
- (modified) llvm/lib/MC/MCELFStreamer.cpp (+63-2) 
- (added) llvm/lib/Support/AArch64BuildAttributes.cpp (+117) 
- (modified) llvm/lib/Support/CMakeLists.txt (+1) 
- (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+89-16) 
- (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+270-1) 
- (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp (+147-1) 
- (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp (+104) 
- (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h (+32) 
- (added) llvm/test/CodeGen/AArch64/aarch64-build-attributes-all.ll (+21) 
- (added) llvm/test/CodeGen/AArch64/aarch64-build-attributes-bti.ll (+19) 
- (added) llvm/test/CodeGen/AArch64/aarch64-build-attributes-gcs.ll (+19) 
- (added) llvm/test/CodeGen/AArch64/aarch64-build-attributes-pac.ll (+19) 
- (added) llvm/test/CodeGen/AArch64/aarch64-build-attributes-pauthabi.ll (+18) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-all.s (+25) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-bti.s (+18) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-err-attrs.s (+70) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-err-headers.s (+61) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-gcs.s (+18) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-none.s (+25) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-numerical-tags.s (+39) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-out-of-order.s (+48) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-pac.s (+18) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-private-subsections-err.s (+28) 
- (added) llvm/test/MC/AArch64/aarch64-build-attributes-asm-private-subsections.s (+51) 
- (modified) llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn (+2) 


``````````diff
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index 1bc69f791bd84c..48ae0db80f43ee 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -1158,6 +1158,8 @@ enum : unsigned {
   SHT_ARM_ATTRIBUTES = 0x70000003U,
   SHT_ARM_DEBUGOVERLAY = 0x70000004U,
   SHT_ARM_OVERLAYSECTION = 0x70000005U,
+  // Support for AArch64 build attributes
+  SHT_AARCH64_ATTRIBUTES = 0x70000003U,
   // Special aarch64-specific section for MTE support, as described in:
   // https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst#section-types
   SHT_AARCH64_AUTH_RELR = 0x70000004U,
diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h
index 94d14088d0f5d2..5a1cdd9e96cad4 100644
--- a/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/llvm/include/llvm/MC/MCELFStreamer.h
@@ -96,7 +96,7 @@ class MCELFStreamer : public MCObjectStreamer {
     // This structure holds all attributes, accounting for their string /
     // numeric value, so we can later emit them in declaration order, keeping
     // all in the same vector.
-    enum {
+    enum Types {
       HiddenAttribute = 0,
       NumericAttribute,
       TextAttribute,
@@ -105,6 +105,17 @@ class MCELFStreamer : public MCObjectStreamer {
     unsigned Tag;
     unsigned IntValue;
     std::string StringValue;
+    AttributeItem(Types Ty, unsigned Tg, unsigned IV, std::string SV)
+        : Type(Ty), Tag(Tg), IntValue(IV), StringValue(SV) {}
+  };
+
+  /// ELF object attributes subsection support
+  struct AttributeSubSection {
+    bool IsActive;
+    StringRef VendorName;
+    unsigned IsOptional;
+    unsigned ParameterType;
+    SmallVector<AttributeItem, 64> Content;
   };
 
   // Attributes that are added and managed entirely by target.
@@ -119,13 +130,23 @@ class MCELFStreamer : public MCObjectStreamer {
                              unsigned Type, MCSection *&AttributeSection) {
     createAttributesSection(Vendor, Section, Type, AttributeSection, Contents);
   }
+  void
+  emitAttributesSection(MCSection *&AttributeSection, const Twine &Section,
+                        unsigned Type,
+                        SmallVector<AttributeSubSection, 64> &SubSectionVec) {
+    createAttributesWithSubsection(AttributeSection, Section, Type,
+                                   SubSectionVec);
+  }
 
 private:
   AttributeItem *getAttributeItem(unsigned Attribute);
-  size_t calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec);
+  size_t calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) const;
   void createAttributesSection(StringRef Vendor, const Twine &Section,
                                unsigned Type, MCSection *&AttributeSection,
                                SmallVector<AttributeItem, 64> &AttrsVec);
+  void createAttributesWithSubsection(
+      MCSection *&AttributeSection, const Twine &Section, unsigned Type,
+      SmallVector<AttributeSubSection, 64> &SubSectionVec);
 
   // GNU attributes that will get emitted at the end of the asm file.
   SmallVector<AttributeItem, 64> GNUAttributes;
diff --git a/llvm/include/llvm/Support/AArch64BuildAttributes.h b/llvm/include/llvm/Support/AArch64BuildAttributes.h
new file mode 100644
index 00000000000000..ea293b72f9bb11
--- /dev/null
+++ b/llvm/include/llvm/Support/AArch64BuildAttributes.h
@@ -0,0 +1,75 @@
+//===-- AArch64BuildAttributes.h - AARch64 Build Attributes -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains enumerations and support routines for AArch64 build
+// attributes as defined in Build Attributes for the AArch64 document.
+//
+// Build Attributes for the ArmĀ® 64-bit Architecture (AArch64) 2024Q1
+//
+// https://github.com/ARM-software/abi-aa/pull/230
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H
+#define LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+namespace AArch64BuildAttributes {
+
+/// AArch64 build attributes vendors IDs (a.k.a subsection name)
+enum VendorID : unsigned {
+  AEABI_FEATURE_AND_BITS = 0,
+  AEABI_PAUTHABI = 1,
+  VENDOR_UNKNOWN = 404 // Treated as a private subsection name
+};
+StringRef getVendorName(unsigned const Vendor);
+VendorID getVendorID(StringRef const Vendor);
+
+enum SubsectionOptional : unsigned {
+  REQUIRED = 0,
+  OPTIONAL = 1,
+  OPTIONAL_NOT_FOUND = 404
+};
+StringRef getOptionalStr(unsigned Optional);
+SubsectionOptional getOptionalID(StringRef Optional);
+StringRef getSubsectionOptionalUnknownError();
+
+enum SubsectionType : unsigned { ULEB128 = 0, NTBS = 1, TYPE_NOT_FOUND = 404 };
+StringRef getTypeStr(unsigned Type);
+SubsectionType getTypeID(StringRef Type);
+StringRef getSubsectionTypeUnknownError();
+
+enum PauthABITags : unsigned {
+  TAG_PAUTH_PLATFORM = 1,
+  TAG_PAUTH_SCHEMA = 2,
+  PAUTHABI_TAG_NOT_FOUND = 404
+};
+StringRef getPauthABITagsStr(unsigned PauthABITag);
+PauthABITags getPauthABITagsID(StringRef PauthABITag);
+
+enum FeatureAndBitsTags : unsigned {
+  TAG_FEATURE_BTI = 0,
+  TAG_FEATURE_PAC = 1,
+  TAG_FEATURE_GCS = 2,
+  FEATURE_AND_BITS_TAG_NOT_FOUND = 404
+};
+StringRef getFeatureAndBitsTagsStr(unsigned FeatureAndBitsTag);
+FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag);
+
+enum FeatureAndBitsFlag : unsigned {
+  Feature_BTI_Flag = 1 << 0,
+  Feature_PAC_Flag = 1 << 1,
+  Feature_GCS_Flag = 1 << 2
+};
+} // namespace AArch64BuildAttributes
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H
\ No newline at end of file
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 64ab2b2ab58f5b..282c82198507d7 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -696,8 +696,8 @@ MCELFStreamer::getAttributeItem(unsigned Attribute) {
   return nullptr;
 }
 
-size_t
-MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) {
+size_t MCELFStreamer::calculateContentSize(
+    SmallVector<AttributeItem, 64> &AttrsVec) const {
   size_t Result = 0;
   for (const AttributeItem &Item : AttrsVec) {
     switch (Item.Type) {
@@ -783,6 +783,67 @@ void MCELFStreamer::createAttributesSection(
   AttrsVec.clear();
 }
 
+void MCELFStreamer::createAttributesWithSubsection(
+    MCSection *&AttributeSection, const Twine &Section, unsigned Type,
+    SmallVector<AttributeSubSection, 64> &SubSectionVec) {
+  // <format-version: 'A'>
+  // [ <uint32: subsection-length> NTBS: vendor-name
+  //   <bytes: vendor-data>
+  // ]*
+  // vendor-data expends to:
+  // <uint8: optional> <uint8: parameter type> <attribute>*
+  if (0 == SubSectionVec.size()) {
+    return;
+  }
+
+  // Switch section to AttributeSection or get/create the section.
+  if (AttributeSection) {
+    switchSection(AttributeSection);
+  } else {
+    AttributeSection = getContext().getELFSection(Section, Type, 0);
+    switchSection(AttributeSection);
+
+    // Format version
+    emitInt8(0x41);
+  }
+
+  for (AttributeSubSection &SubSection : SubSectionVec) {
+    // subsection-length + vendor-name + '\0'
+    const size_t VendorHeaderSize = 4 + SubSection.VendorName.size() + 1;
+    // optional + parameter-type
+    const size_t VendorParameters = 1 + 1;
+    const size_t ContentsSize = calculateContentSize(SubSection.Content);
+
+    emitInt32(VendorHeaderSize + VendorParameters + ContentsSize);
+    emitBytes(SubSection.VendorName);
+    emitInt8(0); // '\0'
+    emitInt8(SubSection.IsOptional);
+    emitInt8(SubSection.ParameterType);
+
+    for (AttributeItem &Item : SubSection.Content) {
+      emitULEB128IntValue(Item.Tag);
+      switch (Item.Type) {
+      default:
+        assert(0 && "Invalid attribute type");
+        break;
+      case AttributeItem::NumericAttribute:
+        emitULEB128IntValue(Item.IntValue);
+        break;
+      case AttributeItem::TextAttribute:
+        emitBytes(Item.StringValue);
+        emitInt8(0); // '\0'
+        break;
+      case AttributeItem::NumericAndTextAttributes:
+        emitULEB128IntValue(Item.IntValue);
+        emitBytes(Item.StringValue);
+        emitInt8(0); // '\0'
+        break;
+      }
+    }
+  }
+  SubSectionVec.clear();
+}
+
 MCStreamer *llvm::createELFStreamer(MCContext &Context,
                                     std::unique_ptr<MCAsmBackend> &&MAB,
                                     std::unique_ptr<MCObjectWriter> &&OW,
diff --git a/llvm/lib/Support/AArch64BuildAttributes.cpp b/llvm/lib/Support/AArch64BuildAttributes.cpp
new file mode 100644
index 00000000000000..ada34eb3f927d1
--- /dev/null
+++ b/llvm/lib/Support/AArch64BuildAttributes.cpp
@@ -0,0 +1,117 @@
+//===-- AArch64BuildAttributes.cpp - AArch64 Build Attributes -------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/AArch64BuildAttributes.h"
+#include "llvm/ADT/StringSwitch.h"
+
+namespace llvm {
+namespace AArch64BuildAttributes {
+
+StringRef getVendorName(unsigned Vendor) {
+  switch (Vendor) {
+  case AEABI_FEATURE_AND_BITS:
+    return "aeabi_feature_and_bits";
+  case AEABI_PAUTHABI:
+    return "aeabi_pauthabi";
+  case VENDOR_UNKNOWN:
+    return "";
+  default:
+    assert(0 && "Vendor name error");
+    return "";
+  }
+}
+VendorID getVendorID(StringRef Vendor) {
+  return StringSwitch<VendorID>(Vendor)
+      .Case("aeabi_feature_and_bits", AEABI_FEATURE_AND_BITS)
+      .Case("aeabi_pauthabi", AEABI_PAUTHABI)
+      .Default(VENDOR_UNKNOWN);
+}
+
+StringRef getOptionalStr(unsigned Optional) {
+  switch (Optional) {
+  case REQUIRED:
+    return "required";
+  case OPTIONAL:
+    return "optional";
+  case OPTIONAL_NOT_FOUND:
+  default:
+    return "";
+  }
+}
+SubsectionOptional getOptionalID(StringRef Optional) {
+  return StringSwitch<SubsectionOptional>(Optional)
+      .Case("required", REQUIRED)
+      .Case("optional", OPTIONAL)
+      .Default(OPTIONAL_NOT_FOUND);
+}
+StringRef getSubsectionOptionalUnknownError() {
+  return "unknown AArch64 build attributes optionality, expected "
+         "required|optional";
+}
+
+StringRef getTypeStr(unsigned Type) {
+  switch (Type) {
+  case ULEB128:
+    return "uleb128";
+  case NTBS:
+    return "ntbs";
+  case TYPE_NOT_FOUND:
+  default:
+    return "";
+  }
+}
+SubsectionType getTypeID(StringRef Type) {
+  return StringSwitch<SubsectionType>(Type)
+      .Cases("uleb128", "ULEB128", ULEB128)
+      .Cases("ntbs", "NTBS", NTBS)
+      .Default(TYPE_NOT_FOUND);
+}
+StringRef getSubsectionTypeUnknownError() {
+  return "unknown AArch64 build attributes type, expected uleb128|ntbs";
+}
+
+StringRef getPauthABITagsStr(unsigned PauthABITag) {
+  switch (PauthABITag) {
+  case TAG_PAUTH_PLATFORM:
+    return "Tag_PAuth_Platform";
+  case TAG_PAUTH_SCHEMA:
+    return "Tag_PAuth_Schema";
+  case PAUTHABI_TAG_NOT_FOUND:
+  default:
+    return "";
+  }
+}
+PauthABITags getPauthABITagsID(StringRef PauthABITag) {
+  return StringSwitch<PauthABITags>(PauthABITag)
+      .Case("Tag_PAuth_Platform", TAG_PAUTH_PLATFORM)
+      .Case("Tag_PAuth_Schema", TAG_PAUTH_SCHEMA)
+      .Default(PAUTHABI_TAG_NOT_FOUND);
+}
+
+StringRef getFeatureAndBitsTagsStr(unsigned FeatureAndBitsTag) {
+  switch (FeatureAndBitsTag) {
+  case TAG_FEATURE_BTI:
+    return "Tag_Feature_BTI";
+  case TAG_FEATURE_PAC:
+    return "Tag_Feature_PAC";
+  case TAG_FEATURE_GCS:
+    return "Tag_Feature_GCS";
+  case FEATURE_AND_BITS_TAG_NOT_FOUND:
+  default:
+    return "";
+  }
+}
+FeatureAndBitsTags getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag) {
+  return StringSwitch<FeatureAndBitsTags>(FeatureAndBitsTag)
+      .Case("Tag_Feature_BTI", TAG_FEATURE_BTI)
+      .Case("Tag_Feature_PAC", TAG_FEATURE_PAC)
+      .Case("Tag_Feature_GCS", TAG_FEATURE_GCS)
+      .Default(FEATURE_AND_BITS_TAG_NOT_FOUND);
+}
+} // namespace AArch64BuildAttributes
+} // namespace llvm
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 2ecaea4b02bf61..122240c27b1fcd 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -144,6 +144,7 @@ add_llvm_component_library(LLVMSupport
   APInt.cpp
   APSInt.cpp
   ARMBuildAttrs.cpp
+  AArch64BuildAttributes.cpp
   ARMAttributeParser.cpp
   ARMWinEH.cpp
   Allocator.cpp
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 27e65d60122fd7..8d8520c68232be 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -208,6 +208,10 @@ class AArch64AsmPrinter : public AsmPrinter {
   /// pseudo instructions.
   bool lowerPseudoInstExpansion(const MachineInstr *MI, MCInst &Inst);
 
+  // Emit Build Attributes
+  void emitAttributes(unsigned Flags, uint64_t PAuthABIPlatform,
+                      uint64_t PAuthABIVersion, AArch64TargetStreamer *TS);
+
   void EmitToStreamer(MCStreamer &S, const MCInst &Inst);
   void EmitToStreamer(const MCInst &Inst) {
     EmitToStreamer(*OutStreamer, Inst);
@@ -345,36 +349,53 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
   if (!TT.isOSBinFormatELF())
     return;
 
-  // Assemble feature flags that may require creation of a note section.
-  unsigned Flags = 0;
+  // For emitting build attributes and .note.gnu.property section
+  auto *TS =
+      static_cast<AArch64TargetStreamer *>(OutStreamer->getTargetStreamer());
+  // Assemble feature flags that may require creation of build attributes and a
+  // note section.
+  unsigned BAFlags = 0;
+  unsigned GNUFlags = 0;
   if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
-          M.getModuleFlag("branch-target-enforcement")))
-    if (!BTE->isZero())
-      Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
+          M.getModuleFlag("branch-target-enforcement"))) {
+    if (!BTE->isZero()) {
+      BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_BTI_Flag;
+      GNUFlags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
+    }
+  }
 
   if (const auto *GCS = mdconst::extract_or_null<ConstantInt>(
-          M.getModuleFlag("guarded-control-stack")))
-    if (!GCS->isZero())
-      Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+          M.getModuleFlag("guarded-control-stack"))) {
+    if (!GCS->isZero()) {
+      BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_GCS_Flag;
+      GNUFlags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_GCS;
+    }
+  }
 
   if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
-          M.getModuleFlag("sign-return-address")))
-    if (!Sign->isZero())
-      Flags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
+          M.getModuleFlag("sign-return-address"))) {
+    if (!Sign->isZero()) {
+      BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_PAC_Flag;
+      GNUFlags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC;
+    }
+  }
 
   uint64_t PAuthABIPlatform = -1;
   if (const auto *PAP = mdconst::extract_or_null<ConstantInt>(
-          M.getModuleFlag("aarch64-elf-pauthabi-platform")))
+          M.getModuleFlag("aarch64-elf-pauthabi-platform"))) {
     PAuthABIPlatform = PAP->getZExtValue();
+  }
+
   uint64_t PAuthABIVersion = -1;
   if (const auto *PAV = mdconst::extract_or_null<ConstantInt>(
-          M.getModuleFlag("aarch64-elf-pauthabi-version")))
+          M.getModuleFlag("aarch64-elf-pauthabi-version"))) {
     PAuthABIVersion = PAV->getZExtValue();
+  }
 
+  // Emit AArch64 Build Attributes
+  emitAttributes(BAFlags, PAuthABIPlatform, PAuthABIVersion, TS);
   // Emit a .note.gnu.property section with the flags.
-  auto *TS =
-      static_cast<AArch64TargetStreamer *>(OutStreamer->getTargetStreamer());
-  TS->emitNoteSection(Flags, PAuthABIPlatform, PAuthABIVersion);
+  TS->emitNoteSection(GNUFlags, PAuthABIPlatform, PAuthABIVersion);
 }
 
 void AArch64AsmPrinter::emitFunctionHeaderComment() {
@@ -447,6 +468,58 @@ void AArch64AsmPrinter::emitSled(const MachineInstr &MI, SledKind Kind) {
   recordSled(CurSled, MI, Kind, 2);
 }
 
+void AArch64AsmPrinter::emitAttributes(unsigned Flags,
+                                       uint64_t PAuthABIPlatform,
+                                       uint64_t PAuthABIVersion,
+                                       AArch64TargetStreamer *TS) {
+
+  PAuthABIPlatform = (uint64_t(-1) == PAuthABIPlatform) ? 0 : PAuthABIPlatform;
+  PAuthABIVersion = (uint64_t(-1) == PAuthABIVersion) ? 0 : PAuthABIVersion;
+
+  if (PAuthABIPlatform || PAuthABIVersion) {
+    TS->emitAtributesSubsection(
+        AArch64BuildAttributes::getVendorName(
+            AArch64BuildAttributes::AEABI_PAUTHABI),
+        AArch64BuildAttributes::SubsectionOptional::REQUIRED,
+        AArch64BuildAttributes::SubsectionType::ULEB128);
+    TS->emitAttribute(AArch64BuildAttributes::getVendorName(
+                          AArch64BuildAttributes::AEABI_PAUTHABI),
+                      AArch64BuildAttributes::TAG_PAUTH_PLATFORM,
+                      PAuthABIPlatform, "", false);
+    TS->emitAttribute(AArch64BuildAttributes::getVendorName(
+                          AArch64BuildAttributes::AEABI_PAUTHABI),
+                      AArch64BuildAttributes::TAG_PAUTH_SCHEMA, PAuthABIVersion,
+                      "", false);
+  }
+
+  unsigned BTIValue =
+      (Flags & AArch64BuildAttributes::Feature_BTI_Flag) ? 1 : 0;
+  unsigned PACValue =
+      (Flags & AArch64BuildAttributes::Feature_PAC_Flag) ? 1 : 0;
+  unsigned GCSValue =
+      (Flags & AArch64BuildAttributes::Feature_GCS_Flag) ? 1 : 0;
+
+  if (BTIValue || PACValue || GCSValue) {
+    TS->emitAtributesSubsection(
+        AArch64BuildAttributes::getVendorName(
+            AArch64BuildAttributes::AEABI_FEATURE_AND_BITS),
+        AArch64BuildAttributes::SubsectionOptional::OPTIONAL,
+        AArch64BuildAttributes::SubsectionType::ULEB128);
+    TS->emitAttribute(AArch64BuildAttributes::getVendorName(
+                          AArch64BuildAttributes::AEABI_FEATURE_AND_BITS),
+                      AArch64BuildAttributes::TAG_FEATURE_BTI, BTIValue, "",
+                      false);
+    TS->emitAttribute(AArch64BuildAttributes::getVendorName(
+                          AArch64BuildAttributes::AEABI_FEATURE_AND_BITS),
+                      AArch64BuildAttributes::TAG_FEATURE_PAC, PACValue, "",
+                      false);
+    TS->emitAttribute(AArch64BuildAttributes::getVendorName(
+                          AArch64BuildAttributes::AEABI_FEATURE_AND_BITS),
+                      AArch64BuildAttributes::TAG_FEATURE_GCS, GCSValue, "",
+                      false);
+  }
+}
+
 // Emit the following code for Intrinsic::{xray_customevent,xray_typedevent}
 // (built-in functions __xray_customevent/__xray_typedevent).
 //
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 92f9f7309f8ec0..d3eda48f3276e9 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -42,7 +42,7 @@
 #include "llvm/MC/MCTargetOptions.h"
 #include "llvm/MC/MCValue.h"
 #include "llvm/MC/TargetRegistry.h"
-#include "llvm/Support/Casting.h"
+#include "llvm/Support/AArch64BuildAttributes.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
@@ -228,6 +228,8 @@ class AArch64AsmParser : public MCTargetAsmParser {
   bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
   bool parseDirectiveSEHPACSignLR(SMLoc L);
   bool parseDirectiveSEHSaveAnyReg(SMLoc L, bool Paired, bool Writeback);
+  bool parseDirectiveAeabiSubSectionHeader(SMLoc L);
+  bool parseDirectiveAeabiAArch64Attr(SMLoc L);
 
   bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
                            SmallVectorImpl<SMLoc> &Loc);
@@ -6992,6 +6994,7 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
   const MCContext::Environment Format = getContext().g...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/123990


More information about the llvm-commits mailing list