[llvm] [LLVM][Clang][AArch64] Implement AArch64 build attributes (PR #118771)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 5 01:14:11 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
@llvm/pr-subscribers-backend-arm
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/blob/654a64cbac041fc3bff617800998d40b5068f592/buildattr64/buildattr64.rst#aeabi-feature-and-bits-subsection
---
Patch is 43.42 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118771.diff
11 Files Affected:
- (modified) llvm/include/llvm/BinaryFormat/ELF.h (+2)
- (modified) llvm/include/llvm/MC/MCELFStreamer.h (+22-5)
- (modified) llvm/include/llvm/Support/ARMBuildAttributes.h (+63)
- (modified) llvm/lib/MC/MCELFStreamer.cpp (+67-9)
- (modified) llvm/lib/Support/ARMBuildAttrs.cpp (+55-4)
- (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+58-16)
- (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp (+121-1)
- (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h (+22-1)
- (modified) llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp (+58-58)
- (modified) llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp (+1-1)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp (+3-3)
``````````diff
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index fd32a6ec19652b..dd64647c5c0334 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -1150,6 +1150,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..351c7ddd3b7380 100644
--- a/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/llvm/include/llvm/MC/MCELFStreamer.h
@@ -10,6 +10,7 @@
#define LLVM_MC_MCELFSTREAMER_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectStreamer.h"
@@ -107,25 +108,41 @@ class MCELFStreamer : public MCObjectStreamer {
std::string StringValue;
};
+ /// ELF object attributes subsection support
+ struct AttributeSubSection {
+ // [<uint32: subsection-length> NTBS: vendor-name <bytes: vendor-data>]*
+ StringRef Vendor;
+ // <uint8: optional> <uint8: parameter type> <attribute>*
+ unsigned IsMandatory; // SubsectionMandatory::REQUIRED (0), SubsectionMandatory::OPTIONAL (1)
+ unsigned ParameterType; // SubsectionType::ULEB128 (0), SubsectionType::NTBS (1)
+ SmallVector<AttributeItem, 64> Content;
+ };
+
// Attributes that are added and managed entirely by target.
SmallVector<AttributeItem, 64> Contents;
void setAttributeItem(unsigned Attribute, unsigned Value,
- bool OverwriteExisting);
+ bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes);
void setAttributeItem(unsigned Attribute, StringRef Value,
- bool OverwriteExisting);
+ bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes);
void setAttributeItems(unsigned Attribute, unsigned IntValue,
- StringRef StringValue, bool OverwriteExisting);
+ StringRef StringValue, bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes);
void emitAttributesSection(StringRef Vendor, const Twine &Section,
unsigned Type, MCSection *&AttributeSection) {
createAttributesSection(Vendor, Section, Type, AttributeSection, Contents);
}
+ void emitAttributesSection(MCSection *&AttributeSection,
+ const Twine &Section, unsigned Type, SmallVector<AttributeSubSection, 64> &SubSectionVec) {
+ createAttributesSection(AttributeSection, Section, Type, SubSectionVec);
+ }
private:
- AttributeItem *getAttributeItem(unsigned Attribute);
- size_t calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec);
+ AttributeItem *getAttributeItem(unsigned Attribute, SmallVector<AttributeItem, 64> &Attributes);
+ size_t calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) const;
void createAttributesSection(StringRef Vendor, const Twine &Section,
unsigned Type, MCSection *&AttributeSection,
SmallVector<AttributeItem, 64> &AttrsVec);
+ void createAttributesSection(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/ARMBuildAttributes.h b/llvm/include/llvm/Support/ARMBuildAttributes.h
index 35f8992ca93296..5e17ccf835190f 100644
--- a/llvm/include/llvm/Support/ARMBuildAttributes.h
+++ b/llvm/include/llvm/Support/ARMBuildAttributes.h
@@ -21,10 +21,58 @@
#include "llvm/Support/ELFAttributes.h"
namespace llvm {
+class StringRef;
+
namespace ARMBuildAttrs {
const TagNameMap &getARMAttributeTags();
+/// AArch64 build attributes vendors (=subsection name)
+enum Vendor : unsigned {
+ AEBI_FEATURE_AND_BITS = 0,
+ AEBI_PAUTHABI = 1
+};
+
+inline StringRef vendorToStr(unsigned Vendor) {
+ switch(Vendor) {
+ default:
+ llvm_unreachable("unknown AArch64 vendor name");
+ return "";
+ case AEBI_FEATURE_AND_BITS:
+ return "aeabi-feature-and-bits";
+ case AEBI_PAUTHABI:
+ return "aeabi-pauthabi";
+ }
+}
+
+enum SubsectionMandatory : unsigned {
+ OPTIONAL = 0,
+ REQUIRED = 1
+};
+
+enum SubsectionType : unsigned {
+ ULEB128 = 0,
+ NTBS = 1
+};
+
+enum FeatureAndBitsTags : unsigned {
+ Tag_PAuth_Platform = 1,
+ Tag_PAuth_Schema = 2
+};
+
+enum PauthabiTags : unsigned {
+ Tag_Feature_BTI = 0,
+ Tag_Feature_PAC = 1,
+ Tag_Feature_GCS = 2
+};
+
+enum PauthabiTagsFlag : unsigned {
+ Feature_BTI_Flag = 1 << 0,
+ Feature_PAC_Flag = 1 << 1,
+ Feature_GCS_Flag = 1 << 2
+};
+/// ---
+
enum SpecialAttr {
// This is for the .cpu asm attr. It translates into one or more
// AttrType (below) entries in the .ARM.attributes section in the ELF.
@@ -88,6 +136,21 @@ enum AttrType : unsigned {
MPextension_use_old = 70 // recoded to MPextension_use (ABI r2.08)
};
+enum AVAttr {
+ AV_cpp_exceptions = 6,
+ AV_eba = 16
+};
+
+StringRef AttrTypeAsString(StringRef Vendor, unsigned Attr, bool HasTagPrefix = true);
+StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix = true);
+StringRef AttrTypeAsString(AVAttr Attr, bool HasTagPrefix = true);
+int AttrTypeFromString(StringRef Vendor, StringRef Tag);
+
+// Magic numbers for .ARM.attributes
+enum AttrMagic {
+ Format_Version = 0x41
+};
+
// Legal Values for CPU_arch, (=6), uleb128
enum CPUArch {
Pre_v4 = 0,
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index 64ab2b2ab58f5b..34a7367a18f44c 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -636,9 +636,9 @@ void MCELFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
}
void MCELFStreamer::setAttributeItem(unsigned Attribute, unsigned Value,
- bool OverwriteExisting) {
+ bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes) {
// Look for existing attribute item
- if (AttributeItem *Item = getAttributeItem(Attribute)) {
+ if (AttributeItem *Item = getAttributeItem(Attribute, Attributes)) {
if (!OverwriteExisting)
return;
Item->Type = AttributeItem::NumericAttribute;
@@ -653,9 +653,9 @@ void MCELFStreamer::setAttributeItem(unsigned Attribute, unsigned Value,
}
void MCELFStreamer::setAttributeItem(unsigned Attribute, StringRef Value,
- bool OverwriteExisting) {
+ bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes) {
// Look for existing attribute item
- if (AttributeItem *Item = getAttributeItem(Attribute)) {
+ if (AttributeItem *Item = getAttributeItem(Attribute, Attributes)) {
if (!OverwriteExisting)
return;
Item->Type = AttributeItem::TextAttribute;
@@ -671,9 +671,9 @@ void MCELFStreamer::setAttributeItem(unsigned Attribute, StringRef Value,
void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue,
StringRef StringValue,
- bool OverwriteExisting) {
+ bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes) {
// Look for existing attribute item
- if (AttributeItem *Item = getAttributeItem(Attribute)) {
+ if (AttributeItem *Item = getAttributeItem(Attribute, Attributes)) {
if (!OverwriteExisting)
return;
Item->Type = AttributeItem::NumericAndTextAttributes;
@@ -689,15 +689,15 @@ void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue,
}
MCELFStreamer::AttributeItem *
-MCELFStreamer::getAttributeItem(unsigned Attribute) {
- for (AttributeItem &Item : Contents)
+MCELFStreamer::getAttributeItem(unsigned Attribute, SmallVector<AttributeItem, 64> &Attributes) {
+ for (AttributeItem &Item : Attributes)
if (Item.Tag == Attribute)
return &Item;
return nullptr;
}
size_t
-MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) {
+MCELFStreamer::calculateContentSize(SmallVector<AttributeItem, 64> &AttrsVec) const {
size_t Result = 0;
for (const AttributeItem &Item : AttrsVec) {
switch (Item.Type) {
@@ -783,6 +783,64 @@ void MCELFStreamer::createAttributesSection(
AttrsVec.clear();
}
+void MCELFStreamer::createAttributesSection(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 (SubSectionVec.size() == 0) {
+ 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.Vendor.size() + 1;
+ // optional + parameter-type
+ const size_t VendorParameters = 1 + 1;
+ const size_t ContentsSize = calculateContentSize(SubSection.Content);
+
+ emitInt32(VendorHeaderSize + VendorParameters + ContentsSize);
+ emitBytes(SubSection.Vendor);
+ emitInt8(SubSection.IsMandatory);
+ emitInt8(SubSection.ParameterType);
+
+ for (AttributeItem &Item : SubSection.Content) {
+ emitULEB128IntValue(Item.Tag);
+ switch (Item.Type) {
+ default:
+ llvm_unreachable("Invalid attribute type");
+ 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/ARMBuildAttrs.cpp b/llvm/lib/Support/ARMBuildAttrs.cpp
index 815cfc62a4b0e3..96d0f312d734ce 100644
--- a/llvm/lib/Support/ARMBuildAttrs.cpp
+++ b/llvm/lib/Support/ARMBuildAttrs.cpp
@@ -6,11 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ARMBuildAttributes.h"
using namespace llvm;
-static const TagNameItem tagData[] = {
+namespace {
+const TagNameItem ARMAttributeTags[] = {
{ARMBuildAttrs::File, "Tag_File"},
{ARMBuildAttrs::Section, "Tag_Section"},
{ARMBuildAttrs::Symbol, "Tag_Symbol"},
@@ -67,7 +69,56 @@ static const TagNameItem tagData[] = {
{ARMBuildAttrs::ABI_align_preserved, "Tag_ABI_align8_preserved"},
};
-constexpr TagNameMap ARMAttributeTags{tagData};
-const TagNameMap &llvm::ARMBuildAttrs::getARMAttributeTags() {
- return ARMAttributeTags;
+const TagNameItem AVAttributeTags[] = {
+ { ARMBuildAttrs::AV_cpp_exceptions, "Tag_AV_cpp_exceptions" },
+ { ARMBuildAttrs::AV_eba, "Tag_AV_eba" },
+};
+
+template<typename T, size_t N> int FromString(T (&Table)[N], StringRef Tag) {
+ bool HasTagPrefix = Tag.starts_with("Tag_");
+ for (unsigned TI = 0; TI < N; ++TI)
+ if (Table[TI].tagName.drop_front(HasTagPrefix ? 0 : 4) == Tag)
+ return Table[TI].attr;
+ return -1;
+}
+
+template<typename T, size_t N, typename A>
+StringRef AsString(T (&Table)[N], A Attr, bool HasTagPrefix) {
+ for (unsigned TI = 0; TI < N; ++TI)
+ if (Table[TI].attr == Attr)
+ return Table[TI].tagName.drop_front(HasTagPrefix ? 0 : 4);
+ return StringRef();
+}
+}
+
+namespace llvm {
+namespace ARMBuildAttrs {
+StringRef AttrTypeAsString(StringRef Vendor, unsigned Attr, bool HasTagPrefix) {
+ if (Vendor.equals_insensitive("aeabi") || Vendor.equals_insensitive("eabi"))
+ return AsString(ARMAttributeTags, static_cast<AttrType>(Attr),
+ HasTagPrefix);
+ else if (Vendor.equals_insensitive("arm"))
+ return AsString(AVAttributeTags, static_cast<AVAttr>(Attr), HasTagPrefix);
+ return StringRef();
+}
+
+StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix) {
+ return AsString(ARMAttributeTags, static_cast<AttrType>(Attr), HasTagPrefix);
+}
+
+StringRef AttrTypeAsString(AVAttr Attr, bool HasTagPrefix) {
+ return AsString(AVAttributeTags, static_cast<AVAttr>(Attr), HasTagPrefix);
+}
+
+int AttrTypeFromString(StringRef Vendor, StringRef Tag) {
+ if (Vendor.equals_insensitive("aeabi") || Vendor.equals_insensitive("eabi"))
+ return FromString(ARMAttributeTags, Tag);
+ else if (Vendor.equals_insensitive("arm"))
+ return FromString(AVAttributeTags, Tag);
+ return -1;
+}
+
+static constexpr TagNameMap tagNameMap(ARMAttributeTags);
+const TagNameMap &getARMAttributeTags() { return tagNameMap; }
+}
}
diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
index 4fd6b0d4311a54..f5e6a580fcd6ad 100644
--- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
+++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
@@ -54,6 +54,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
@@ -200,6 +201,9 @@ 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);
@@ -332,36 +336,51 @@ 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 |= ARMBuildAttrs::PauthabiTagsFlag::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 |= ARMBuildAttrs::PauthabiTagsFlag::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 |= ARMBuildAttrs::PauthabiTagsFlag::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() {
@@ -434,6 +453,29 @@ 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 = (PAuthABIPlatform == uint64_t(-1)) ? 0 : PAuthABIPlatform;
+ PAuthABIVersion = (PAuthABIVersion == uint64_t(-1)) ? 0 : PAuthABIVersion;
+
+ if(PAuthABIPlatform || PAuthABIVersion) {
+ TS->emitSubsection(ARMBuildAttrs::AEBI_PAUTHABI, 0, 0);
+ TS->emitAttribute(ARMBuildAttrs::AEBI_PAUTHABI, ARMBuildAttrs::Tag_PAuth_Platform, PAuthABIPlatform, false);
+ TS->emitAttribute(ARMBuildAttrs::AEBI_PAUTHABI, ARMBuildAttrs::Tag_PAuth_Schema, PAuthABIVersion, false);
+ }
+
+ unsigned BTIValue = (Flags & ARMBuildAttrs::Feature_BTI_Flag) ? 1 : 0;
+ unsigned PACValue = (Flags & ARMBuildAttrs::Feature_PAC_Flag) ? 1 : 0;
+ unsigned GCSValue = (Flags & ARMBuildAttrs::Feature_GCS_Flag) ? 1 : 0;
+
+ if(BTIValue || PACValue || GCSValue) {
+ TS->emitSubsection(ARMBuildAttrs::AEBI_FEATURE_AND_BITS, 1, 0);
+ TS->emitAttribute(ARMBuildAttrs::AEBI_FEATURE_AND_BITS, ARMBuildAttrs::Tag_Feature_BTI, BTIValue, false);
+ TS->emitAttribute(ARMBuildAttrs::AEBI_FEATURE_AND_BITS, ARMBuildAttrs::Tag_Feature_PAC, PACValue, false);
+ TS->emitAttribute(ARMBuildAttrs::AEBI_FEATURE_AND_BITS, ARMBuildAttrs::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/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index 5bae846824548b..e57b0703137382 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -33,6 +33,7 @@
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCWinCOFFStreamer.h"
+#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"
@@ -45,6 +46,8 @@ class AArch64ELFStreamer;
class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
formatted_raw_ostream &OS;
+ std::string VendorTag;
+ bool IsVerboseAsm;
void emitInst(uint32_t Inst) override;
@@ -148,13 +151,80 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
OS << "\t.seh_save_any_reg_px\tq" << Reg << ", " << Offset << "\n";
}
+ void emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, bool Override) override {
+ // AArch64 build attributes for assembly attribute form:
+ // .aeabi_attribute tag, value
+
+ switch(Vendor) {
+ default: llvm...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/118771
More information about the llvm-commits
mailing list