diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 60c72062a3f6..bafc92cafe53 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -410,6 +410,9 @@ protected: case ELF::EM_ARM: Type = ELF::SHT_ARM_ATTRIBUTES; break; + case ELF::EM_AARCH64: + Type = ELF::SHT_AARCH64_ATTRIBUTES; + break; case ELF::EM_RISCV: Type = ELF::SHT_RISCV_ATTRIBUTES; break; diff --git a/llvm/include/llvm/Support/AArch64AttributeParser.h b/llvm/include/llvm/Support/AArch64AttributeParser.h new file mode 100644 index 000000000000..823ae180a5c5 --- /dev/null +++ b/llvm/include/llvm/Support/AArch64AttributeParser.h @@ -0,0 +1,29 @@ +//=== - AArch64AttributeParser.h-AArch64 Attribute Information Printer - ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H +#define LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H + +#include "llvm/Support/ELFAttrParserExtended.h" +#include "llvm/Support/ELFAttributes.h" + +namespace llvm { + +class AArch64AttributeParser : public ELFExtendedAttrParser { + static std::vector &returnTagsNamesMap(); + +public: + AArch64AttributeParser(ScopedPrinter *Sw) + : ELFExtendedAttrParser(Sw, returnTagsNamesMap()) {} + AArch64AttributeParser() + : ELFExtendedAttrParser(nullptr, returnTagsNamesMap()) {} +}; + +} // namespace llvm + +#endif // LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H diff --git a/llvm/include/llvm/Support/AArch64BuildAttributes.h b/llvm/include/llvm/Support/AArch64BuildAttributes.h index 2479992cf8e7..477c7f4f7efe 100644 --- a/llvm/include/llvm/Support/AArch64BuildAttributes.h +++ b/llvm/include/llvm/Support/AArch64BuildAttributes.h @@ -22,7 +22,7 @@ namespace llvm { -namespace AArch64BuildAttrs { +namespace AArch64BuildAttributes { /// AArch64 build attributes vendors IDs (a.k.a subsection name) enum VendorID : unsigned { @@ -69,7 +69,7 @@ enum FeatureAndBitsFlag : unsigned { Feature_PAC_Flag = 1 << 1, Feature_GCS_Flag = 1 << 2 }; -} // namespace AArch64BuildAttrs +} // namespace AArch64BuildAttributes } // namespace llvm -#endif // LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H \ No newline at end of file +#endif // LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H diff --git a/llvm/include/llvm/Support/ARMAttributeParser.h b/llvm/include/llvm/Support/ARMAttributeParser.h index d1d953120ae7..749f9cd2213d 100644 --- a/llvm/include/llvm/Support/ARMAttributeParser.h +++ b/llvm/include/llvm/Support/ARMAttributeParser.h @@ -10,15 +10,15 @@ #define LLVM_SUPPORT_ARMATTRIBUTEPARSER_H #include "ARMBuildAttributes.h" -#include "ELFAttributeParser.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ELFAttrParserCompact.h" #include "llvm/Support/Error.h" namespace llvm { class ScopedPrinter; -class ARMAttributeParser : public ELFAttributeParser { +class ARMAttributeParser : public ELFCompactAttrParser { struct DisplayHandler { ARMBuildAttrs::AttrType attribute; Error (ARMAttributeParser::*routine)(ARMBuildAttrs::AttrType); @@ -74,9 +74,10 @@ class ARMAttributeParser : public ELFAttributeParser { public: ARMAttributeParser(ScopedPrinter *sw) - : ELFAttributeParser(sw, ARMBuildAttrs::getARMAttributeTags(), "aeabi") {} + : ELFCompactAttrParser(sw, ARMBuildAttrs::getARMAttributeTags(), + "aeabi") {} ARMAttributeParser() - : ELFAttributeParser(ARMBuildAttrs::getARMAttributeTags(), "aeabi") {} + : ELFCompactAttrParser(ARMBuildAttrs::getARMAttributeTags(), "aeabi") {} }; } diff --git a/llvm/include/llvm/Support/CSKYAttributeParser.h b/llvm/include/llvm/Support/CSKYAttributeParser.h index e926ebe5e306..08257a744a95 100644 --- a/llvm/include/llvm/Support/CSKYAttributeParser.h +++ b/llvm/include/llvm/Support/CSKYAttributeParser.h @@ -10,10 +10,10 @@ #define LLVM_SUPPORT_CSKYATTRIBUTEPARSER_H #include "llvm/Support/CSKYAttributes.h" -#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/ELFAttrParserCompact.h" namespace llvm { -class CSKYAttributeParser : public ELFAttributeParser { +class CSKYAttributeParser : public ELFCompactAttrParser { struct DisplayHandler { CSKYAttrs::AttrType attribute; Error (CSKYAttributeParser::*routine)(unsigned); @@ -33,9 +33,9 @@ class CSKYAttributeParser : public ELFAttributeParser { public: CSKYAttributeParser(ScopedPrinter *sw) - : ELFAttributeParser(sw, CSKYAttrs::getCSKYAttributeTags(), "csky") {} + : ELFCompactAttrParser(sw, CSKYAttrs::getCSKYAttributeTags(), "csky") {} CSKYAttributeParser() - : ELFAttributeParser(CSKYAttrs::getCSKYAttributeTags(), "csky") {} + : ELFCompactAttrParser(CSKYAttrs::getCSKYAttributeTags(), "csky") {} }; } // namespace llvm diff --git a/llvm/include/llvm/Support/ELFAttrParserCompact.h b/llvm/include/llvm/Support/ELFAttrParserCompact.h new file mode 100644 index 000000000000..34f740bc9f0a --- /dev/null +++ b/llvm/include/llvm/Support/ELFAttrParserCompact.h @@ -0,0 +1,92 @@ +//===- ELF AttributeParser.h - ELF Attribute Parser -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H +#define LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/ELFAttributes.h" +#include "llvm/Support/Error.h" + +#include +#include + +namespace llvm { +class StringRef; +class ScopedPrinter; + +class ELFCompactAttrParser : public ELFAttributeParser { + StringRef vendor; + std::unordered_map attributes; + std::unordered_map attributesStr; + + virtual Error handler(uint64_t tag, bool &handled) = 0; + +protected: + ScopedPrinter *sw; + TagNameMap tagToStringMap; + DataExtractor de{ArrayRef{}, true, 0}; + DataExtractor::Cursor cursor{0}; + + void printAttribute(unsigned tag, unsigned value, StringRef valueDesc); + + Error parseStringAttribute(const char *name, unsigned tag, + ArrayRef strings); + Error parseAttributeList(uint32_t length); + void parseIndexList(SmallVectorImpl &indexList); + Error parseSubsection(uint32_t length); + + void setAttributeString(unsigned tag, StringRef value) { + attributesStr.emplace(tag, value); + } + +public: + virtual ~ELFCompactAttrParser() { static_cast(!cursor.takeError()); } + Error integerAttribute(unsigned tag); + Error stringAttribute(unsigned tag); + + ELFCompactAttrParser(ScopedPrinter *sw, TagNameMap tagNameMap, + StringRef vendor) + : vendor(vendor), sw(sw), tagToStringMap(tagNameMap) {} + ELFCompactAttrParser(TagNameMap tagNameMap, StringRef vendor) + : vendor(vendor), sw(nullptr), tagToStringMap(tagNameMap) {} + + Error parse(ArrayRef section, llvm::endianness endian) override; + + std::optional getAttributeValue(unsigned tag) const override { + auto I = attributes.find(tag); + if (I == attributes.end()) + return std::nullopt; + return I->second; + } + std::optional + getAttributeValue(StringRef buildAttributeSubsectionName, + unsigned tag) const override { + assert("" == buildAttributeSubsectionName && + "buildAttributeSubsectionName must be an empty string"); + return getAttributeValue(tag); + } + std::optional getAttributeString(unsigned tag) const override { + auto I = attributesStr.find(tag); + if (I == attributesStr.end()) + return std::nullopt; + return I->second; + } + std::optional + getAttributeString(StringRef buildAttributeSubsectionName, + unsigned tag) const override { + assert("" == buildAttributeSubsectionName && + "buildAttributeSubsectionName must be an empty string"); + return getAttributeString(tag); + } +}; + +} // namespace llvm +#endif // LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H diff --git a/llvm/include/llvm/Support/ELFAttrParserExtended.h b/llvm/include/llvm/Support/ELFAttrParserExtended.h new file mode 100644 index 000000000000..63712c38d731 --- /dev/null +++ b/llvm/include/llvm/Support/ELFAttrParserExtended.h @@ -0,0 +1,56 @@ +//===- ELF AttributeParser.h - ELF Attribute Parser -------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H +#define LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/ELFAttributes.h" +#include "llvm/Support/Error.h" +#include +#include + +namespace llvm { +class StringRef; +class ScopedPrinter; + +class ELFExtendedAttrParser : public ELFAttributeParser { +protected: + ScopedPrinter *Sw; + DataExtractor De{ArrayRef{}, true, 0}; + DataExtractor::Cursor Cursor{0}; + + // Data structure for holding Extended ELF Build Attribute subsection + SmallVector SubSectionVec; + // Maps SubsectionName + Tag to tags names. Required for printing comments. + const std::vector TagsNamesMap; + StringRef getTagName(const StringRef &BuildAttrSubsectionName, + const unsigned Tag); + +public: + Error parse(ArrayRef Section, llvm::endianness Endian) override; + + std::optional getAttributeValue(unsigned Tag) const override; + std::optional getAttributeValue(StringRef BuildAttrSubsectionName, + unsigned Tag) const override; + std::optional getAttributeString(unsigned Tag) const override; + std::optional getAttributeString(StringRef BuildAttrSubsectionName, + unsigned Tag) const override; + + ELFExtendedAttrParser( + ScopedPrinter *Sw, + const std::vector TagsNamesMap) + : Sw(Sw), TagsNamesMap(TagsNamesMap) {} + ELFExtendedAttrParser( + const std::vector TagsNamesMap) + : Sw(nullptr), TagsNamesMap(TagsNamesMap) {} +}; +} // namespace llvm +#endif // LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H diff --git a/llvm/include/llvm/Support/ELFAttributeParser.h b/llvm/include/llvm/Support/ELFAttributeParser.h index ffb92468fb37..97350edb793c 100644 --- a/llvm/include/llvm/Support/ELFAttributeParser.h +++ b/llvm/include/llvm/Support/ELFAttributeParser.h @@ -9,69 +9,34 @@ #ifndef LLVM_SUPPORT_ELFATTRIBUTEPARSER_H #define LLVM_SUPPORT_ELFATTRIBUTEPARSER_H -#include "ELFAttributes.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/Support/DataExtractor.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" -#include -#include - namespace llvm { -class StringRef; -class ScopedPrinter; class ELFAttributeParser { - StringRef vendor; - std::unordered_map attributes; - std::unordered_map attributesStr; - - virtual Error handler(uint64_t tag, bool &handled) = 0; - -protected: - ScopedPrinter *sw; - TagNameMap tagToStringMap; - DataExtractor de{ArrayRef{}, true, 0}; - DataExtractor::Cursor cursor{0}; - - void printAttribute(unsigned tag, unsigned value, StringRef valueDesc); - - Error parseStringAttribute(const char *name, unsigned tag, - ArrayRef strings); - Error parseAttributeList(uint32_t length); - void parseIndexList(SmallVectorImpl &indexList); - Error parseSubsection(uint32_t length); - - void setAttributeString(unsigned tag, StringRef value) { - attributesStr.emplace(tag, value); - } - public: - virtual ~ELFAttributeParser() { static_cast(!cursor.takeError()); } - Error integerAttribute(unsigned tag); - Error stringAttribute(unsigned tag); + virtual ~ELFAttributeParser() {} - ELFAttributeParser(ScopedPrinter *sw, TagNameMap tagNameMap, StringRef vendor) - : vendor(vendor), sw(sw), tagToStringMap(tagNameMap) {} - - ELFAttributeParser(TagNameMap tagNameMap, StringRef vendor) - : vendor(vendor), sw(nullptr), tagToStringMap(tagNameMap) {} - - Error parse(ArrayRef section, llvm::endianness endian); - - std::optional getAttributeValue(unsigned tag) const { - auto I = attributes.find(tag); - if (I == attributes.end()) - return std::nullopt; - return I->second; + virtual Error parse(ArrayRef Section, llvm::endianness Endian) { + return llvm::Error::success(); } - std::optional getAttributeString(unsigned tag) const { - auto I = attributesStr.find(tag); - if (I == attributesStr.end()) - return std::nullopt; - return I->second; + virtual std::optional + getAttributeValue(StringRef BuildAttrSubsectionName, unsigned Tag) const { + return std::nullopt; + } + virtual std::optional getAttributeValue(unsigned Tag) const { + return std::nullopt; + } + virtual std::optional + getAttributeString(StringRef BuildAttrSubsectionName, unsigned Tag) const { + return std::nullopt; + } + virtual std::optional getAttributeString(unsigned Tag) const { + return std::nullopt; } }; } // namespace llvm -#endif +#endif // LLVM_SUPPORT_ELFATTRIBUTEPARSER_H diff --git a/llvm/include/llvm/Support/ELFAttributes.h b/llvm/include/llvm/Support/ELFAttributes.h index 295d0f466981..6782aec6050a 100644 --- a/llvm/include/llvm/Support/ELFAttributes.h +++ b/llvm/include/llvm/Support/ELFAttributes.h @@ -15,6 +15,7 @@ namespace llvm { +// Tag to string: ELF compact build attribute section struct TagNameItem { unsigned attr; StringRef tagName; @@ -22,6 +23,34 @@ struct TagNameItem { using TagNameMap = ArrayRef; +// Build Attribute storage for ELF extended attribute section +struct BuildAttributeItem { + enum Types : uint8_t { + NumericAttribute = 0, + TextAttribute, + } Type; + unsigned Tag; + unsigned IntValue; + std::string StringValue; + BuildAttributeItem(Types Ty, unsigned Tg, unsigned IV, std::string SV) + : Type(Ty), Tag(Tg), IntValue(IV), StringValue(std::move(SV)) {} +}; +struct BuildAttributeSubSection { + StringRef Name; + unsigned IsOptional; + unsigned ParameterType; + SmallVector Content; +}; + +// Tag to string: ELF extended build attribute section +struct SubsectionAndTagToTagName { + StringRef SubsectionName; + unsigned Tag; + StringRef TagName; + SubsectionAndTagToTagName(StringRef SN, unsigned Tg, StringRef TN) + : SubsectionName(SN), Tag(Tg), TagName(TN) {} +}; + namespace ELFAttrs { enum AttrType : unsigned { File = 1, Section = 2, Symbol = 3 }; diff --git a/llvm/include/llvm/Support/HexagonAttributeParser.h b/llvm/include/llvm/Support/HexagonAttributeParser.h index 1116dd42b1ad..462bfc4e2df1 100644 --- a/llvm/include/llvm/Support/HexagonAttributeParser.h +++ b/llvm/include/llvm/Support/HexagonAttributeParser.h @@ -9,11 +9,11 @@ #ifndef LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H #define LLVM_SUPPORT_HEXAGONATTRIBUTEPARSER_H -#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/ELFAttrParserCompact.h" #include "llvm/Support/HexagonAttributes.h" namespace llvm { -class HexagonAttributeParser : public ELFAttributeParser { +class HexagonAttributeParser : public ELFCompactAttrParser { struct DisplayHandler { HexagonAttrs::AttrType Attribute; Error (HexagonAttributeParser::*Routine)(unsigned); @@ -25,11 +25,11 @@ class HexagonAttributeParser : public ELFAttributeParser { public: HexagonAttributeParser(ScopedPrinter *SP) - : ELFAttributeParser(SP, HexagonAttrs::getHexagonAttributeTags(), - "hexagon") {} + : ELFCompactAttrParser(SP, HexagonAttrs::getHexagonAttributeTags(), + "hexagon") {} HexagonAttributeParser() - : ELFAttributeParser(HexagonAttrs::getHexagonAttributeTags(), "hexagon") { - } + : ELFCompactAttrParser(HexagonAttrs::getHexagonAttributeTags(), + "hexagon") {} }; } // namespace llvm diff --git a/llvm/include/llvm/Support/MSP430AttributeParser.h b/llvm/include/llvm/Support/MSP430AttributeParser.h index bc9b21494470..3a4f1b43d9d1 100644 --- a/llvm/include/llvm/Support/MSP430AttributeParser.h +++ b/llvm/include/llvm/Support/MSP430AttributeParser.h @@ -14,11 +14,11 @@ #ifndef LLVM_SUPPORT_MSP430ATTRIBUTEPARSER_H #define LLVM_SUPPORT_MSP430ATTRIBUTEPARSER_H -#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/ELFAttrParserCompact.h" #include "llvm/Support/MSP430Attributes.h" namespace llvm { -class MSP430AttributeParser : public ELFAttributeParser { +class MSP430AttributeParser : public ELFCompactAttrParser { struct DisplayHandler { MSP430Attrs::AttrType Attribute; Error (MSP430AttributeParser::*Routine)(MSP430Attrs::AttrType); @@ -34,10 +34,10 @@ class MSP430AttributeParser : public ELFAttributeParser { public: MSP430AttributeParser(ScopedPrinter *SW) - : ELFAttributeParser(SW, MSP430Attrs::getMSP430AttributeTags(), - "mspabi") {} + : ELFCompactAttrParser(SW, MSP430Attrs::getMSP430AttributeTags(), + "mspabi") {} MSP430AttributeParser() - : ELFAttributeParser(MSP430Attrs::getMSP430AttributeTags(), "mspabi") {} + : ELFCompactAttrParser(MSP430Attrs::getMSP430AttributeTags(), "mspabi") {} }; } // namespace llvm diff --git a/llvm/include/llvm/Support/RISCVAttributeParser.h b/llvm/include/llvm/Support/RISCVAttributeParser.h index 9f295504de95..4a74ed321d7a 100644 --- a/llvm/include/llvm/Support/RISCVAttributeParser.h +++ b/llvm/include/llvm/Support/RISCVAttributeParser.h @@ -9,11 +9,11 @@ #ifndef LLVM_SUPPORT_RISCVATTRIBUTEPARSER_H #define LLVM_SUPPORT_RISCVATTRIBUTEPARSER_H -#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/ELFAttrParserCompact.h" #include "llvm/Support/RISCVAttributes.h" namespace llvm { -class RISCVAttributeParser : public ELFAttributeParser { +class RISCVAttributeParser : public ELFCompactAttrParser { struct DisplayHandler { RISCVAttrs::AttrType attribute; Error (RISCVAttributeParser::*routine)(unsigned); @@ -28,9 +28,10 @@ class RISCVAttributeParser : public ELFAttributeParser { public: RISCVAttributeParser(ScopedPrinter *sw) - : ELFAttributeParser(sw, RISCVAttrs::getRISCVAttributeTags(), "riscv") {} + : ELFCompactAttrParser(sw, RISCVAttrs::getRISCVAttributeTags(), "riscv") { + } RISCVAttributeParser() - : ELFAttributeParser(RISCVAttrs::getRISCVAttributeTags(), "riscv") {} + : ELFCompactAttrParser(RISCVAttrs::getRISCVAttributeTags(), "riscv") {} }; } // namespace llvm diff --git a/llvm/lib/Support/AArch64AttributeParser.cpp b/llvm/lib/Support/AArch64AttributeParser.cpp new file mode 100644 index 000000000000..c675ef2a3b3d --- /dev/null +++ b/llvm/lib/Support/AArch64AttributeParser.cpp @@ -0,0 +1,21 @@ +//===-- AArch64AttributeParser.cpp - AArch64 Build Attributes PArser------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with +// LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===---------------------------------------------------------------------===// + +#include "llvm/Support/AArch64AttributeParser.h" + +std::vector & +llvm::AArch64AttributeParser::returnTagsNamesMap() { + static std::vector TagsNamesMap = { + {"aeabi_pauthabi", 1, "Tag_PAuth_Platform"}, + {"aeabi_pauthabi", 2, "Tag_PAuth_Schema"}, + {"aeabi_feature_and_bits", 0, "Tag_Feature_BTI"}, + {"aeabi_feature_and_bits", 1, "Tag_Feature_PAC"}, + {"aeabi_feature_and_bits", 2, "Tag_Feature_GCS"}}; + return TagsNamesMap; +} diff --git a/llvm/lib/Support/AArch64BuildAttributes.cpp b/llvm/lib/Support/AArch64BuildAttributes.cpp index e36667ca711e..4a6b2fd53880 100644 --- a/llvm/lib/Support/AArch64BuildAttributes.cpp +++ b/llvm/lib/Support/AArch64BuildAttributes.cpp @@ -10,9 +10,9 @@ #include "llvm/ADT/StringSwitch.h" using namespace llvm; -using namespace llvm::AArch64BuildAttrs; +using namespace llvm::AArch64BuildAttributes; -StringRef AArch64BuildAttrs::getVendorName(unsigned Vendor) { +StringRef AArch64BuildAttributes::getVendorName(unsigned Vendor) { switch (Vendor) { case AEABI_FEATURE_AND_BITS: return "aeabi_feature_and_bits"; @@ -25,14 +25,14 @@ StringRef AArch64BuildAttrs::getVendorName(unsigned Vendor) { return ""; } } -VendorID AArch64BuildAttrs::getVendorID(StringRef Vendor) { +VendorID AArch64BuildAttributes::getVendorID(StringRef Vendor) { return StringSwitch(Vendor) .Case("aeabi_feature_and_bits", AEABI_FEATURE_AND_BITS) .Case("aeabi_pauthabi", AEABI_PAUTHABI) .Default(VENDOR_UNKNOWN); } -StringRef AArch64BuildAttrs::getOptionalStr(unsigned Optional) { +StringRef AArch64BuildAttributes::getOptionalStr(unsigned Optional) { switch (Optional) { case REQUIRED: return "required"; @@ -43,18 +43,18 @@ StringRef AArch64BuildAttrs::getOptionalStr(unsigned Optional) { return ""; } } -SubsectionOptional AArch64BuildAttrs::getOptionalID(StringRef Optional) { +SubsectionOptional AArch64BuildAttributes::getOptionalID(StringRef Optional) { return StringSwitch(Optional) .Case("required", REQUIRED) .Case("optional", OPTIONAL) .Default(OPTIONAL_NOT_FOUND); } -StringRef AArch64BuildAttrs::getSubsectionOptionalUnknownError() { +StringRef AArch64BuildAttributes::getSubsectionOptionalUnknownError() { return "unknown AArch64 build attributes optionality, expected " "required|optional"; } -StringRef AArch64BuildAttrs::getTypeStr(unsigned Type) { +StringRef AArch64BuildAttributes::getTypeStr(unsigned Type) { switch (Type) { case ULEB128: return "uleb128"; @@ -65,17 +65,17 @@ StringRef AArch64BuildAttrs::getTypeStr(unsigned Type) { return ""; } } -SubsectionType AArch64BuildAttrs::getTypeID(StringRef Type) { +SubsectionType AArch64BuildAttributes::getTypeID(StringRef Type) { return StringSwitch(Type) .Cases("uleb128", "ULEB128", ULEB128) .Cases("ntbs", "NTBS", NTBS) .Default(TYPE_NOT_FOUND); } -StringRef AArch64BuildAttrs::getSubsectionTypeUnknownError() { +StringRef AArch64BuildAttributes::getSubsectionTypeUnknownError() { return "unknown AArch64 build attributes type, expected uleb128|ntbs"; } -StringRef AArch64BuildAttrs::getPauthABITagsStr(unsigned PauthABITag) { +StringRef AArch64BuildAttributes::getPauthABITagsStr(unsigned PauthABITag) { switch (PauthABITag) { case TAG_PAUTH_PLATFORM: return "Tag_PAuth_Platform"; @@ -87,7 +87,7 @@ StringRef AArch64BuildAttrs::getPauthABITagsStr(unsigned PauthABITag) { } } -PauthABITags AArch64BuildAttrs::getPauthABITagsID(StringRef PauthABITag) { +PauthABITags AArch64BuildAttributes::getPauthABITagsID(StringRef PauthABITag) { return StringSwitch(PauthABITag) .Case("Tag_PAuth_Platform", TAG_PAUTH_PLATFORM) .Case("Tag_PAuth_Schema", TAG_PAUTH_SCHEMA) @@ -95,7 +95,7 @@ PauthABITags AArch64BuildAttrs::getPauthABITagsID(StringRef PauthABITag) { } StringRef -AArch64BuildAttrs::getFeatureAndBitsTagsStr(unsigned FeatureAndBitsTag) { +AArch64BuildAttributes::getFeatureAndBitsTagsStr(unsigned FeatureAndBitsTag) { switch (FeatureAndBitsTag) { case TAG_FEATURE_BTI: return "Tag_Feature_BTI"; @@ -110,7 +110,7 @@ AArch64BuildAttrs::getFeatureAndBitsTagsStr(unsigned FeatureAndBitsTag) { } FeatureAndBitsTags -AArch64BuildAttrs::getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag) { +AArch64BuildAttributes::getFeatureAndBitsTagsID(StringRef FeatureAndBitsTag) { return StringSwitch(FeatureAndBitsTag) .Case("Tag_Feature_BTI", TAG_FEATURE_BTI) .Case("Tag_Feature_PAC", TAG_FEATURE_PAC) diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index a6d8a2581886..49a26a618de8 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -144,6 +144,7 @@ add_llvm_component_library(LLVMSupport APInt.cpp APSInt.cpp ARMBuildAttributes.cpp + AArch64AttributeParser.cpp AArch64BuildAttributes.cpp ARMAttributeParser.cpp ARMWinEH.cpp @@ -182,8 +183,9 @@ add_llvm_component_library(LLVMSupport DAGDeltaAlgorithm.cpp DJB.cpp DynamicAPInt.cpp - ELFAttributeParser.cpp ELFAttributes.cpp + ELFAttrParserCompact.cpp + ELFAttrParserExtended.cpp Error.cpp ErrorHandling.cpp ExponentialBackoff.cpp diff --git a/llvm/lib/Support/CSKYAttributeParser.cpp b/llvm/lib/Support/CSKYAttributeParser.cpp index 40ee617b981b..1e46bf8127df 100644 --- a/llvm/lib/Support/CSKYAttributeParser.cpp +++ b/llvm/lib/Support/CSKYAttributeParser.cpp @@ -16,19 +16,19 @@ const CSKYAttributeParser::DisplayHandler CSKYAttributeParser::displayRoutines[] = { { CSKYAttrs::CSKY_ARCH_NAME, - &ELFAttributeParser::stringAttribute, + &ELFCompactAttrParser::stringAttribute, }, { CSKYAttrs::CSKY_CPU_NAME, - &ELFAttributeParser::stringAttribute, + &ELFCompactAttrParser::stringAttribute, }, { CSKYAttrs::CSKY_ISA_FLAGS, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { CSKYAttrs::CSKY_ISA_EXT_FLAGS, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { CSKYAttrs::CSKY_DSP_VERSION, @@ -60,7 +60,7 @@ const CSKYAttributeParser::DisplayHandler }, { CSKYAttrs::CSKY_FPU_NUMBER_MODULE, - &ELFAttributeParser::stringAttribute, + &ELFCompactAttrParser::stringAttribute, }, { CSKYAttrs::CSKY_FPU_HARDFP, diff --git a/llvm/lib/Support/ELFAttributeParser.cpp b/llvm/lib/Support/ELFAttrParserCompact.cpp similarity index 87% rename from llvm/lib/Support/ELFAttributeParser.cpp rename to llvm/lib/Support/ELFAttrParserCompact.cpp index 26c3d54e17ad..14c5533678a7 100644 --- a/llvm/lib/Support/ELFAttributeParser.cpp +++ b/llvm/lib/Support/ELFAttrParserCompact.cpp @@ -1,12 +1,15 @@ -//===--- ELFAttributeParser.cpp - ELF Attribute Parser --------------------===// +//===--- ELFCompactAttrParser.cpp - ELF Compact Attribute Parser ------ ===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -//===----------------------------------------------------------------------===// +// ELF Compact Attribute Parser parse ELF build atrributes that are held +// in a single Build Attributes Subsection. +// +//===--------------------------------------------------------------------===// -#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/ELFAttrParserCompact.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Errc.h" #include "llvm/Support/ScopedPrinter.h" @@ -20,8 +23,8 @@ static constexpr EnumEntry tagNames[] = { {"Tag_Symbol", ELFAttrs::Symbol}, }; -Error ELFAttributeParser::parseStringAttribute(const char *name, unsigned tag, - ArrayRef strings) { +Error ELFCompactAttrParser::parseStringAttribute( + const char *name, unsigned tag, ArrayRef strings) { uint64_t value = de.getULEB128(cursor); if (value >= strings.size()) { printAttribute(tag, value, ""); @@ -33,7 +36,7 @@ Error ELFAttributeParser::parseStringAttribute(const char *name, unsigned tag, return Error::success(); } -Error ELFAttributeParser::integerAttribute(unsigned tag) { +Error ELFCompactAttrParser::integerAttribute(unsigned tag) { StringRef tagName = ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false); uint64_t value = de.getULEB128(cursor); @@ -49,7 +52,7 @@ Error ELFAttributeParser::integerAttribute(unsigned tag) { return Error::success(); } -Error ELFAttributeParser::stringAttribute(unsigned tag) { +Error ELFCompactAttrParser::stringAttribute(unsigned tag) { StringRef tagName = ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false); StringRef desc = de.getCStrRef(cursor); @@ -65,8 +68,8 @@ Error ELFAttributeParser::stringAttribute(unsigned tag) { return Error::success(); } -void ELFAttributeParser::printAttribute(unsigned tag, unsigned value, - StringRef valueDesc) { +void ELFCompactAttrParser::printAttribute(unsigned tag, unsigned value, + StringRef valueDesc) { attributes.insert(std::make_pair(tag, value)); if (sw) { @@ -82,7 +85,7 @@ void ELFAttributeParser::printAttribute(unsigned tag, unsigned value, } } -void ELFAttributeParser::parseIndexList(SmallVectorImpl &indexList) { +void ELFCompactAttrParser::parseIndexList(SmallVectorImpl &indexList) { for (;;) { uint64_t value = de.getULEB128(cursor); if (!cursor || !value) @@ -91,7 +94,7 @@ void ELFAttributeParser::parseIndexList(SmallVectorImpl &indexList) { } } -Error ELFAttributeParser::parseAttributeList(uint32_t length) { +Error ELFCompactAttrParser::parseAttributeList(uint32_t length) { uint64_t pos; uint64_t end = cursor.tell() + length; while ((pos = cursor.tell()) < end) { @@ -119,7 +122,7 @@ Error ELFAttributeParser::parseAttributeList(uint32_t length) { return Error::success(); } -Error ELFAttributeParser::parseSubsection(uint32_t length) { +Error ELFCompactAttrParser::parseSubsection(uint32_t length) { uint64_t end = cursor.tell() - sizeof(length) + length; StringRef vendorName = de.getCStrRef(cursor); if (sw) { @@ -188,8 +191,8 @@ Error ELFAttributeParser::parseSubsection(uint32_t length) { return Error::success(); } -Error ELFAttributeParser::parse(ArrayRef section, - llvm::endianness endian) { +Error ELFCompactAttrParser::parse(ArrayRef section, + llvm::endianness endian) { unsigned sectionNumber = 0; de = DataExtractor(section, endian == llvm::endianness::little, 0); diff --git a/llvm/lib/Support/ELFAttrParserExtended.cpp b/llvm/lib/Support/ELFAttrParserExtended.cpp new file mode 100644 index 000000000000..44f86a38ef8c --- /dev/null +++ b/llvm/lib/Support/ELFAttrParserExtended.cpp @@ -0,0 +1,187 @@ +//===-ELFAttrParserExtended.cpp-ELF Extended Attribute Information Printer-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM +// Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===------------------------------------------------------------------===// + +#include "llvm/Support/ELFAttrParserExtended.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/AArch64BuildAttributes.h" +#include "llvm/Support/ELFAttributes.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace llvm; +using namespace ELFAttrs; + +std::optional +ELFExtendedAttrParser::getAttributeValue(unsigned Tag) const { + assert( + 0 && + "use getAttributeValue overloaded version accepting Stringref, unsigned"); + return std::nullopt; +} + +std::optional +ELFExtendedAttrParser::getAttributeValue(StringRef BuildAttrSubsectionName, + unsigned Tag) const { + for (auto SubSection : SubSectionVec) { + if (BuildAttrSubsectionName == SubSection.Name) + for (auto BAItem : SubSection.Content) { + if (Tag == BAItem.Tag) + return std::optional(BAItem.IntValue); + } + } + return std::nullopt; +} + +std::optional +ELFExtendedAttrParser::getAttributeString(unsigned Tag) const { + assert( + 0 && + "use getAttributeValue overloaded version accepting Stringref, unsigned"); + return std::nullopt; +} + +std::optional +ELFExtendedAttrParser::getAttributeString(StringRef BuildAttrSubsectionName, + unsigned Tag) const { + for (auto SubSection : SubSectionVec) { + if (BuildAttrSubsectionName == SubSection.Name) + for (auto BAItem : SubSection.Content) { + if (Tag == BAItem.Tag) + return std::optional(BAItem.StringValue); + } + } + return std::nullopt; +} + +StringRef +ELFExtendedAttrParser::getTagName(const StringRef &BuildAttrSubsectionName, + const unsigned Tag) { + for (const auto &Entry : TagsNamesMap) { + if (BuildAttrSubsectionName == Entry.SubsectionName) + if (Tag == Entry.Tag) + return Entry.TagName; + } + return ""; +} + +Error ELFExtendedAttrParser::parse(ArrayRef Section, + llvm::endianness Endian) { + + unsigned SectionNumber = 0; + De = DataExtractor(Section, Endian == llvm::endianness::little, 0); + + // Early returns have specific errors. Consume the Error in Cursor. + struct ClearCursorError { + DataExtractor::Cursor &Cursor; + ~ClearCursorError() { consumeError(Cursor.takeError()); } + } Clear{Cursor}; + + /* + ELF Extended Build Attributes Layout: + --> Currently, there is only one version: 'A' (0x41) + [ ] + --> subsection-length: Offset from the start of this subsection to the + start of the next one. + --> vendor-name: Null-terminated byte string. + --> vendor-data expands to: + [ * ] + --> optional: 0 = required, 1 = optional. + --> parameter type: 0 = ULEB128, 1 = NTBS. + --> attribute: * pair. Tag is ULEB128, value is of + . + */ + + // Get format-version + uint8_t FormatVersion = De.getU8(Cursor); + if (ELFAttrs::Format_Version != FormatVersion) + return createStringError(errc::invalid_argument, + "unrecognized format-version: 0x" + + utohexstr(FormatVersion)); + + while (!De.eof(Cursor)) { + uint32_t ExtBASubsectionLength = De.getU32(Cursor); + // Minimal valid Extended Build Attributes subsection header size is at + // least 8: length(4) name(at least a single char + null) optionality(1) and + // type(1) + if (ExtBASubsectionLength < 8) + return createStringError( + errc::invalid_argument, + "invalid Extended Build Attributes subsection size at offset: " + + utohexstr(Cursor.tell() - 4)); + + StringRef VendorName = De.getCStrRef(Cursor); + uint8_t IsOptional = De.getU8(Cursor); + StringRef IsOptionalStr = IsOptional ? "optional" : "required"; + uint8_t Type = De.getU8(Cursor); + StringRef TypeStr = Type ? "ntbs" : "uleb128"; + + BuildAttributeSubSection BASubSection; + BASubSection.Name = VendorName; + BASubSection.IsOptional = IsOptional; + BASubSection.ParameterType = Type; + + if (Sw) { + Sw->startLine() << "Section " << ++SectionNumber << " {\n"; + Sw->indent(); + Sw->printNumber("SectionLength", ExtBASubsectionLength); + Sw->startLine() << "VendorName" << ": " << VendorName + << " Optionality: " << IsOptionalStr + << " Type: " << TypeStr << "\n"; + Sw->startLine() << "Attributes {\n"; + Sw->indent(); + } + + // Offset in Section + uint64_t OffsetInSection = Cursor.tell(); + // Size: 4 bytes, Vendor Name: VendorName.size() + 1 (null termination), + // optionality: 1, size: 1 + uint32_t BytesAllButAttributes = 4 + (VendorName.size() + 1) + 1 + 1; + while (Cursor.tell() < + (OffsetInSection + ExtBASubsectionLength - BytesAllButAttributes)) { + + uint64_t Tag = De.getULEB128(Cursor); + + StringRef TagName = getTagName(VendorName, Tag); + + uint64_t ValueInt = 0; + std::string ValueStr = ""; + if (Type) { // type==1 --> ntbs + ValueStr = De.getCStrRef(Cursor); + if (Sw) + Sw->printString("" != TagName ? TagName : utostr(Tag), ValueStr); + } else { // type==0 --> uleb128 + ValueInt = De.getULEB128(Cursor); + if (Sw) + Sw->printNumber("" != TagName ? TagName : utostr(Tag), ValueInt); + } + + // populate data structure + BuildAttributeItem BAItem(static_cast(Type), + Tag, ValueInt, ValueStr); + BASubSection.Content.push_back(BAItem); + } + if (Sw) { + // Close 'Attributes' + Sw->unindent(); + Sw->startLine() << "}\n"; + // Close 'Section' + Sw->unindent(); + Sw->startLine() << "}\n"; + } + + // populate data structure + SubSectionVec.push_back(BASubSection); + } + + return Cursor.takeError(); +} diff --git a/llvm/lib/Support/HexagonAttributeParser.cpp b/llvm/lib/Support/HexagonAttributeParser.cpp index 2143162d11c7..3baa97657493 100644 --- a/llvm/lib/Support/HexagonAttributeParser.cpp +++ b/llvm/lib/Support/HexagonAttributeParser.cpp @@ -14,31 +14,31 @@ const HexagonAttributeParser::DisplayHandler HexagonAttributeParser::DisplayRoutines[] = { { HexagonAttrs::ARCH, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { HexagonAttrs::HVXARCH, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { HexagonAttrs::HVXIEEEFP, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { HexagonAttrs::HVXQFLOAT, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { HexagonAttrs::ZREG, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { HexagonAttrs::AUDIO, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { HexagonAttrs::CABAC, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }}; Error HexagonAttributeParser::handler(uint64_t Tag, bool &Handled) { diff --git a/llvm/lib/Support/RISCVAttributeParser.cpp b/llvm/lib/Support/RISCVAttributeParser.cpp index 20392e4bae19..41c48859566e 100644 --- a/llvm/lib/Support/RISCVAttributeParser.cpp +++ b/llvm/lib/Support/RISCVAttributeParser.cpp @@ -15,19 +15,19 @@ const RISCVAttributeParser::DisplayHandler RISCVAttributeParser::displayRoutines[] = { { RISCVAttrs::ARCH, - &ELFAttributeParser::stringAttribute, + &ELFCompactAttrParser::stringAttribute, }, { RISCVAttrs::PRIV_SPEC, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { RISCVAttrs::PRIV_SPEC_MINOR, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { RISCVAttrs::PRIV_SPEC_REVISION, - &ELFAttributeParser::integerAttribute, + &ELFCompactAttrParser::integerAttribute, }, { RISCVAttrs::STACK_ALIGN, diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp index 49d48357b7fc..47c0a1fab08f 100644 --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -361,7 +361,7 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) { if (const auto *BTE = mdconst::extract_or_null( M.getModuleFlag("branch-target-enforcement"))) { if (!BTE->isZero()) { - BAFlags |= AArch64BuildAttrs::FeatureAndBitsFlag::Feature_BTI_Flag; + BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_BTI_Flag; GNUFlags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI; } } @@ -369,7 +369,7 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) { if (const auto *GCS = mdconst::extract_or_null( M.getModuleFlag("guarded-control-stack"))) { if (!GCS->isZero()) { - BAFlags |= AArch64BuildAttrs::FeatureAndBitsFlag::Feature_GCS_Flag; + BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_GCS_Flag; GNUFlags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_GCS; } } @@ -377,7 +377,7 @@ void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) { if (const auto *Sign = mdconst::extract_or_null( M.getModuleFlag("sign-return-address"))) { if (!Sign->isZero()) { - BAFlags |= AArch64BuildAttrs::FeatureAndBitsFlag::Feature_PAC_Flag; + BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_PAC_Flag; GNUFlags |= ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC; } } @@ -480,35 +480,42 @@ void AArch64AsmPrinter::emitAttributes(unsigned Flags, if (PAuthABIPlatform || PAuthABIVersion) { TS->emitAtributesSubsection( - AArch64BuildAttrs::getVendorName(AArch64BuildAttrs::AEABI_PAUTHABI), - AArch64BuildAttrs::SubsectionOptional::REQUIRED, - AArch64BuildAttrs::SubsectionType::ULEB128); - TS->emitAttribute( - AArch64BuildAttrs::getVendorName(AArch64BuildAttrs::AEABI_PAUTHABI), - AArch64BuildAttrs::TAG_PAUTH_PLATFORM, PAuthABIPlatform, ""); - TS->emitAttribute( - AArch64BuildAttrs::getVendorName(AArch64BuildAttrs::AEABI_PAUTHABI), - AArch64BuildAttrs::TAG_PAUTH_SCHEMA, PAuthABIVersion, ""); + AArch64BuildAttributes::getVendorName( + AArch64BuildAttributes::AEABI_PAUTHABI), + AArch64BuildAttributes::SubsectionOptional::REQUIRED, + AArch64BuildAttributes::SubsectionType::ULEB128); + TS->emitAttribute(AArch64BuildAttributes::getVendorName( + AArch64BuildAttributes::AEABI_PAUTHABI), + AArch64BuildAttributes::TAG_PAUTH_PLATFORM, + PAuthABIPlatform, ""); + TS->emitAttribute(AArch64BuildAttributes::getVendorName( + AArch64BuildAttributes::AEABI_PAUTHABI), + AArch64BuildAttributes::TAG_PAUTH_SCHEMA, PAuthABIVersion, + ""); } - unsigned BTIValue = (Flags & AArch64BuildAttrs::Feature_BTI_Flag) ? 1 : 0; - unsigned PACValue = (Flags & AArch64BuildAttrs::Feature_PAC_Flag) ? 1 : 0; - unsigned GCSValue = (Flags & AArch64BuildAttrs::Feature_GCS_Flag) ? 1 : 0; + unsigned BTIValue = + (Flags & AArch64BuildAttributes::Feature_BTI_Flag) ? 1 : 0; + unsigned PACValue = + (Flags & AArch64BuildAttributes::Feature_PAC_Flag) ? 1 : 0; + unsigned GCSValue = + (Flags & AArch64BuildAttributes::Feature_GCS_Flag) ? 1 : 0; if (BTIValue || PACValue || GCSValue) { - TS->emitAtributesSubsection(AArch64BuildAttrs::getVendorName( - AArch64BuildAttrs::AEABI_FEATURE_AND_BITS), - AArch64BuildAttrs::SubsectionOptional::OPTIONAL, - AArch64BuildAttrs::SubsectionType::ULEB128); - TS->emitAttribute(AArch64BuildAttrs::getVendorName( - AArch64BuildAttrs::AEABI_FEATURE_AND_BITS), - AArch64BuildAttrs::TAG_FEATURE_BTI, BTIValue, ""); - TS->emitAttribute(AArch64BuildAttrs::getVendorName( - AArch64BuildAttrs::AEABI_FEATURE_AND_BITS), - AArch64BuildAttrs::TAG_FEATURE_PAC, PACValue, ""); - TS->emitAttribute(AArch64BuildAttrs::getVendorName( - AArch64BuildAttrs::AEABI_FEATURE_AND_BITS), - AArch64BuildAttrs::TAG_FEATURE_GCS, GCSValue, ""); + TS->emitAtributesSubsection( + AArch64BuildAttributes::getVendorName( + AArch64BuildAttributes::AEABI_FEATURE_AND_BITS), + AArch64BuildAttributes::SubsectionOptional::OPTIONAL, + AArch64BuildAttributes::SubsectionType::ULEB128); + TS->emitAttribute(AArch64BuildAttributes::getVendorName( + AArch64BuildAttributes::AEABI_FEATURE_AND_BITS), + AArch64BuildAttributes::TAG_FEATURE_BTI, BTIValue, ""); + TS->emitAttribute(AArch64BuildAttributes::getVendorName( + AArch64BuildAttributes::AEABI_FEATURE_AND_BITS), + AArch64BuildAttributes::TAG_FEATURE_PAC, PACValue, ""); + TS->emitAttribute(AArch64BuildAttributes::getVendorName( + AArch64BuildAttributes::AEABI_FEATURE_AND_BITS), + AArch64BuildAttributes::TAG_FEATURE_GCS, GCSValue, ""); } } diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 6a973b0160e2..1e7296fa2348 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -7847,10 +7847,10 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) { // Consume the name (subsection name) StringRef SubsectionName; - AArch64BuildAttrs::VendorID SubsectionNameID; + AArch64BuildAttributes::VendorID SubsectionNameID; if (Parser.getTok().is(AsmToken::Identifier)) { SubsectionName = Parser.getTok().getIdentifier(); - SubsectionNameID = AArch64BuildAttrs::getVendorID(SubsectionName); + SubsectionNameID = AArch64BuildAttributes::getVendorID(SubsectionName); } else { Error(Parser.getTok().getLoc(), "subsection name not found"); return true; @@ -7867,14 +7867,14 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) { getTargetStreamer().getAtributesSubsectionByName(SubsectionName); // Consume the first parameter (optionality parameter) - AArch64BuildAttrs::SubsectionOptional IsOptional; + AArch64BuildAttributes::SubsectionOptional IsOptional; // options: optional/required if (Parser.getTok().is(AsmToken::Identifier)) { StringRef Optionality = Parser.getTok().getIdentifier(); - IsOptional = AArch64BuildAttrs::getOptionalID(Optionality); - if (AArch64BuildAttrs::OPTIONAL_NOT_FOUND == IsOptional) { + IsOptional = AArch64BuildAttributes::getOptionalID(Optionality); + if (AArch64BuildAttributes::OPTIONAL_NOT_FOUND == IsOptional) { Error(Parser.getTok().getLoc(), - AArch64BuildAttrs::getSubsectionOptionalUnknownError()); + AArch64BuildAttributes::getSubsectionOptionalUnknownError()); return true; } if (SubsectionExists) { @@ -7882,10 +7882,10 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) { Error(Parser.getTok().getLoc(), "optionality mismatch! subsection '" + SubsectionName + "' already exists with optionality defined as '" + - AArch64BuildAttrs::getOptionalStr( + AArch64BuildAttributes::getOptionalStr( SubsectionExists->IsOptional) + "' and not '" + - AArch64BuildAttrs::getOptionalStr(IsOptional) + "'"); + AArch64BuildAttributes::getOptionalStr(IsOptional) + "'"); return true; } } @@ -7895,15 +7895,15 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) { return true; } // Check for possible IsOptional unaccepted values for known subsections - if (AArch64BuildAttrs::AEABI_FEATURE_AND_BITS == SubsectionNameID) { - if (AArch64BuildAttrs::REQUIRED == IsOptional) { + if (AArch64BuildAttributes::AEABI_FEATURE_AND_BITS == SubsectionNameID) { + if (AArch64BuildAttributes::REQUIRED == IsOptional) { Error(Parser.getTok().getLoc(), "aeabi_feature_and_bits must be marked as optional"); return true; } } - if (AArch64BuildAttrs::AEABI_PAUTHABI == SubsectionNameID) { - if (AArch64BuildAttrs::OPTIONAL == IsOptional) { + if (AArch64BuildAttributes::AEABI_PAUTHABI == SubsectionNameID) { + if (AArch64BuildAttributes::OPTIONAL == IsOptional) { Error(Parser.getTok().getLoc(), "aeabi_pauthabi must be marked as required"); return true; @@ -7916,23 +7916,24 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) { } // Consume the second parameter (type parameter) - AArch64BuildAttrs::SubsectionType Type; + AArch64BuildAttributes::SubsectionType Type; if (Parser.getTok().is(AsmToken::Identifier)) { StringRef Name = Parser.getTok().getIdentifier(); - Type = AArch64BuildAttrs::getTypeID(Name); - if (AArch64BuildAttrs::TYPE_NOT_FOUND == Type) { + Type = AArch64BuildAttributes::getTypeID(Name); + if (AArch64BuildAttributes::TYPE_NOT_FOUND == Type) { Error(Parser.getTok().getLoc(), - AArch64BuildAttrs::getSubsectionTypeUnknownError()); + AArch64BuildAttributes::getSubsectionTypeUnknownError()); return true; } if (SubsectionExists) { if (Type != SubsectionExists->ParameterType) { - Error( - Parser.getTok().getLoc(), - "type mismatch! subsection '" + SubsectionName + - "' already exists with type defined as '" + - AArch64BuildAttrs::getTypeStr(SubsectionExists->ParameterType) + - "' and not '" + AArch64BuildAttrs::getTypeStr(Type) + "'"); + Error(Parser.getTok().getLoc(), + "type mismatch! subsection '" + SubsectionName + + "' already exists with type defined as '" + + AArch64BuildAttributes::getTypeStr( + SubsectionExists->ParameterType) + + "' and not '" + AArch64BuildAttributes::getTypeStr(Type) + + "'"); return true; } } @@ -7942,9 +7943,9 @@ bool AArch64AsmParser::parseDirectiveAeabiSubSectionHeader(SMLoc L) { return true; } // Check for possible unaccepted 'type' values for known subsections - if (AArch64BuildAttrs::AEABI_FEATURE_AND_BITS == SubsectionNameID || - AArch64BuildAttrs::AEABI_PAUTHABI == SubsectionNameID) { - if (AArch64BuildAttrs::NTBS == Type) { + if (AArch64BuildAttributes::AEABI_FEATURE_AND_BITS == SubsectionNameID || + AArch64BuildAttributes::AEABI_PAUTHABI == SubsectionNameID) { + if (AArch64BuildAttributes::NTBS == Type) { Error(Parser.getTok().getLoc(), SubsectionName + " must be marked as ULEB128"); return true; @@ -7980,13 +7981,14 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) { StringRef ActiveSubsectionName = ActiveSubsection->VendorName; unsigned ActiveSubsectionType = ActiveSubsection->ParameterType; - unsigned ActiveSubsectionID = AArch64BuildAttrs::VENDOR_UNKNOWN; - if (AArch64BuildAttrs::getVendorName(AArch64BuildAttrs::AEABI_PAUTHABI) == + unsigned ActiveSubsectionID = AArch64BuildAttributes::VENDOR_UNKNOWN; + if (AArch64BuildAttributes::getVendorName( + AArch64BuildAttributes::AEABI_PAUTHABI) == ActiveSubsectionName) + ActiveSubsectionID = AArch64BuildAttributes::AEABI_PAUTHABI; + if (AArch64BuildAttributes::getVendorName( + AArch64BuildAttributes::AEABI_FEATURE_AND_BITS) == ActiveSubsectionName) - ActiveSubsectionID = AArch64BuildAttrs::AEABI_PAUTHABI; - if (AArch64BuildAttrs::getVendorName( - AArch64BuildAttrs::AEABI_FEATURE_AND_BITS) == ActiveSubsectionName) - ActiveSubsectionID = AArch64BuildAttrs::AEABI_FEATURE_AND_BITS; + ActiveSubsectionID = AArch64BuildAttributes::AEABI_FEATURE_AND_BITS; StringRef TagStr = ""; unsigned Tag; @@ -7995,7 +7997,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) { } else if (Parser.getTok().is(AsmToken::Identifier)) { TagStr = Parser.getTok().getIdentifier(); switch (ActiveSubsectionID) { - case AArch64BuildAttrs::VENDOR_UNKNOWN: + case AArch64BuildAttributes::VENDOR_UNKNOWN: // Tag was provided as an unrecognized string instead of an unsigned // integer Error(Parser.getTok().getLoc(), "unrecognized Tag: '" + TagStr + @@ -8003,18 +8005,18 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) { "tags have to be an unsigned int."); return true; break; - case AArch64BuildAttrs::AEABI_PAUTHABI: - Tag = AArch64BuildAttrs::getPauthABITagsID(TagStr); - if (AArch64BuildAttrs::PAUTHABI_TAG_NOT_FOUND == Tag) { + case AArch64BuildAttributes::AEABI_PAUTHABI: + Tag = AArch64BuildAttributes::getPauthABITagsID(TagStr); + if (AArch64BuildAttributes::PAUTHABI_TAG_NOT_FOUND == Tag) { Error(Parser.getTok().getLoc(), "unknown AArch64 build attribute '" + TagStr + "' for subsection '" + ActiveSubsectionName + "'"); return true; } break; - case AArch64BuildAttrs::AEABI_FEATURE_AND_BITS: - Tag = AArch64BuildAttrs::getFeatureAndBitsTagsID(TagStr); - if (AArch64BuildAttrs::FEATURE_AND_BITS_TAG_NOT_FOUND == Tag) { + case AArch64BuildAttributes::AEABI_FEATURE_AND_BITS: + Tag = AArch64BuildAttributes::getFeatureAndBitsTagsID(TagStr); + if (AArch64BuildAttributes::FEATURE_AND_BITS_TAG_NOT_FOUND == Tag) { Error(Parser.getTok().getLoc(), "unknown AArch64 build attribute '" + TagStr + "' for subsection '" + ActiveSubsectionName + "'"); @@ -8038,7 +8040,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) { unsigned ValueInt = unsigned(-1); std::string ValueStr = ""; if (Parser.getTok().is(AsmToken::Integer)) { - if (AArch64BuildAttrs::NTBS == ActiveSubsectionType) { + if (AArch64BuildAttributes::NTBS == ActiveSubsectionType) { Error( Parser.getTok().getLoc(), "active subsection type is NTBS (string), found ULEB128 (unsigned)"); @@ -8046,7 +8048,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) { } ValueInt = getTok().getIntVal(); } else if (Parser.getTok().is(AsmToken::Identifier)) { - if (AArch64BuildAttrs::ULEB128 == ActiveSubsectionType) { + if (AArch64BuildAttributes::ULEB128 == ActiveSubsectionType) { Error( Parser.getTok().getLoc(), "active subsection type is ULEB128 (unsigned), found NTBS (string)"); @@ -8054,7 +8056,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) { } ValueStr = Parser.getTok().getIdentifier(); } else if (Parser.getTok().is(AsmToken::String)) { - if (AArch64BuildAttrs::ULEB128 == ActiveSubsectionType) { + if (AArch64BuildAttributes::ULEB128 == ActiveSubsectionType) { Error( Parser.getTok().getLoc(), "active subsection type is ULEB128 (unsigned), found NTBS (string)"); @@ -8067,7 +8069,7 @@ bool AArch64AsmParser::parseDirectiveAeabiAArch64Attr(SMLoc L) { } // Check for possible unaccepted values for known tags // (AEABI_FEATURE_AND_BITS) - if (ActiveSubsectionID == AArch64BuildAttrs::AEABI_FEATURE_AND_BITS) { + if (ActiveSubsectionID == AArch64BuildAttributes::AEABI_FEATURE_AND_BITS) { if (0 != ValueInt && 1 != ValueInt) { Error(Parser.getTok().getLoc(), "unknown AArch64 build attributes Value for Tag '" + TagStr + diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp index a0953e13aa37..98bd102d8f4c 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp @@ -161,10 +161,10 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { return; } - unsigned VendorID = AArch64BuildAttrs::getVendorID(VendorName); + unsigned VendorID = AArch64BuildAttributes::getVendorID(VendorName); switch (VendorID) { - case AArch64BuildAttrs::VENDOR_UNKNOWN: + case AArch64BuildAttributes::VENDOR_UNKNOWN: if (unsigned(-1) != Value) { OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value; AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, ""); @@ -176,7 +176,7 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { } break; // Note: AEABI_FEATURE_AND_BITS takes only unsigned values - case AArch64BuildAttrs::AEABI_FEATURE_AND_BITS: + case AArch64BuildAttributes::AEABI_FEATURE_AND_BITS: switch (Tag) { default: // allow emitting any attribute by number OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value; @@ -184,17 +184,17 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { // (important for llvm-mc asm parsing) AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, ""); break; - case AArch64BuildAttrs::TAG_FEATURE_BTI: - case AArch64BuildAttrs::TAG_FEATURE_GCS: - case AArch64BuildAttrs::TAG_FEATURE_PAC: + case AArch64BuildAttributes::TAG_FEATURE_BTI: + case AArch64BuildAttributes::TAG_FEATURE_GCS: + case AArch64BuildAttributes::TAG_FEATURE_PAC: OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value << "\t// " - << AArch64BuildAttrs::getFeatureAndBitsTagsStr(Tag); + << AArch64BuildAttributes::getFeatureAndBitsTagsStr(Tag); AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, ""); break; } break; // Note: AEABI_PAUTHABI takes only unsigned values - case AArch64BuildAttrs::AEABI_PAUTHABI: + case AArch64BuildAttributes::AEABI_PAUTHABI: switch (Tag) { default: // allow emitting any attribute by number OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value; @@ -202,10 +202,10 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { // (important for llvm-mc asm parsing) AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, ""); break; - case AArch64BuildAttrs::TAG_PAUTH_PLATFORM: - case AArch64BuildAttrs::TAG_PAUTH_SCHEMA: + case AArch64BuildAttributes::TAG_PAUTH_PLATFORM: + case AArch64BuildAttributes::TAG_PAUTH_SCHEMA: OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value << "\t// " - << AArch64BuildAttrs::getPauthABITagsStr(Tag); + << AArch64BuildAttributes::getPauthABITagsStr(Tag); AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, ""); break; } @@ -215,42 +215,43 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer { } void emitAtributesSubsection( - StringRef SubsectionName, AArch64BuildAttrs::SubsectionOptional Optional, - AArch64BuildAttrs::SubsectionType ParameterType) override { + StringRef SubsectionName, + AArch64BuildAttributes::SubsectionOptional Optional, + AArch64BuildAttributes::SubsectionType 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) - unsigned SubsectionID = AArch64BuildAttrs::getVendorID(SubsectionName); + unsigned SubsectionID = AArch64BuildAttributes::getVendorID(SubsectionName); assert((0 == Optional || 1 == Optional) && - AArch64BuildAttrs::getSubsectionOptionalUnknownError().data()); + AArch64BuildAttributes::getSubsectionOptionalUnknownError().data()); assert((0 == ParameterType || 1 == ParameterType) && - AArch64BuildAttrs::getSubsectionTypeUnknownError().data()); + AArch64BuildAttributes::getSubsectionTypeUnknownError().data()); std::string SubsectionTag = ".aeabi_subsection"; StringRef OptionalStr = getOptionalStr(Optional); StringRef ParameterStr = getTypeStr(ParameterType); switch (SubsectionID) { - case AArch64BuildAttrs::VENDOR_UNKNOWN: { + case AArch64BuildAttributes::VENDOR_UNKNOWN: { // Private subsection break; } - case AArch64BuildAttrs::AEABI_PAUTHABI: { - assert(AArch64BuildAttrs::REQUIRED == Optional && + case AArch64BuildAttributes::AEABI_PAUTHABI: { + assert(AArch64BuildAttributes::REQUIRED == Optional && "subsection .aeabi-pauthabi should be marked as " "required and not as optional"); - assert(AArch64BuildAttrs::ULEB128 == ParameterType && + assert(AArch64BuildAttributes::ULEB128 == ParameterType && "subsection .aeabi-pauthabi should be " "marked as uleb128 and not as ntbs"); break; } - case AArch64BuildAttrs::AEABI_FEATURE_AND_BITS: { - assert(AArch64BuildAttrs::OPTIONAL == Optional && + case AArch64BuildAttributes::AEABI_FEATURE_AND_BITS: { + assert(AArch64BuildAttributes::OPTIONAL == Optional && "subsection .aeabi_feature_and_bits should be " "marked as optional and not as required"); - assert(AArch64BuildAttrs::ULEB128 == ParameterType && + assert(AArch64BuildAttributes::ULEB128 == ParameterType && "subsection .aeabi_feature_and_bits should " "be marked as uleb128 and not as ntbs"); break; @@ -416,8 +417,8 @@ AArch64ELFStreamer &AArch64TargetELFStreamer::getStreamer() { } void AArch64TargetELFStreamer::emitAtributesSubsection( - StringRef VendorName, AArch64BuildAttrs::SubsectionOptional IsOptional, - AArch64BuildAttrs::SubsectionType ParameterType) { + StringRef VendorName, AArch64BuildAttributes::SubsectionOptional IsOptional, + AArch64BuildAttributes::SubsectionType ParameterType) { AArch64TargetStreamer::emitAtributesSubsection(VendorName, IsOptional, ParameterType); } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp index 028d9196613c..04defbc97746 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp @@ -154,8 +154,8 @@ MCTargetStreamer *llvm::createAArch64NullTargetStreamer(MCStreamer &S) { } void AArch64TargetStreamer::emitAtributesSubsection( - StringRef VendorName, AArch64BuildAttrs::SubsectionOptional IsOptional, - AArch64BuildAttrs::SubsectionType ParameterType) { + StringRef VendorName, AArch64BuildAttributes::SubsectionOptional IsOptional, + AArch64BuildAttributes::SubsectionType ParameterType) { // If exists, return. for (MCELFStreamer::AttributeSubSection &SubSection : AttributeSubSections) { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h index 9cbb104c0eb9..43e099f91999 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h @@ -97,8 +97,8 @@ public: /// Build attributes implementation virtual void emitAtributesSubsection(StringRef VendorName, - AArch64BuildAttrs::SubsectionOptional IsOptional, - AArch64BuildAttrs::SubsectionType ParameterType); + AArch64BuildAttributes::SubsectionOptional IsOptional, + AArch64BuildAttributes::SubsectionType ParameterType); virtual void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value, std::string String); void activateAtributesSubsection(StringRef VendorName); @@ -124,8 +124,9 @@ private: /// Build attributes implementation void emitAtributesSubsection( - StringRef VendorName, AArch64BuildAttrs::SubsectionOptional IsOptional, - AArch64BuildAttrs::SubsectionType ParameterType) override; + StringRef VendorName, + AArch64BuildAttributes::SubsectionOptional IsOptional, + AArch64BuildAttributes::SubsectionType ParameterType) override; void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value, std::string String) override; void emitInst(uint32_t Inst) override; diff --git a/llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-comprehensive.s b/llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-comprehensive.s new file mode 100644 index 000000000000..0722d006c4f4 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-comprehensive.s @@ -0,0 +1,81 @@ +# RUN: llvm-mc -triple=aarch64-linux -filetype=obj < %s | llvm-readelf --arch-specific - | FileCheck %s --check-prefix=ATTR + +# ATTR: BuildAttributes { +# ATTR-NEXT: FormatVersion: 0x41 +# ATTR-NEXT: Section 1 { +# ATTR-NEXT: SectionLength: 29 +# ATTR-NEXT: VendorName: private_subsection_1 Optionality: optional Type: uleb128 +# ATTR-NEXT: Attributes { +# ATTR-NEXT: 1: 1 +# ATTR-NEXT: } +# ATTR-NEXT: } +# ATTR-NEXT: Section 2 { +# ATTR-NEXT: SectionLength: 37 +# ATTR-NEXT: VendorName: aeabi_feature_and_bits Optionality: optional Type: uleb128 +# ATTR-NEXT: Attributes { +# ATTR-NEXT: Tag_Feature_BTI: 1 +# ATTR-NEXT: Tag_Feature_PAC: 1 +# ATTR-NEXT: Tag_Feature_GCS: 1 +# ATTR-NEXT: 3: 1 +# ATTR-NEXT: } +# ATTR-NEXT: } +# ATTR-NEXT: Section 3 { +# ATTR-NEXT: SectionLength: 32 +# ATTR-NEXT: VendorName: private_subsection_3 Optionality: optional Type: ntbs +# ATTR-NEXT: Attributes { +# ATTR-NEXT: 1: "1" +# ATTR-NEXT: } +# ATTR-NEXT: } +# ATTR-NEXT: Section 4 { +# ATTR-NEXT: SectionLength: 35 +# ATTR-NEXT: VendorName: aeabi_pauthabi Optionality: required Type: uleb128 +# ATTR-NEXT: Attributes { +# ATTR-NEXT: Tag_PAuth_Schema: 1 +# ATTR-NEXT: Tag_PAuth_Platform: 1 +# ATTR-NEXT: 5: 1 +# ATTR-NEXT: 6: 1 +# ATTR-NEXT: 7: 1 +# ATTR-NEXT: 8: 1 +# ATTR-NEXT: 9: 1 +# ATTR-NEXT: } +# ATTR-NEXT: } +# ATTR-NEXT: Section 5 { +# ATTR-NEXT: SectionLength: 32 +# ATTR-NEXT: VendorName: private_subsection_4 Optionality: required Type: ntbs +# ATTR-NEXT: Attributes { +# ATTR-NEXT: 1: "1" +# ATTR-NEXT: } +# ATTR-NEXT: } +# ATTR-NEXT: Section 6 { +# ATTR-NEXT: SectionLength: 31 +# ATTR-NEXT: VendorName: private_subsection_2 Optionality: required Type: uleb128 +# ATTR-NEXT: Attributes { +# ATTR-NEXT: 1: 1 +# ATTR-NEXT: 2: 1 +# ATTR-NEXT: } +# ATTR-NEXT: } +# ATTR-NEXT: } + + +.aeabi_subsection private_subsection_1, optional, uleb128 +.aeabi_attribute 1, 1 +.aeabi_subsection aeabi_feature_and_bits, optional, uleb128 +.aeabi_attribute Tag_Feature_BTI, 1 +.aeabi_attribute 1, 1 +.aeabi_attribute 2, 1 +.aeabi_attribute 3, 1 +.aeabi_subsection private_subsection_3, optional, ntbs +.aeabi_attribute 1, "1" +.aeabi_subsection aeabi_pauthabi, required, uleb128 +.aeabi_attribute Tag_PAuth_Schema, 1 +.aeabi_attribute Tag_PAuth_Platform, 1 +.aeabi_attribute 5, 1 +.aeabi_attribute 6, 1 +.aeabi_attribute 7, 1 +.aeabi_attribute 8, 1 +.aeabi_attribute 9, 1 +.aeabi_subsection private_subsection_4, required, ntbs +.aeabi_attribute 1, "1" +.aeabi_subsection private_subsection_2, required, uleb128 +.aeabi_attribute 1, 1 +.aeabi_attribute 2, 1 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index e7825419ef9e..d01cab211afd 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -39,6 +39,7 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Object/RelocationResolver.h" #include "llvm/Object/StackMapParser.h" +#include "llvm/Support/AArch64AttributeParser.h" #include "llvm/Support/AMDGPUMetadata.h" #include "llvm/Support/ARMAttributeParser.h" #include "llvm/Support/ARMBuildAttributes.h" @@ -2878,6 +2879,12 @@ template void ELFDumper::printArchSpecificInfo() { ELF::SHT_ARM_ATTRIBUTES, std::make_unique(&W), Obj.isLE() ? llvm::endianness::little : llvm::endianness::big); break; + case EM_AARCH64: + printAttributes(ELF::SHT_AARCH64_ATTRIBUTES, + std::make_unique(&W), + Obj.isLE() ? llvm::endianness::little + : llvm::endianness::big); + break; case EM_RISCV: if (Obj.isLE()) printAttributes(ELF::SHT_RISCV_ATTRIBUTES, diff --git a/llvm/unittests/Support/ARMAttributeParser.cpp b/llvm/unittests/Support/ARMAttributeParser.cpp index a0568262b4da..e06f7fab85fa 100644 --- a/llvm/unittests/Support/ARMAttributeParser.cpp +++ b/llvm/unittests/Support/ARMAttributeParser.cpp @@ -37,7 +37,7 @@ bool testBuildAttr(unsigned Tag, unsigned Value, ARMAttributeParser Parser; cantFail(Parser.parse(Bytes, llvm::endianness::little)); - std::optional Attr = Parser.getAttributeValue(ExpectedTag); + std::optional Attr = Parser.getAttributeValue("", ExpectedTag); return Attr && *Attr == ExpectedValue; } diff --git a/llvm/unittests/Support/CSKYAttributeParserTest.cpp b/llvm/unittests/Support/CSKYAttributeParserTest.cpp index 2c5d93b0b756..25b151fe5c1c 100644 --- a/llvm/unittests/Support/CSKYAttributeParserTest.cpp +++ b/llvm/unittests/Support/CSKYAttributeParserTest.cpp @@ -83,7 +83,7 @@ static bool testAttributeInt(unsigned Tag, unsigned Value, unsigned ExpectedTag, CSKYAttributeParser Parser; cantFail(Parser.parse(Bytes, llvm::endianness::little)); - std::optional Attr = Parser.getAttributeValue(ExpectedTag); + std::optional Attr = Parser.getAttributeValue("", ExpectedTag); return Attr && *Attr == ExpectedValue; } @@ -100,7 +100,7 @@ static bool testAttributeString(unsigned Tag, const char *Value, CSKYAttributeParser Parser; cantFail(Parser.parse(Bytes, llvm::endianness::little)); - std::optional Attr = Parser.getAttributeString(ExpectedTag); + std::optional Attr = Parser.getAttributeString("", ExpectedTag); return Attr && *Attr == ExpectedValue; } diff --git a/llvm/unittests/Support/ELFAttributeParserTest.cpp b/llvm/unittests/Support/ELFAttributeParserTest.cpp index 38e7b09cc3c7..31cc594188e3 100644 --- a/llvm/unittests/Support/ELFAttributeParserTest.cpp +++ b/llvm/unittests/Support/ELFAttributeParserTest.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/ELFAttrParserCompact.h" #include "llvm/Support/ELFAttributes.h" #include "gtest/gtest.h" #include @@ -16,7 +16,7 @@ using namespace llvm; static const TagNameMap emptyTagNameMap; // This class is used to test the common part of the ELF attribute section. -class AttributeHeaderParser : public ELFAttributeParser { +class AttributeHeaderParser : public ELFCompactAttrParser { Error handler(uint64_t tag, bool &handled) override { // Treat all attributes as handled. handled = true; @@ -25,8 +25,8 @@ class AttributeHeaderParser : public ELFAttributeParser { public: AttributeHeaderParser(ScopedPrinter *printer) - : ELFAttributeParser(printer, emptyTagNameMap, "test") {} - AttributeHeaderParser() : ELFAttributeParser(emptyTagNameMap, "test") {} + : ELFCompactAttrParser(printer, emptyTagNameMap, "test") {} + AttributeHeaderParser() : ELFCompactAttrParser(emptyTagNameMap, "test") {} }; static void testParseError(ArrayRef bytes, const char *msg) { diff --git a/llvm/unittests/Support/RISCVAttributeParserTest.cpp b/llvm/unittests/Support/RISCVAttributeParserTest.cpp index aa73bb92d6e3..777dc4d0f4d4 100644 --- a/llvm/unittests/Support/RISCVAttributeParserTest.cpp +++ b/llvm/unittests/Support/RISCVAttributeParserTest.cpp @@ -44,7 +44,7 @@ static bool testAttribute(unsigned Tag, unsigned Value, unsigned ExpectedTag, RISCVAttributeParser Parser; cantFail(Parser.parse(Bytes, llvm::endianness::little)); - std::optional Attr = Parser.getAttributeValue(ExpectedTag); + std::optional Attr = Parser.getAttributeValue("", ExpectedTag); return Attr && *Attr == ExpectedValue; }