https://github.com/sivan-shani updated https://github.com/llvm/llvm-project/pull/118771
>From a10af4639c827bd44ff25bd60b820186b5bec74f Mon Sep 17 00:00:00 2001 From: Sivan Shani <sivan.sh...@arm.com> Date: Wed, 4 Dec 2024 20:08:20 +0000 Subject: [PATCH 1/4] [LLVM][Clang][AArch64] Implement AArch64 build attributes - 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 --- llvm/include/llvm/BinaryFormat/ELF.h | 2 + llvm/include/llvm/MC/MCELFStreamer.h | 27 +++- .../include/llvm/Support/ARMBuildAttributes.h | 63 +++++++++ llvm/lib/MC/MCELFStreamer.cpp | 76 +++++++++-- llvm/lib/Support/ARMBuildAttrs.cpp | 59 ++++++++- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 74 ++++++++--- .../MCTargetDesc/AArch64ELFStreamer.cpp | 122 +++++++++++++++++- .../MCTargetDesc/AArch64TargetStreamer.h | 23 +++- .../ARM/MCTargetDesc/ARMELFStreamer.cpp | 116 ++++++++--------- .../MCTargetDesc/HexagonMCTargetDesc.cpp | 2 +- .../RISCV/MCTargetDesc/RISCVELFStreamer.cpp | 6 +- 11 files changed, 472 insertions(+), 98 deletions(-) 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_unreachable("unknown AArch64 build attributes subsection name"); + + case ARMBuildAttrs::AEBI_FEATURE_AND_BITS: + switch(Tag) { + default: llvm_unreachable("unknown tag for the feature-and-bits subsection"); + case ARMBuildAttrs::Tag_Feature_BTI: + OS << "\t.aeabi_attribute\t" << "Tag_Feature_BTI" << ", " << Value; + break; + case ARMBuildAttrs::Tag_Feature_GCS: + OS << "\t.aeabi_attribute\t" << "Tag_Feature_GCS" << ", " << Value; + break; + case ARMBuildAttrs::Tag_Feature_PAC: + OS << "\t.aeabi_attribute\t" << "Tag_Feature_PAC" << ", " << Value; + break; + } + break; + + case ARMBuildAttrs::AEBI_PAUTHABI: + switch(Tag) { + default: llvm_unreachable("unknown tag for the feature-and-bits subsection"); + case ARMBuildAttrs::Tag_PAuth_Platform: + OS << "\t.aeabi_attribute\t" << "Tag_PAuth_Platform" << ", " << Value; + break; + case ARMBuildAttrs::Tag_PAuth_Schema: + OS << "\t.aeabi_attribute\t" << "Tag_PAuth_Schema" << ", " << Value; + break; + break; + } + } + OS << "\n"; + } + + void emitSubsection(unsigned SubsectionName, unsigned Optional, unsigned ParameterType) override { + // The AArch64 build attributes assembly subsection header format: + // ".aeabi_subsection name, optional, parameter type" + // optional: required (0) optional (1) + // parameter type: uleb128 or ULEB128 (0) ntbs or NTBS (1) + + assert((Optional == 0 || Optional == 1) && "unsupported parameter for Optional"); + assert((ParameterType == 0 || ParameterType == 1) && "unsupported parameter for ParameterType"); + + StringRef OptionalStr = Optional ? "optional" : "required"; + StringRef ParameterStr = ParameterType ? "NTBS" : "ULEB128"; + + switch(SubsectionName) { + default: llvm_unreachable("unknown AArch64 build attributes subsection name"); + + case ARMBuildAttrs::AEBI_FEATURE_AND_BITS: + assert(Optional == 1 && "subsection .aeabi-feature-and-bits should be marked as optional and not as mandatory"); + assert(ParameterType == 0 && "subsection .aeabi-feature-and-bits should be marked as uleb128 and not as ntbs"); + OS << "\t.aeabi_subsection\t" << ".aeabi-feature-and-bits" << ", " << OptionalStr << ", " << ParameterStr; + break; + + case ARMBuildAttrs::AEBI_PAUTHABI: + assert(Optional == 0 && "subsection .aeabi-pauthabi should be marked as mandatory and not as optional"); + assert(ParameterType == 0 && "subsection .aeabi-pauthabi should be marked as uleb128 and not as ntbs"); + OS << "\t.aeabi_subsection\t" << ".aeabi-pauthabi" << ", " << OptionalStr << ", " << ParameterStr; + break; + } + OS << "\n"; + } + public: AArch64TargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS); }; AArch64TargetAsmStreamer::AArch64TargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) - : AArch64TargetStreamer(S), OS(OS) {} + : AArch64TargetStreamer(S), OS(OS), VendorTag("eabi"), IsVerboseAsm(S.isVerboseAsm()) {} void AArch64TargetAsmStreamer::emitInst(uint32_t Inst) { OS << "\t.inst\t0x" << Twine::utohexstr(Inst) << "\n"; @@ -294,6 +364,53 @@ AArch64ELFStreamer &AArch64TargetELFStreamer::getStreamer() { return static_cast<AArch64ELFStreamer &>(Streamer); } +void AArch64TargetELFStreamer::emitSubsection(unsigned Vendor, unsigned IsMandatory, unsigned ParameterType) { + StringRef VendorAsStr = ARMBuildAttrs::vendorToStr(Vendor); + + // If exists, return. + for (MCELFStreamer::AttributeSubSection &SubSection : AttributeSubSections) { + if (SubSection.Vendor == VendorAsStr) { + llvm_unreachable("AArch64 build attributes subsection already exists"); + return; + } + } + // else, add the subsection + MCELFStreamer::AttributeSubSection AttSubSection; + AttSubSection.Vendor = VendorAsStr; + AttSubSection.IsMandatory = IsMandatory; + AttSubSection.ParameterType = ParameterType; + AttributeSubSections.push_back(AttSubSection); +} + +void AArch64TargetELFStreamer::emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, bool Override) { + StringRef VendorAsStr = ARMBuildAttrs::vendorToStr(Vendor); + + if (AttributeSubSections.size() == 0) { + llvm_unreachable("Attribute can not be added unless the required AArch64 build attributes subsection exists"); + return; + } + + for (MCELFStreamer::AttributeSubSection &SubSection : AttributeSubSections) { + if (SubSection.Vendor == VendorAsStr) { + for (MCELFStreamer::AttributeItem &Item : SubSection.Content) { + if (Item.Tag == Tag) { + if (!Override) { + llvm_unreachable("Attribute exists but override is set to false"); + return; + } + } + } + MCELFStreamer::AttributeItem AttItem; + AttItem.Type = AttItem.NumericAttribute; + AttItem.Tag = Tag; + AttItem.IntValue = Value; + SubSection.Content.push_back(AttItem); + return; + } + } + llvm_unreachable("Attribute can not be added unless the required AArch64 build attributes subsection exists"); +} + void AArch64TargetELFStreamer::emitInst(uint32_t Inst) { getStreamer().emitInst(Inst); } @@ -309,6 +426,9 @@ void AArch64TargetELFStreamer::finish() { MCContext &Ctx = S.getContext(); auto &Asm = S.getAssembler(); + S.emitAttributesSection(AttributeSection, ".ARM.attributes", + ELF::SHT_AARCH64_ATTRIBUTES, AttributeSubSections); + // If ImplicitMapSyms is specified, ensure that text sections end with // the A64 state while non-text sections end with the data state. When // sections are combined by the linker, the subsequent section will start with diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h index ac441ae3b603ff..7d90759cfc6e10 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h @@ -9,7 +9,15 @@ #ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H #define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64TARGETSTREAMER_H +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Instructions.h" +#include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/Support/ARMBuildAttributes.h" +#include "llvm/TableGen/Record.h" +#include <cstddef> +#include <cstdint> +#include <utility> namespace { class AArch64ELFStreamer; @@ -83,20 +91,33 @@ class AArch64TargetStreamer : public MCTargetStreamer { virtual void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) {} virtual void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) {} + /// Build attributes implementation + virtual void emitSubsection(unsigned Vendor, unsigned IsMandatory, unsigned ParameterType) {} + virtual void emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, bool Override) {} + private: std::unique_ptr<AssemblerConstantPools> ConstantPools; }; class AArch64TargetELFStreamer : public AArch64TargetStreamer { private: + StringRef CurrentVendor; AArch64ELFStreamer &getStreamer(); + MCSection *AttributeSection = nullptr; + SmallVector<MCELFStreamer::AttributeSubSection, 64> AttributeSubSections; + + /// Build attributes implementation + void emitSubsection(unsigned Vendor, unsigned IsMandatory, unsigned ParameterType) override; + void emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, bool Override) override; + void emitInst(uint32_t Inst) override; void emitDirectiveVariantPCS(MCSymbol *Symbol) override; void finish() override; public: - AArch64TargetELFStreamer(MCStreamer &S) : AArch64TargetStreamer(S) {} + AArch64TargetELFStreamer(MCStreamer &S) + : AArch64TargetStreamer(S), CurrentVendor("aeabi") {} }; class AArch64TargetWinCOFFStreamer : public llvm::AArch64TargetStreamer { diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index c528526382a2b4..b6a16de748d9b0 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -793,20 +793,20 @@ void ARMTargetELFStreamer::switchVendor(StringRef Vendor) { void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { getStreamer().setAttributeItem(Attribute, Value, - /* OverwriteExisting= */ true); + /* OverwriteExisting= */ true, getStreamer().Contents); } void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute, StringRef Value) { getStreamer().setAttributeItem(Attribute, Value, - /* OverwriteExisting= */ true); + /* OverwriteExisting= */ true, getStreamer().Contents); } void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue) { getStreamer().setAttributeItems(Attribute, IntValue, StringValue, - /* OverwriteExisting= */ true); + /* OverwriteExisting= */ true, getStreamer().Contents); } void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) { @@ -821,16 +821,16 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() { using namespace ARMBuildAttrs; ARMELFStreamer &S = getStreamer(); - S.setAttributeItem(CPU_name, ARM::getCPUAttr(Arch), false); + S.setAttributeItem(CPU_name, ARM::getCPUAttr(Arch), false, getStreamer().Contents); if (EmittedArch == ARM::ArchKind::INVALID) - S.setAttributeItem(CPU_arch, ARM::getArchAttr(Arch), false); + S.setAttributeItem(CPU_arch, ARM::getArchAttr(Arch), false, getStreamer().Contents); else - S.setAttributeItem(CPU_arch, ARM::getArchAttr(EmittedArch), false); + S.setAttributeItem(CPU_arch, ARM::getArchAttr(EmittedArch), false, getStreamer().Contents); switch (Arch) { case ARM::ArchKind::ARMV4: - S.setAttributeItem(ARM_ISA_use, Allowed, false); + S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); break; case ARM::ArchKind::ARMV4T: @@ -838,42 +838,42 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() { case ARM::ArchKind::XSCALE: case ARM::ArchKind::ARMV5TE: case ARM::ArchKind::ARMV6: - S.setAttributeItem(ARM_ISA_use, Allowed, false); - S.setAttributeItem(THUMB_ISA_use, Allowed, false); + S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, Allowed, false, getStreamer().Contents); break; case ARM::ArchKind::ARMV6T2: - S.setAttributeItem(ARM_ISA_use, Allowed, false); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false); + S.setAttributeItem(ARM_ISA_use, Allowed, false,getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); break; case ARM::ArchKind::ARMV6K: case ARM::ArchKind::ARMV6KZ: - S.setAttributeItem(ARM_ISA_use, Allowed, false); - S.setAttributeItem(THUMB_ISA_use, Allowed, false); - S.setAttributeItem(Virtualization_use, AllowTZ, false); + S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(Virtualization_use, AllowTZ, false, getStreamer().Contents); break; case ARM::ArchKind::ARMV6M: - S.setAttributeItem(THUMB_ISA_use, Allowed, false); + S.setAttributeItem(THUMB_ISA_use, Allowed, false, getStreamer().Contents); break; case ARM::ArchKind::ARMV7A: - S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false); - S.setAttributeItem(ARM_ISA_use, Allowed, false); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false); + S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false, getStreamer().Contents); + S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); break; case ARM::ArchKind::ARMV7R: - S.setAttributeItem(CPU_arch_profile, RealTimeProfile, false); - S.setAttributeItem(ARM_ISA_use, Allowed, false); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false); + S.setAttributeItem(CPU_arch_profile, RealTimeProfile, false, getStreamer().Contents); + S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); break; case ARM::ArchKind::ARMV7EM: case ARM::ArchKind::ARMV7M: - S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false); + S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); break; case ARM::ArchKind::ARMV8A: @@ -893,29 +893,29 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() { case ARM::ArchKind::ARMV9_4A: case ARM::ArchKind::ARMV9_5A: case ARM::ArchKind::ARMV9_6A: - S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false); - S.setAttributeItem(ARM_ISA_use, Allowed, false); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false); - S.setAttributeItem(MPextension_use, Allowed, false); - S.setAttributeItem(Virtualization_use, AllowTZVirtualization, false); + S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false, getStreamer().Contents); + S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); + S.setAttributeItem(MPextension_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(Virtualization_use, AllowTZVirtualization, false, getStreamer().Contents); break; case ARM::ArchKind::ARMV8MBaseline: case ARM::ArchKind::ARMV8MMainline: - S.setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false); - S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); + S.setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false, getStreamer().Contents); + S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false, getStreamer().Contents); break; case ARM::ArchKind::IWMMXT: - S.setAttributeItem(ARM_ISA_use, Allowed, false); - S.setAttributeItem(THUMB_ISA_use, Allowed, false); - S.setAttributeItem(WMMX_arch, AllowWMMXv1, false); + S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(WMMX_arch, AllowWMMXv1, false, getStreamer().Contents); break; case ARM::ArchKind::IWMMXT2: - S.setAttributeItem(ARM_ISA_use, Allowed, false); - S.setAttributeItem(THUMB_ISA_use, Allowed, false); - S.setAttributeItem(WMMX_arch, AllowWMMXv2, false); + S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(WMMX_arch, AllowWMMXv2, false, getStreamer().Contents); break; default: @@ -933,47 +933,47 @@ void ARMTargetELFStreamer::emitFPUDefaultAttributes() { case ARM::FK_VFP: case ARM::FK_VFPV2: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv2, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_VFPV3: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_VFPV3_FP16: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_VFPV3_D16: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_VFPV3_D16_FP16: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_VFPV3XD: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_VFPV3XD_FP16: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_VFPV4: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4A, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same @@ -981,12 +981,12 @@ void ARMTargetELFStreamer::emitFPUDefaultAttributes() { case ARM::FK_FPV4_SP_D16: case ARM::FK_VFPV4_D16: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4B, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_FP_ARMV8: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8A, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so @@ -998,39 +998,39 @@ void ARMTargetELFStreamer::emitFPUDefaultAttributes() { case ARM::FK_FP_ARMV8_FULLFP16_SP_D16: case ARM::FK_FP_ARMV8_FULLFP16_D16: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8B, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_NEON: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, ARMBuildAttrs::AllowNeon, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_NEON_FP16: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, ARMBuildAttrs::AllowNeon, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_NEON_VFPV4: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4A, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, ARMBuildAttrs::AllowNeon2, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); break; case ARM::FK_NEON_FP_ARMV8: case ARM::FK_CRYPTO_NEON_FP_ARMV8: S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8A, - /* OverwriteExisting= */ false); + /* OverwriteExisting= */ false, getStreamer().Contents); // 'Advanced_SIMD_arch' must be emitted not here, but within // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a() break; diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index aa86b2df856296..d8a177a90a7a3d 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -330,7 +330,7 @@ class HexagonTargetELFStreamer : public HexagonTargetStreamer { void emitAttribute(uint32_t Attribute, uint32_t Value) override { getStreamer().setAttributeItem(Attribute, Value, - /*OverwriteExisting=*/true); + /*OverwriteExisting=*/true, getStreamer().Contents); } }; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp index ea0e9fcde21cf9..ae536accb399a2 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -57,19 +57,19 @@ void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {} void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {} void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { - getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); + getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true, getStreamer().Contents); } void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute, StringRef String) { - getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true); + getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true, getStreamer().Contents); } void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue) { getStreamer().setAttributeItems(Attribute, IntValue, StringValue, - /*OverwriteExisting=*/true); + /*OverwriteExisting=*/true, getStreamer().Contents); } void RISCVTargetELFStreamer::finishAttributeSection() { >From c1c4c469b3e46e8777d3c9ca2d8ada5838e82b6b Mon Sep 17 00:00:00 2001 From: Sivan Shani <sivan.sh...@arm.com> Date: Thu, 5 Dec 2024 10:53:07 +0000 Subject: [PATCH 2/4] Formatting --- llvm/include/llvm/MC/MCELFStreamer.h | 30 +++-- .../include/llvm/Support/ARMBuildAttributes.h | 43 +++---- llvm/lib/MC/MCELFStreamer.cpp | 68 +++++----- llvm/lib/Support/ARMBuildAttrs.cpp | 16 +-- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 34 +++-- .../MCTargetDesc/AArch64ELFStreamer.cpp | 116 ++++++++++-------- .../MCTargetDesc/AArch64TargetStreamer.h | 14 ++- .../ARM/MCTargetDesc/ARMELFStreamer.cpp | 59 ++++++--- .../MCTargetDesc/HexagonMCTargetDesc.cpp | 3 +- .../RISCV/MCTargetDesc/RISCVELFStreamer.cpp | 9 +- 10 files changed, 226 insertions(+), 166 deletions(-) diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index 351c7ddd3b7380..0e37948d3d2b7f 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -113,36 +113,46 @@ class MCELFStreamer : public MCObjectStreamer { // [<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) + 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, SmallVector<AttributeItem, 64> &Attributes); + bool OverwriteExisting, + SmallVector<AttributeItem, 64> &Attributes); void setAttributeItem(unsigned Attribute, StringRef Value, - bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes); + bool OverwriteExisting, + SmallVector<AttributeItem, 64> &Attributes); void setAttributeItems(unsigned Attribute, unsigned IntValue, - StringRef StringValue, bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes); + 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) { + void + emitAttributesSection(MCSection *&AttributeSection, const Twine &Section, + unsigned Type, + SmallVector<AttributeSubSection, 64> &SubSectionVec) { createAttributesSection(AttributeSection, Section, Type, SubSectionVec); } private: - AttributeItem *getAttributeItem(unsigned Attribute, SmallVector<AttributeItem, 64> &Attributes); + 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); + 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 5e17ccf835190f..788d72977d6f05 100644 --- a/llvm/include/llvm/Support/ARMBuildAttributes.h +++ b/llvm/include/llvm/Support/ARMBuildAttributes.h @@ -28,32 +28,23 @@ namespace ARMBuildAttrs { const TagNameMap &getARMAttributeTags(); /// AArch64 build attributes vendors (=subsection name) -enum Vendor : unsigned { - AEBI_FEATURE_AND_BITS = 0, - AEBI_PAUTHABI = 1 -}; +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"; + 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 SubsectionMandatory : unsigned { OPTIONAL = 0, REQUIRED = 1 }; -enum SubsectionType : unsigned { - ULEB128 = 0, - NTBS = 1 -}; +enum SubsectionType : unsigned { ULEB128 = 0, NTBS = 1 }; enum FeatureAndBitsTags : unsigned { Tag_PAuth_Platform = 1, @@ -136,20 +127,16 @@ enum AttrType : unsigned { MPextension_use_old = 70 // recoded to MPextension_use (ABI r2.08) }; -enum AVAttr { - AV_cpp_exceptions = 6, - AV_eba = 16 -}; +enum AVAttr { AV_cpp_exceptions = 6, AV_eba = 16 }; -StringRef AttrTypeAsString(StringRef Vendor, unsigned Attr, bool HasTagPrefix = true); +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 -}; +enum AttrMagic { Format_Version = 0x41 }; // Legal Values for CPU_arch, (=6), uleb128 enum CPUArch { diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 34a7367a18f44c..576d4997a3dea7 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -635,8 +635,9 @@ void MCELFStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, llvm_unreachable("ELF doesn't support this directive"); } -void MCELFStreamer::setAttributeItem(unsigned Attribute, unsigned Value, - bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes) { +void MCELFStreamer::setAttributeItem( + unsigned Attribute, unsigned Value, bool OverwriteExisting, + SmallVector<AttributeItem, 64> &Attributes) { // Look for existing attribute item if (AttributeItem *Item = getAttributeItem(Attribute, Attributes)) { if (!OverwriteExisting) @@ -652,8 +653,9 @@ void MCELFStreamer::setAttributeItem(unsigned Attribute, unsigned Value, Contents.push_back(Item); } -void MCELFStreamer::setAttributeItem(unsigned Attribute, StringRef Value, - bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes) { +void MCELFStreamer::setAttributeItem( + unsigned Attribute, StringRef Value, bool OverwriteExisting, + SmallVector<AttributeItem, 64> &Attributes) { // Look for existing attribute item if (AttributeItem *Item = getAttributeItem(Attribute, Attributes)) { if (!OverwriteExisting) @@ -669,9 +671,9 @@ void MCELFStreamer::setAttributeItem(unsigned Attribute, StringRef Value, Contents.push_back(Item); } -void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue, - StringRef StringValue, - bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes) { +void MCELFStreamer::setAttributeItems( + unsigned Attribute, unsigned IntValue, StringRef StringValue, + bool OverwriteExisting, SmallVector<AttributeItem, 64> &Attributes) { // Look for existing attribute item if (AttributeItem *Item = getAttributeItem(Attribute, Attributes)) { if (!OverwriteExisting) @@ -689,15 +691,16 @@ void MCELFStreamer::setAttributeItems(unsigned Attribute, unsigned IntValue, } MCELFStreamer::AttributeItem * -MCELFStreamer::getAttributeItem(unsigned Attribute, SmallVector<AttributeItem, 64> &Attributes) { +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) const { +size_t MCELFStreamer::calculateContentSize( + SmallVector<AttributeItem, 64> &AttrsVec) const { size_t Result = 0; for (const AttributeItem &Item : AttrsVec) { switch (Item.Type) { @@ -783,14 +786,15 @@ 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>* +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; } @@ -821,20 +825,20 @@ void MCELFStreamer::createAttributesSection(MCSection *&AttributeSection, 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; + 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; } } } diff --git a/llvm/lib/Support/ARMBuildAttrs.cpp b/llvm/lib/Support/ARMBuildAttrs.cpp index 96d0f312d734ce..457e7d66a7e87a 100644 --- a/llvm/lib/Support/ARMBuildAttrs.cpp +++ b/llvm/lib/Support/ARMBuildAttrs.cpp @@ -70,26 +70,26 @@ const TagNameItem ARMAttributeTags[] = { }; const TagNameItem AVAttributeTags[] = { - { ARMBuildAttrs::AV_cpp_exceptions, "Tag_AV_cpp_exceptions" }, - { ARMBuildAttrs::AV_eba, "Tag_AV_eba" }, + {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) { +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) + 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> +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 namespace llvm { namespace ARMBuildAttrs { @@ -120,5 +120,5 @@ int AttrTypeFromString(StringRef Vendor, StringRef Tag) { static constexpr TagNameMap tagNameMap(ARMAttributeTags); const TagNameMap &getARMAttributeTags() { return tagNameMap; } -} -} +} // namespace ARMBuildAttrs +} // namespace llvm diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index f5e6a580fcd6ad..ca60e249e14214 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -202,7 +202,8 @@ class AArch64AsmPrinter : public AsmPrinter { bool lowerPseudoInstExpansion(const MachineInstr *MI, MCInst &Inst); // Emit Build Attributes - void emitAttributes(unsigned Flags, uint64_t PAuthABIPlatform, uint64_t PAuthABIVersion, AArch64TargetStreamer* TS); + void emitAttributes(unsigned Flags, uint64_t PAuthABIPlatform, + uint64_t PAuthABIVersion, AArch64TargetStreamer *TS); void EmitToStreamer(MCStreamer &S, const MCInst &Inst); void EmitToStreamer(const MCInst &Inst) { @@ -337,8 +338,10 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) { return; // 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. + 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>( @@ -453,26 +456,35 @@ 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) { +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) { + 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); + 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) { + 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); + 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); } } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp index e57b0703137382..cb594785a09d2f 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp @@ -151,69 +151,83 @@ 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 { + 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_unreachable("unknown AArch64 build attributes subsection name"); - - case ARMBuildAttrs::AEBI_FEATURE_AND_BITS: - switch(Tag) { - default: llvm_unreachable("unknown tag for the feature-and-bits subsection"); - case ARMBuildAttrs::Tag_Feature_BTI: - OS << "\t.aeabi_attribute\t" << "Tag_Feature_BTI" << ", " << Value; - break; - case ARMBuildAttrs::Tag_Feature_GCS: - OS << "\t.aeabi_attribute\t" << "Tag_Feature_GCS" << ", " << Value; - break; - case ARMBuildAttrs::Tag_Feature_PAC: - OS << "\t.aeabi_attribute\t" << "Tag_Feature_PAC" << ", " << Value; - break; - } + switch (Vendor) { + default: + llvm_unreachable("unknown AArch64 build attributes subsection name"); + + case ARMBuildAttrs::AEBI_FEATURE_AND_BITS: + switch (Tag) { + default: + llvm_unreachable("unknown tag for the feature-and-bits subsection"); + case ARMBuildAttrs::Tag_Feature_BTI: + OS << "\t.aeabi_attribute\t" << "Tag_Feature_BTI" << ", " << Value; + break; + case ARMBuildAttrs::Tag_Feature_GCS: + OS << "\t.aeabi_attribute\t" << "Tag_Feature_GCS" << ", " << Value; + break; + case ARMBuildAttrs::Tag_Feature_PAC: + OS << "\t.aeabi_attribute\t" << "Tag_Feature_PAC" << ", " << Value; break; + } + break; - case ARMBuildAttrs::AEBI_PAUTHABI: - switch(Tag) { - default: llvm_unreachable("unknown tag for the feature-and-bits subsection"); - case ARMBuildAttrs::Tag_PAuth_Platform: - OS << "\t.aeabi_attribute\t" << "Tag_PAuth_Platform" << ", " << Value; - break; - case ARMBuildAttrs::Tag_PAuth_Schema: - OS << "\t.aeabi_attribute\t" << "Tag_PAuth_Schema" << ", " << Value; - break; + case ARMBuildAttrs::AEBI_PAUTHABI: + switch (Tag) { + default: + llvm_unreachable("unknown tag for the feature-and-bits subsection"); + case ARMBuildAttrs::Tag_PAuth_Platform: + OS << "\t.aeabi_attribute\t" << "Tag_PAuth_Platform" << ", " << Value; break; - } + case ARMBuildAttrs::Tag_PAuth_Schema: + OS << "\t.aeabi_attribute\t" << "Tag_PAuth_Schema" << ", " << Value; + break; + break; + } } OS << "\n"; } - void emitSubsection(unsigned SubsectionName, unsigned Optional, unsigned ParameterType) override { + void emitSubsection(unsigned SubsectionName, unsigned Optional, + unsigned ParameterType) override { // The AArch64 build attributes assembly subsection header format: // ".aeabi_subsection name, optional, parameter type" // optional: required (0) optional (1) // parameter type: uleb128 or ULEB128 (0) ntbs or NTBS (1) - assert((Optional == 0 || Optional == 1) && "unsupported parameter for Optional"); - assert((ParameterType == 0 || ParameterType == 1) && "unsupported parameter for ParameterType"); + assert((Optional == 0 || Optional == 1) && + "unsupported parameter for Optional"); + assert((ParameterType == 0 || ParameterType == 1) && + "unsupported parameter for ParameterType"); StringRef OptionalStr = Optional ? "optional" : "required"; StringRef ParameterStr = ParameterType ? "NTBS" : "ULEB128"; - switch(SubsectionName) { - default: llvm_unreachable("unknown AArch64 build attributes subsection name"); - - case ARMBuildAttrs::AEBI_FEATURE_AND_BITS: - assert(Optional == 1 && "subsection .aeabi-feature-and-bits should be marked as optional and not as mandatory"); - assert(ParameterType == 0 && "subsection .aeabi-feature-and-bits should be marked as uleb128 and not as ntbs"); - OS << "\t.aeabi_subsection\t" << ".aeabi-feature-and-bits" << ", " << OptionalStr << ", " << ParameterStr; - break; + switch (SubsectionName) { + default: + llvm_unreachable("unknown AArch64 build attributes subsection name"); + + case ARMBuildAttrs::AEBI_FEATURE_AND_BITS: + assert(Optional == 1 && "subsection .aeabi-feature-and-bits should be " + "marked as optional and not as mandatory"); + assert(ParameterType == 0 && "subsection .aeabi-feature-and-bits should " + "be marked as uleb128 and not as ntbs"); + OS << "\t.aeabi_subsection\t" << ".aeabi-feature-and-bits" << ", " + << OptionalStr << ", " << ParameterStr; + break; - case ARMBuildAttrs::AEBI_PAUTHABI: - assert(Optional == 0 && "subsection .aeabi-pauthabi should be marked as mandatory and not as optional"); - assert(ParameterType == 0 && "subsection .aeabi-pauthabi should be marked as uleb128 and not as ntbs"); - OS << "\t.aeabi_subsection\t" << ".aeabi-pauthabi" << ", " << OptionalStr << ", " << ParameterStr; - break; + case ARMBuildAttrs::AEBI_PAUTHABI: + assert(Optional == 0 && "subsection .aeabi-pauthabi should be marked as " + "mandatory and not as optional"); + assert(ParameterType == 0 && "subsection .aeabi-pauthabi should be " + "marked as uleb128 and not as ntbs"); + OS << "\t.aeabi_subsection\t" << ".aeabi-pauthabi" << ", " << OptionalStr + << ", " << ParameterStr; + break; } OS << "\n"; } @@ -224,7 +238,8 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { AArch64TargetAsmStreamer::AArch64TargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) - : AArch64TargetStreamer(S), OS(OS), VendorTag("eabi"), IsVerboseAsm(S.isVerboseAsm()) {} + : AArch64TargetStreamer(S), OS(OS), VendorTag("eabi"), + IsVerboseAsm(S.isVerboseAsm()) {} void AArch64TargetAsmStreamer::emitInst(uint32_t Inst) { OS << "\t.inst\t0x" << Twine::utohexstr(Inst) << "\n"; @@ -364,7 +379,9 @@ AArch64ELFStreamer &AArch64TargetELFStreamer::getStreamer() { return static_cast<AArch64ELFStreamer &>(Streamer); } -void AArch64TargetELFStreamer::emitSubsection(unsigned Vendor, unsigned IsMandatory, unsigned ParameterType) { +void AArch64TargetELFStreamer::emitSubsection(unsigned Vendor, + unsigned IsMandatory, + unsigned ParameterType) { StringRef VendorAsStr = ARMBuildAttrs::vendorToStr(Vendor); // If exists, return. @@ -382,11 +399,13 @@ void AArch64TargetELFStreamer::emitSubsection(unsigned Vendor, unsigned IsMandat AttributeSubSections.push_back(AttSubSection); } -void AArch64TargetELFStreamer::emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, bool Override) { +void AArch64TargetELFStreamer::emitAttribute(unsigned Vendor, unsigned Tag, + unsigned Value, bool Override) { StringRef VendorAsStr = ARMBuildAttrs::vendorToStr(Vendor); if (AttributeSubSections.size() == 0) { - llvm_unreachable("Attribute can not be added unless the required AArch64 build attributes subsection exists"); + llvm_unreachable("Attribute can not be added unless the required AArch64 " + "build attributes subsection exists"); return; } @@ -408,7 +427,8 @@ void AArch64TargetELFStreamer::emitAttribute(unsigned Vendor, unsigned Tag, unsi return; } } - llvm_unreachable("Attribute can not be added unless the required AArch64 build attributes subsection exists"); + llvm_unreachable("Attribute can not be added unless the required AArch64 " + "build attributes subsection exists"); } void AArch64TargetELFStreamer::emitInst(uint32_t Inst) { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h index 7d90759cfc6e10..913754af6f2668 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h @@ -92,8 +92,10 @@ class AArch64TargetStreamer : public MCTargetStreamer { virtual void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) {} /// Build attributes implementation - virtual void emitSubsection(unsigned Vendor, unsigned IsMandatory, unsigned ParameterType) {} - virtual void emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, bool Override) {} + virtual void emitSubsection(unsigned Vendor, unsigned IsMandatory, + unsigned ParameterType) {} + virtual void emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, + bool Override) {} private: std::unique_ptr<AssemblerConstantPools> ConstantPools; @@ -108,8 +110,10 @@ class AArch64TargetELFStreamer : public AArch64TargetStreamer { SmallVector<MCELFStreamer::AttributeSubSection, 64> AttributeSubSections; /// Build attributes implementation - void emitSubsection(unsigned Vendor, unsigned IsMandatory, unsigned ParameterType) override; - void emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, bool Override) override; + void emitSubsection(unsigned Vendor, unsigned IsMandatory, + unsigned ParameterType) override; + void emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, + bool Override) override; void emitInst(uint32_t Inst) override; void emitDirectiveVariantPCS(MCSymbol *Symbol) override; @@ -117,7 +121,7 @@ class AArch64TargetELFStreamer : public AArch64TargetStreamer { public: AArch64TargetELFStreamer(MCStreamer &S) - : AArch64TargetStreamer(S), CurrentVendor("aeabi") {} + : AArch64TargetStreamer(S), CurrentVendor("aeabi") {} }; class AArch64TargetWinCOFFStreamer : public llvm::AArch64TargetStreamer { diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index b6a16de748d9b0..8c7fc4e7a17713 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -793,20 +793,23 @@ void ARMTargetELFStreamer::switchVendor(StringRef Vendor) { void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { getStreamer().setAttributeItem(Attribute, Value, - /* OverwriteExisting= */ true, getStreamer().Contents); + /* OverwriteExisting= */ true, + getStreamer().Contents); } void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute, StringRef Value) { getStreamer().setAttributeItem(Attribute, Value, - /* OverwriteExisting= */ true, getStreamer().Contents); + /* OverwriteExisting= */ true, + getStreamer().Contents); } void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue) { getStreamer().setAttributeItems(Attribute, IntValue, StringValue, - /* OverwriteExisting= */ true, getStreamer().Contents); + /* OverwriteExisting= */ true, + getStreamer().Contents); } void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) { @@ -821,12 +824,15 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() { using namespace ARMBuildAttrs; ARMELFStreamer &S = getStreamer(); - S.setAttributeItem(CPU_name, ARM::getCPUAttr(Arch), false, getStreamer().Contents); + S.setAttributeItem(CPU_name, ARM::getCPUAttr(Arch), false, + getStreamer().Contents); if (EmittedArch == ARM::ArchKind::INVALID) - S.setAttributeItem(CPU_arch, ARM::getArchAttr(Arch), false, getStreamer().Contents); + S.setAttributeItem(CPU_arch, ARM::getArchAttr(Arch), false, + getStreamer().Contents); else - S.setAttributeItem(CPU_arch, ARM::getArchAttr(EmittedArch), false, getStreamer().Contents); + S.setAttributeItem(CPU_arch, ARM::getArchAttr(EmittedArch), false, + getStreamer().Contents); switch (Arch) { case ARM::ArchKind::ARMV4: @@ -843,15 +849,17 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() { break; case ARM::ArchKind::ARMV6T2: - S.setAttributeItem(ARM_ISA_use, Allowed, false,getStreamer().Contents); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); + S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, + getStreamer().Contents); break; case ARM::ArchKind::ARMV6K: case ARM::ArchKind::ARMV6KZ: S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); S.setAttributeItem(THUMB_ISA_use, Allowed, false, getStreamer().Contents); - S.setAttributeItem(Virtualization_use, AllowTZ, false, getStreamer().Contents); + S.setAttributeItem(Virtualization_use, AllowTZ, false, + getStreamer().Contents); break; case ARM::ArchKind::ARMV6M: @@ -859,21 +867,27 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() { break; case ARM::ArchKind::ARMV7A: - S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false, getStreamer().Contents); + S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false, + getStreamer().Contents); S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, + getStreamer().Contents); break; case ARM::ArchKind::ARMV7R: - S.setAttributeItem(CPU_arch_profile, RealTimeProfile, false, getStreamer().Contents); + S.setAttributeItem(CPU_arch_profile, RealTimeProfile, false, + getStreamer().Contents); S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, + getStreamer().Contents); break; case ARM::ArchKind::ARMV7EM: case ARM::ArchKind::ARMV7M: - S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false, getStreamer().Contents); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); + S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false, + getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, + getStreamer().Contents); break; case ARM::ArchKind::ARMV8A: @@ -893,17 +907,22 @@ void ARMTargetELFStreamer::emitArchDefaultAttributes() { case ARM::ArchKind::ARMV9_4A: case ARM::ArchKind::ARMV9_5A: case ARM::ArchKind::ARMV9_6A: - S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false, getStreamer().Contents); + S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false, + getStreamer().Contents); S.setAttributeItem(ARM_ISA_use, Allowed, false, getStreamer().Contents); - S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false, + getStreamer().Contents); S.setAttributeItem(MPextension_use, Allowed, false, getStreamer().Contents); - S.setAttributeItem(Virtualization_use, AllowTZVirtualization, false, getStreamer().Contents); + S.setAttributeItem(Virtualization_use, AllowTZVirtualization, false, + getStreamer().Contents); break; case ARM::ArchKind::ARMV8MBaseline: case ARM::ArchKind::ARMV8MMainline: - S.setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false, getStreamer().Contents); - S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false, getStreamer().Contents); + S.setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false, + getStreamer().Contents); + S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false, + getStreamer().Contents); break; case ARM::ArchKind::IWMMXT: diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index d8a177a90a7a3d..4bc205e3f4b6d8 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -330,7 +330,8 @@ class HexagonTargetELFStreamer : public HexagonTargetStreamer { void emitAttribute(uint32_t Attribute, uint32_t Value) override { getStreamer().setAttributeItem(Attribute, Value, - /*OverwriteExisting=*/true, getStreamer().Contents); + /*OverwriteExisting=*/true, + getStreamer().Contents); } }; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp index ae536accb399a2..b5e2338f379b6b 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -57,19 +57,22 @@ void RISCVTargetELFStreamer::emitDirectiveOptionRelax() {} void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {} void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { - getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true, getStreamer().Contents); + getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true, + getStreamer().Contents); } void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute, StringRef String) { - getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true, getStreamer().Contents); + getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true, + getStreamer().Contents); } void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue) { getStreamer().setAttributeItems(Attribute, IntValue, StringValue, - /*OverwriteExisting=*/true, getStreamer().Contents); + /*OverwriteExisting=*/true, + getStreamer().Contents); } void RISCVTargetELFStreamer::finishAttributeSection() { >From 8bc5b42531321f7ec8337dafa09305b9e5b7a257 Mon Sep 17 00:00:00 2001 From: Sivan Shani <sivan.sh...@arm.com> Date: Fri, 6 Dec 2024 13:00:42 +0000 Subject: [PATCH 3/4] Fixing according to some comments: - make use of the enums - s/AEBI/AEABI/ - change function name (createAttributesSection) - remove AVAttribute code --- llvm/include/llvm/MC/MCELFStreamer.h | 17 +++--- .../include/llvm/Support/ARMBuildAttributes.h | 17 +----- llvm/lib/MC/MCELFStreamer.cpp | 2 +- llvm/lib/Support/ARMBuildAttrs.cpp | 59 ++----------------- llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 18 +++--- .../MCTargetDesc/AArch64ELFStreamer.cpp | 19 +++--- .../MCTargetDesc/AArch64TargetStreamer.h | 10 ++-- 7 files changed, 43 insertions(+), 99 deletions(-) diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index 0e37948d3d2b7f..f32e8d323935ee 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -13,6 +13,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCObjectStreamer.h" +#include "llvm/Support/ARMBuildAttributes.h" namespace llvm { @@ -113,10 +114,8 @@ class MCELFStreamer : public MCObjectStreamer { // [<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) + ARMBuildAttrs::SubsectionMandatory IsMandatory; + ARMBuildAttrs::SubsectionType ParameterType; SmallVector<AttributeItem, 64> Content; }; @@ -139,7 +138,8 @@ class MCELFStreamer : public MCObjectStreamer { emitAttributesSection(MCSection *&AttributeSection, const Twine &Section, unsigned Type, SmallVector<AttributeSubSection, 64> &SubSectionVec) { - createAttributesSection(AttributeSection, Section, Type, SubSectionVec); + createAArch64AttributesSection(AttributeSection, Section, Type, + SubSectionVec); } private: @@ -149,10 +149,9 @@ class MCELFStreamer : public MCObjectStreamer { 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); + void createAArch64AttributesSection( + 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 788d72977d6f05..2c940fb20485ee 100644 --- a/llvm/include/llvm/Support/ARMBuildAttributes.h +++ b/llvm/include/llvm/Support/ARMBuildAttributes.h @@ -28,16 +28,16 @@ namespace ARMBuildAttrs { const TagNameMap &getARMAttributeTags(); /// AArch64 build attributes vendors (=subsection name) -enum Vendor : unsigned { AEBI_FEATURE_AND_BITS = 0, AEBI_PAUTHABI = 1 }; +enum Vendor : unsigned { AEABI_FEATURE_AND_BITS = 0, AEABI_PAUTHABI = 1 }; inline StringRef vendorToStr(unsigned Vendor) { switch (Vendor) { default: llvm_unreachable("unknown AArch64 vendor name"); return ""; - case AEBI_FEATURE_AND_BITS: + case AEABI_FEATURE_AND_BITS: return "aeabi-feature-and-bits"; - case AEBI_PAUTHABI: + case AEABI_PAUTHABI: return "aeabi-pauthabi"; } } @@ -127,17 +127,6 @@ 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 576d4997a3dea7..0f49d042233f0b 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -786,7 +786,7 @@ void MCELFStreamer::createAttributesSection( AttrsVec.clear(); } -void MCELFStreamer::createAttributesSection( +void MCELFStreamer::createAArch64AttributesSection( MCSection *&AttributeSection, const Twine &Section, unsigned Type, SmallVector<AttributeSubSection, 64> &SubSectionVec) { // <format-version: 'A'> diff --git a/llvm/lib/Support/ARMBuildAttrs.cpp b/llvm/lib/Support/ARMBuildAttrs.cpp index 457e7d66a7e87a..815cfc62a4b0e3 100644 --- a/llvm/lib/Support/ARMBuildAttrs.cpp +++ b/llvm/lib/Support/ARMBuildAttrs.cpp @@ -6,13 +6,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/StringRef.h" #include "llvm/Support/ARMBuildAttributes.h" using namespace llvm; -namespace { -const TagNameItem ARMAttributeTags[] = { +static const TagNameItem tagData[] = { {ARMBuildAttrs::File, "Tag_File"}, {ARMBuildAttrs::Section, "Tag_Section"}, {ARMBuildAttrs::Symbol, "Tag_Symbol"}, @@ -69,56 +67,7 @@ const TagNameItem ARMAttributeTags[] = { {ARMBuildAttrs::ABI_align_preserved, "Tag_ABI_align8_preserved"}, }; -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(); +constexpr TagNameMap ARMAttributeTags{tagData}; +const TagNameMap &llvm::ARMBuildAttrs::getARMAttributeTags() { + return ARMAttributeTags; } -} // namespace - -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; } -} // namespace ARMBuildAttrs -} // namespace llvm diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index ca60e249e14214..a12d41e22fb3dc 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -465,11 +465,13 @@ void AArch64AsmPrinter::emitAttributes(unsigned Flags, PAuthABIVersion = (PAuthABIVersion == uint64_t(-1)) ? 0 : PAuthABIVersion; if (PAuthABIPlatform || PAuthABIVersion) { - TS->emitSubsection(ARMBuildAttrs::AEBI_PAUTHABI, 0, 0); - TS->emitAttribute(ARMBuildAttrs::AEBI_PAUTHABI, + TS->emitSubsection(ARMBuildAttrs::AEABI_PAUTHABI, + ARMBuildAttrs::SubsectionMandatory::OPTIONAL, + ARMBuildAttrs::SubsectionType::ULEB128); + TS->emitAttribute(ARMBuildAttrs::AEABI_PAUTHABI, ARMBuildAttrs::Tag_PAuth_Platform, PAuthABIPlatform, false); - TS->emitAttribute(ARMBuildAttrs::AEBI_PAUTHABI, + TS->emitAttribute(ARMBuildAttrs::AEABI_PAUTHABI, ARMBuildAttrs::Tag_PAuth_Schema, PAuthABIVersion, false); } @@ -478,12 +480,14 @@ void AArch64AsmPrinter::emitAttributes(unsigned Flags, 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, + TS->emitSubsection(ARMBuildAttrs::AEABI_FEATURE_AND_BITS, + ARMBuildAttrs::SubsectionMandatory::REQUIRED, + ARMBuildAttrs::SubsectionType::ULEB128); + TS->emitAttribute(ARMBuildAttrs::AEABI_FEATURE_AND_BITS, ARMBuildAttrs::Tag_Feature_BTI, BTIValue, false); - TS->emitAttribute(ARMBuildAttrs::AEBI_FEATURE_AND_BITS, + TS->emitAttribute(ARMBuildAttrs::AEABI_FEATURE_AND_BITS, ARMBuildAttrs::Tag_Feature_PAC, PACValue, false); - TS->emitAttribute(ARMBuildAttrs::AEBI_FEATURE_AND_BITS, + TS->emitAttribute(ARMBuildAttrs::AEABI_FEATURE_AND_BITS, ARMBuildAttrs::Tag_Feature_GCS, GCSValue, false); } } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp index cb594785a09d2f..b9c70177436df4 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp @@ -160,7 +160,7 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { default: llvm_unreachable("unknown AArch64 build attributes subsection name"); - case ARMBuildAttrs::AEBI_FEATURE_AND_BITS: + case ARMBuildAttrs::AEABI_FEATURE_AND_BITS: switch (Tag) { default: llvm_unreachable("unknown tag for the feature-and-bits subsection"); @@ -176,7 +176,7 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { } break; - case ARMBuildAttrs::AEBI_PAUTHABI: + case ARMBuildAttrs::AEABI_PAUTHABI: switch (Tag) { default: llvm_unreachable("unknown tag for the feature-and-bits subsection"); @@ -192,8 +192,9 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { OS << "\n"; } - void emitSubsection(unsigned SubsectionName, unsigned Optional, - unsigned ParameterType) override { + void emitSubsection(unsigned SubsectionName, + ARMBuildAttrs::SubsectionMandatory Optional, + ARMBuildAttrs::SubsectionType ParameterType) override { // The AArch64 build attributes assembly subsection header format: // ".aeabi_subsection name, optional, parameter type" // optional: required (0) optional (1) @@ -211,7 +212,7 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { default: llvm_unreachable("unknown AArch64 build attributes subsection name"); - case ARMBuildAttrs::AEBI_FEATURE_AND_BITS: + case ARMBuildAttrs::AEABI_FEATURE_AND_BITS: assert(Optional == 1 && "subsection .aeabi-feature-and-bits should be " "marked as optional and not as mandatory"); assert(ParameterType == 0 && "subsection .aeabi-feature-and-bits should " @@ -220,7 +221,7 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { << OptionalStr << ", " << ParameterStr; break; - case ARMBuildAttrs::AEBI_PAUTHABI: + case ARMBuildAttrs::AEABI_PAUTHABI: assert(Optional == 0 && "subsection .aeabi-pauthabi should be marked as " "mandatory and not as optional"); assert(ParameterType == 0 && "subsection .aeabi-pauthabi should be " @@ -379,9 +380,9 @@ AArch64ELFStreamer &AArch64TargetELFStreamer::getStreamer() { return static_cast<AArch64ELFStreamer &>(Streamer); } -void AArch64TargetELFStreamer::emitSubsection(unsigned Vendor, - unsigned IsMandatory, - unsigned ParameterType) { +void AArch64TargetELFStreamer::emitSubsection( + unsigned Vendor, ARMBuildAttrs::SubsectionMandatory IsMandatory, + ARMBuildAttrs::SubsectionType ParameterType) { StringRef VendorAsStr = ARMBuildAttrs::vendorToStr(Vendor); // If exists, return. diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h index 913754af6f2668..1aa207b40a9326 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h @@ -92,8 +92,9 @@ class AArch64TargetStreamer : public MCTargetStreamer { virtual void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) {} /// Build attributes implementation - virtual void emitSubsection(unsigned Vendor, unsigned IsMandatory, - unsigned ParameterType) {} + virtual void emitSubsection(unsigned Vendor, + ARMBuildAttrs::SubsectionMandatory IsMandatory, + ARMBuildAttrs::SubsectionType ParameterType) {} virtual void emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, bool Override) {} @@ -110,8 +111,9 @@ class AArch64TargetELFStreamer : public AArch64TargetStreamer { SmallVector<MCELFStreamer::AttributeSubSection, 64> AttributeSubSections; /// Build attributes implementation - void emitSubsection(unsigned Vendor, unsigned IsMandatory, - unsigned ParameterType) override; + void emitSubsection(unsigned Vendor, + ARMBuildAttrs::SubsectionMandatory IsMandatory, + ARMBuildAttrs::SubsectionType ParameterType) override; void emitAttribute(unsigned Vendor, unsigned Tag, unsigned Value, bool Override) override; >From 6e09e352dd559bd54b4000593bfe913d5f78d1fe Mon Sep 17 00:00:00 2001 From: Sivan Shani <sivan.sh...@arm.com> Date: Fri, 6 Dec 2024 16:35:55 +0000 Subject: [PATCH 4/4] Add test files --- ...ld-attributes-aeabi-feature-and-bits-ASM.c | 30 +++++++++++++++++++ ...ld-attributes-aeabi-feature-and-bits-ELF.c | 30 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 clang/test/CodeGen/AArch64/aarch64-build-attributes-aeabi-feature-and-bits-ASM.c create mode 100644 clang/test/CodeGen/AArch64/aarch64-build-attributes-aeabi-feature-and-bits-ELF.c diff --git a/clang/test/CodeGen/AArch64/aarch64-build-attributes-aeabi-feature-and-bits-ASM.c b/clang/test/CodeGen/AArch64/aarch64-build-attributes-aeabi-feature-and-bits-ASM.c new file mode 100644 index 00000000000000..2a64274b3f4f1e --- /dev/null +++ b/clang/test/CodeGen/AArch64/aarch64-build-attributes-aeabi-feature-and-bits-ASM.c @@ -0,0 +1,30 @@ +// Test AArch64 build attributes to assmebly: 'aeabi-feature-and-bits' + +// RUN: %clang --target=aarch64-none-elf -mbranch-protection=bti+pac-ret+gcs -S -o- %s | FileCheck %s -check-prefix=ALL +// RUN: %clang --target=aarch64-none-elf -mbranch-protection=bti -S -o- %s | FileCheck %s -check-prefix=BTI +// RUN: %clang --target=aarch64-none-elf -mbranch-protection=pac-ret -S -o- %s | FileCheck %s -check-prefix=PAC +// RUN: %clang --target=aarch64-none-elf -mbranch-protection=gcs -S -o- %s | FileCheck %s -check-prefix=GCS + +// ALL: .text +// ALL-NEXT: .aeabi_subsection .aeabi-feature-and-bits, optional, ULEB128 +// ALL-NEXT: .aeabi_attribute Tag_Feature_BTI, 1 +// ALL-NEXT: .aeabi_attribute Tag_Feature_PAC, 1 +// ALL-NEXT: .aeabi_attribute Tag_Feature_GCS, 1 + +// BTI: .text +// BTI-NEXT: .aeabi_subsection .aeabi-feature-and-bits, optional, ULEB128 +// BTI-NEXT: .aeabi_attribute Tag_Feature_BTI, 1 +// BTI-NEXT: .aeabi_attribute Tag_Feature_PAC, 0 +// BTI-NEXT: .aeabi_attribute Tag_Feature_GCS, 0 + +// PAC: .text +// PAC-NEXT: .aeabi_subsection .aeabi-feature-and-bits, optional, ULEB128 +// PAC-NEXT: .aeabi_attribute Tag_Feature_BTI, 0 +// PAC-NEXT: .aeabi_attribute Tag_Feature_PAC, 1 +// PAC-NEXT: .aeabi_attribute Tag_Feature_GCS, 0 + +// GCS: .text +// GCS-NEXT: .aeabi_subsection .aeabi-feature-and-bits, optional, ULEB128 +// GCS-NEXT: .aeabi_attribute Tag_Feature_BTI, 0 +// GCS-NEXT: .aeabi_attribute Tag_Feature_PAC, 0 +// GCS-NEXT: .aeabi_attribute Tag_Feature_GCS, 1 \ No newline at end of file diff --git a/clang/test/CodeGen/AArch64/aarch64-build-attributes-aeabi-feature-and-bits-ELF.c b/clang/test/CodeGen/AArch64/aarch64-build-attributes-aeabi-feature-and-bits-ELF.c new file mode 100644 index 00000000000000..b4191a340128d9 --- /dev/null +++ b/clang/test/CodeGen/AArch64/aarch64-build-attributes-aeabi-feature-and-bits-ELF.c @@ -0,0 +1,30 @@ +// Test AArch64 build attributes to ELF: 'aeabi-feature-and-bits' + +// RUN: %clang -c --target=aarch64-none-elf -mbranch-protection=bti+pac-ret+gcs %s -o %t +// RUN: llvm-readelf --hex-dump=.ARM.attributes %t | FileCheck %s -check-prefix=ALL +// RUN: %clang -c --target=aarch64-none-elf -mbranch-protection=bti %s -o %t +// RUN: llvm-readelf --hex-dump=.ARM.attributes %t | FileCheck %s -check-prefix=BTI +// RUN: %clang -c --target=aarch64-none-elf -mbranch-protection=pac-ret %s -o %t +// RUN: llvm-readelf --hex-dump=.ARM.attributes %t | FileCheck %s -check-prefix=PAC +// RUN: %clang -c --target=aarch64-none-elf -mbranch-protection=gcs %s -o %t +// RUN: llvm-readelf --hex-dump=.ARM.attributes %t | FileCheck %s -check-prefix=GCS + +// ALL: Hex dump of section '.ARM.attributes': +// ALL-NEXT: 0x00000000 41230000 00616561 62692d66 65617475 A#...aeabi-featu +// ALL-NEXT: 0x00000010 72652d61 6e642d62 69747301 00000101 re-and-bits..... +// ALL-NEXT: 0x00000020 010201 + +// BTI: Hex dump of section '.ARM.attributes': +// BTI-NEXT: 0x00000000 41230000 00616561 62692d66 65617475 A#...aeabi-featu +// BTI-NEXT: 0x00000010 72652d61 6e642d62 69747301 00000101 re-and-bits..... +// BTI-NEXT: 0x00000020 000200 + +// PAC: Hex dump of section '.ARM.attributes': +// PAC-NEXT: 0x00000000 41230000 00616561 62692d66 65617475 A#...aeabi-featu +// PAC-NEXT: 0x00000010 72652d61 6e642d62 69747301 00000001 re-and-bits..... +// PAC-NEXT: 0x00000020 010200 + +// GCS: Hex dump of section '.ARM.attributes': +// GCS-NEXT: 0x00000000 41230000 00616561 62692d66 65617475 A#...aeabi-featu +// GCS-NEXT: 0x00000010 72652d61 6e642d62 69747301 00000001 re-and-bits..... +// GCS-NEXT: 0x00000020 000201 \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits