[lld] [llvm] [readobj][Arm][AArch64] Refactor Build Attributes parsing under ELFAtributeParser and add support for AArch64 Build Attributes (PR #128727)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 26 02:44:31 PST 2025
https://github.com/sivan-shani updated https://github.com/llvm/llvm-project/pull/128727
>From f3a80563c9a66050cf6fd9f49441bb8a8b252bb6 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Thu, 23 Jan 2025 18:00:32 +0000
Subject: [PATCH 1/5] [readobj][Arm][AArch64] Refactor build attribute parsing
under ELFAttributeParser and add support for AArch64 Build Attributes
Refactor readobj to integrate AArch64 build attributes under ELFAttributeParser.
ELFAttributeParser now serves as a base class for:
- ELFCompactAttrParser, handling Arm-style attributes with a single build attribute subsection.
- ELFExtendedAttrParser, handling AArch64-style attributes with multiple build attribute subsections.
This improves code organization and better aligns with the attribute parsing model.
Add support for parsing AArch64 Build Attributes.
---
lld/ELF/Arch/RISCV.cpp | 12 +-
lld/ELF/InputFiles.cpp | 10 +-
llvm/include/llvm/Object/ELFObjectFile.h | 3 +
.../llvm/Support/AArch64AttributeParser.h | 29 +++
.../llvm/Support/AArch64BuildAttributes.h | 4 +-
.../include/llvm/Support/ARMAttributeParser.h | 9 +-
.../llvm/Support/CSKYAttributeParser.h | 8 +-
.../llvm/Support/ELFAttrParserCompact.h | 82 ++++++++
.../llvm/Support/ELFAttrParserExtended.h | 51 +++++
.../include/llvm/Support/ELFAttributeParser.h | 63 +------
llvm/include/llvm/Support/ELFAttributes.h | 29 +++
.../llvm/Support/HexagonAttributeParser.h | 12 +-
.../llvm/Support/MSP430AttributeParser.h | 10 +-
.../llvm/Support/RISCVAttributeParser.h | 9 +-
llvm/lib/Object/ELFObjectFile.cpp | 34 ++--
llvm/lib/Support/AArch64AttributeParser.cpp | 19 ++
llvm/lib/Support/AArch64BuildAttributes.cpp | 26 +--
llvm/lib/Support/CMakeLists.txt | 4 +-
llvm/lib/Support/CSKYAttributeParser.cpp | 10 +-
...uteParser.cpp => ELFAttrParserCompact.cpp} | 36 ++--
llvm/lib/Support/ELFAttrParserExtended.cpp | 176 ++++++++++++++++++
llvm/lib/Support/HexagonAttributeParser.cpp | 14 +-
llvm/lib/Support/RISCVAttributeParser.cpp | 8 +-
llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp | 67 ++++---
.../AArch64/AsmParser/AArch64AsmParser.cpp | 86 ++++-----
.../MCTargetDesc/AArch64ELFStreamer.cpp | 51 ++---
.../MCTargetDesc/AArch64TargetStreamer.cpp | 4 +-
.../MCTargetDesc/AArch64TargetStreamer.h | 9 +-
.../AArch64/build-attributes-comprehensive.s | 81 ++++++++
llvm/tools/llvm-readobj/ELFDumper.cpp | 7 +
llvm/unittests/Support/ARMAttributeParser.cpp | 2 +-
.../Support/CSKYAttributeParserTest.cpp | 4 +-
.../Support/ELFAttributeParserTest.cpp | 8 +-
.../Support/RISCVAttributeParserTest.cpp | 2 +-
34 files changed, 713 insertions(+), 266 deletions(-)
create mode 100644 llvm/include/llvm/Support/AArch64AttributeParser.h
create mode 100644 llvm/include/llvm/Support/ELFAttrParserCompact.h
create mode 100644 llvm/include/llvm/Support/ELFAttrParserExtended.h
create mode 100644 llvm/lib/Support/AArch64AttributeParser.cpp
rename llvm/lib/Support/{ELFAttributeParser.cpp => ELFAttrParserCompact.cpp} (85%)
create mode 100644 llvm/lib/Support/ELFAttrParserExtended.cpp
create mode 100644 llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-comprehensive.s
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 4d8989a21b501..0f9788640950f 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -1175,7 +1175,7 @@ mergeAttributesSection(Ctx &ctx,
switch (RISCVAttrs::AttrType(tag.attr)) {
// Integer attributes.
case RISCVAttrs::STACK_ALIGN:
- if (auto i = parser.getAttributeValue(tag.attr)) {
+ if (auto i = parser.getAttributeValue("", tag.attr)) {
auto r = merged.intAttr.try_emplace(tag.attr, *i);
if (r.second) {
firstStackAlign = sec;
@@ -1188,13 +1188,13 @@ mergeAttributesSection(Ctx &ctx,
}
continue;
case RISCVAttrs::UNALIGNED_ACCESS:
- if (auto i = parser.getAttributeValue(tag.attr))
+ if (auto i = parser.getAttributeValue("", tag.attr))
merged.intAttr[tag.attr] |= *i;
continue;
// String attributes.
case RISCVAttrs::ARCH:
- if (auto s = parser.getAttributeString(tag.attr)) {
+ if (auto s = parser.getAttributeString("", tag.attr)) {
hasArch = true;
mergeArch(ctx, exts, xlen, sec, *s);
}
@@ -1207,7 +1207,7 @@ mergeAttributesSection(Ctx &ctx,
break;
case RISCVAttrs::AttrType::ATOMIC_ABI:
- if (auto i = parser.getAttributeValue(tag.attr)) {
+ if (auto i = parser.getAttributeValue("", tag.attr)) {
auto r = merged.intAttr.try_emplace(tag.attr, *i);
if (r.second)
firstAtomicAbi = sec;
@@ -1225,12 +1225,12 @@ mergeAttributesSection(Ctx &ctx,
// TODO Adjust after resolution to
// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/352
if (tag.attr % 2 == 0) {
- if (auto i = parser.getAttributeValue(tag.attr)) {
+ if (auto i = parser.getAttributeValue("", tag.attr)) {
auto r = merged.intAttr.try_emplace(tag.attr, *i);
if (!r.second && r.first->second != *i)
r.first->second = 0;
}
- } else if (auto s = parser.getAttributeString(tag.attr)) {
+ } else if (auto s = parser.getAttributeString("", tag.attr)) {
auto r = merged.strAttr.try_emplace(tag.attr, *s);
if (!r.second && r.first->second != *s)
r.first->second = {};
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index d43de8ce6dfef..fa94f02819298 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -107,7 +107,7 @@ static ELFKind getELFKind(Ctx &ctx, MemoryBufferRef mb, StringRef archiveName) {
static void updateARMVFPArgs(Ctx &ctx, const ARMAttributeParser &attributes,
const InputFile *f) {
std::optional<unsigned> attr =
- attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
+ attributes.getAttributeValue("", ARMBuildAttrs::ABI_VFP_args);
if (!attr)
// If an ABI tag isn't present then it is implicitly given the value of 0
// which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files,
@@ -155,7 +155,7 @@ static void updateARMVFPArgs(Ctx &ctx, const ARMAttributeParser &attributes,
static void updateSupportedARMFeatures(Ctx &ctx,
const ARMAttributeParser &attributes) {
std::optional<unsigned> attr =
- attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+ attributes.getAttributeValue("", ARMBuildAttrs::CPU_arch);
if (!attr)
return;
auto arch = *attr;
@@ -189,7 +189,7 @@ static void updateSupportedARMFeatures(Ctx &ctx,
// Only ARMv8-M or later architectures have CMSE support.
std::optional<unsigned> profile =
- attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
+ attributes.getAttributeValue("", ARMBuildAttrs::CPU_arch_profile);
if (!profile)
return;
if (arch >= ARMBuildAttrs::CPUArch::v8_M_Base &&
@@ -200,9 +200,9 @@ static void updateSupportedARMFeatures(Ctx &ctx,
// For now, let's limit it to ones where ARM isn't available and we know have
// Thumb2.
std::optional<unsigned> armISA =
- attributes.getAttributeValue(ARMBuildAttrs::ARM_ISA_use);
+ attributes.getAttributeValue("", ARMBuildAttrs::ARM_ISA_use);
std::optional<unsigned> thumb =
- attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);
+ attributes.getAttributeValue("", ARMBuildAttrs::THUMB_ISA_use);
ctx.arg.armHasArmISA |= armISA && *armISA >= ARMBuildAttrs::Allowed;
ctx.arg.armHasThumb2ISA |= thumb && *thumb >= ARMBuildAttrs::AllowThumb32;
}
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h
index 60c72062a3f6a..bafc92cafe539 100644
--- a/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/llvm/include/llvm/Object/ELFObjectFile.h
@@ -410,6 +410,9 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
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 0000000000000..add18fa3349fe
--- /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 const std::vector<SubsectionAndTagToTagName> 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 2479992cf8e79..ea293b72f9bb1 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
diff --git a/llvm/include/llvm/Support/ARMAttributeParser.h b/llvm/include/llvm/Support/ARMAttributeParser.h
index d1d953120ae7e..749f9cd2213d7 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 e926ebe5e306e..08257a744a959 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 0000000000000..cb2710ec631af
--- /dev/null
+++ b/llvm/include/llvm/Support/ELFAttrParserCompact.h
@@ -0,0 +1,82 @@
+//===- 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 <optional>
+#include <unordered_map>
+
+namespace llvm {
+class StringRef;
+class ScopedPrinter;
+
+class ELFCompactAttrParser : public ELFAttributeParser {
+ StringRef vendor;
+ std::unordered_map<unsigned, unsigned> attributes;
+ std::unordered_map<unsigned, StringRef> attributesStr;
+
+ virtual Error handler(uint64_t tag, bool &handled) = 0;
+
+protected:
+ ScopedPrinter *sw;
+ TagNameMap tagToStringMap;
+ DataExtractor de{ArrayRef<uint8_t>{}, true, 0};
+ DataExtractor::Cursor cursor{0};
+
+ void printAttribute(unsigned tag, unsigned value, StringRef valueDesc);
+
+ Error parseStringAttribute(const char *name, unsigned tag,
+ ArrayRef<const char *> strings);
+ Error parseAttributeList(uint32_t length);
+ void parseIndexList(SmallVectorImpl<uint8_t> &indexList);
+ Error parseSubsection(uint32_t length);
+
+ void setAttributeString(unsigned tag, StringRef value) {
+ attributesStr.emplace(tag, value);
+ }
+
+public:
+ virtual ~ELFCompactAttrParser() { static_cast<void>(!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<uint8_t> section, llvm::endianness endian) override;
+
+ std::optional<unsigned>
+ getAttributeValue(StringRef buildAttributeSubsectionName,
+ unsigned tag) const override {
+ auto I = attributes.find(tag);
+ if (I == attributes.end())
+ return std::nullopt;
+ return I->second;
+ }
+ std::optional<StringRef>
+ getAttributeString(StringRef buildAttributeSubsectionName,
+ unsigned tag) const override {
+ auto I = attributesStr.find(tag);
+ if (I == attributesStr.end())
+ return std::nullopt;
+ return I->second;
+ }
+};
+
+} // 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 0000000000000..5fc1371173313
--- /dev/null
+++ b/llvm/include/llvm/Support/ELFAttrParserExtended.h
@@ -0,0 +1,51 @@
+//===- 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 <optional>
+#include <vector>
+
+namespace llvm {
+class StringRef;
+class ScopedPrinter;
+
+class ELFExtendedAttrParser : public ELFAttributeParser {
+protected:
+ ScopedPrinter *Sw;
+ DataExtractor De{ArrayRef<uint8_t>{}, true, 0};
+ DataExtractor::Cursor Cursor{0};
+
+ // Data structure for holding Extended ELF Build Attribute subsection
+ SmallVector<BuildAttributeSubSection, 64> SubSectionVec;
+ // Maps SubsectionName + Tag to tags names. Required for printing comments.
+ const std::vector<SubsectionAndTagToTagName> TagsNamesMap;
+ StringRef getTagName(const StringRef &s, const unsigned i);
+
+public:
+ Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian) override;
+
+ std::optional<unsigned> getAttributeValue(StringRef BuildAttrSubsectionName,
+ unsigned Tag) const override;
+ std::optional<StringRef> getAttributeString(StringRef BuildAttrSubsectionName,
+ unsigned Tag) const override;
+
+ ELFExtendedAttrParser(ScopedPrinter *Sw,
+ std::vector<SubsectionAndTagToTagName> TagsNamesMap)
+ : Sw(Sw), TagsNamesMap(TagsNamesMap) {}
+ ELFExtendedAttrParser(std::vector<SubsectionAndTagToTagName> 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 ffb92468fb37e..1eeaaea3bf356 100644
--- a/llvm/include/llvm/Support/ELFAttributeParser.h
+++ b/llvm/include/llvm/Support/ELFAttributeParser.h
@@ -9,69 +9,22 @@
#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 <optional>
-#include <unordered_map>
-
namespace llvm {
-class StringRef;
-class ScopedPrinter;
class ELFAttributeParser {
- StringRef vendor;
- std::unordered_map<unsigned, unsigned> attributes;
- std::unordered_map<unsigned, StringRef> attributesStr;
-
- virtual Error handler(uint64_t tag, bool &handled) = 0;
-
-protected:
- ScopedPrinter *sw;
- TagNameMap tagToStringMap;
- DataExtractor de{ArrayRef<uint8_t>{}, true, 0};
- DataExtractor::Cursor cursor{0};
-
- void printAttribute(unsigned tag, unsigned value, StringRef valueDesc);
-
- Error parseStringAttribute(const char *name, unsigned tag,
- ArrayRef<const char *> strings);
- Error parseAttributeList(uint32_t length);
- void parseIndexList(SmallVectorImpl<uint8_t> &indexList);
- Error parseSubsection(uint32_t length);
-
- void setAttributeString(unsigned tag, StringRef value) {
- attributesStr.emplace(tag, value);
- }
-
public:
- virtual ~ELFAttributeParser() { static_cast<void>(!cursor.takeError()); }
- Error integerAttribute(unsigned tag);
- Error stringAttribute(unsigned tag);
-
- 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<uint8_t> section, llvm::endianness endian);
+ virtual ~ELFAttributeParser() {}
- std::optional<unsigned> getAttributeValue(unsigned tag) const {
- auto I = attributes.find(tag);
- if (I == attributes.end())
- return std::nullopt;
- return I->second;
- }
- std::optional<StringRef> getAttributeString(unsigned tag) const {
- auto I = attributesStr.find(tag);
- if (I == attributesStr.end())
- return std::nullopt;
- return I->second;
- }
+ virtual Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian);
+ virtual std::optional<unsigned>
+ getAttributeValue(StringRef BuildAttrSubsectionName, unsigned Tag) const;
+ virtual std::optional<StringRef>
+ getAttributeString(StringRef BuildAttrSubsectionName, unsigned Tag) const;
};
} // 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 295d0f4669812..6782aec6050ad 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<TagNameItem>;
+// 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<BuildAttributeItem, 64> 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 1116dd42b1ad0..462bfc4e2df1e 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 bc9b214944708..3a4f1b43d9d18 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 9f295504de959..4a74ed321d7a2 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/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp
index ac25d76709726..a0f381274f4f9 100644
--- a/llvm/lib/Object/ELFObjectFile.cpp
+++ b/llvm/lib/Object/ELFObjectFile.cpp
@@ -168,11 +168,11 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
// both ARMv7-M and R have to support thumb hardware div
bool isV7 = false;
std::optional<unsigned> Attr =
- Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+ Attributes.getAttributeValue("", ARMBuildAttrs::CPU_arch);
if (Attr)
isV7 = *Attr == ARMBuildAttrs::v7;
- Attr = Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
+ Attr = Attributes.getAttributeValue("", ARMBuildAttrs::CPU_arch_profile);
if (Attr) {
switch (*Attr) {
case ARMBuildAttrs::ApplicationProfile:
@@ -191,7 +191,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- Attr = Attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);
+ Attr = Attributes.getAttributeValue("", ARMBuildAttrs::THUMB_ISA_use);
if (Attr) {
switch (*Attr) {
default:
@@ -206,7 +206,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- Attr = Attributes.getAttributeValue(ARMBuildAttrs::FP_arch);
+ Attr = Attributes.getAttributeValue("", ARMBuildAttrs::FP_arch);
if (Attr) {
switch (*Attr) {
default:
@@ -230,7 +230,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- Attr = Attributes.getAttributeValue(ARMBuildAttrs::Advanced_SIMD_arch);
+ Attr = Attributes.getAttributeValue("", ARMBuildAttrs::Advanced_SIMD_arch);
if (Attr) {
switch (*Attr) {
default:
@@ -249,7 +249,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- Attr = Attributes.getAttributeValue(ARMBuildAttrs::MVE_arch);
+ Attr = Attributes.getAttributeValue("", ARMBuildAttrs::MVE_arch);
if (Attr) {
switch (*Attr) {
default:
@@ -268,7 +268,7 @@ SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
}
}
- Attr = Attributes.getAttributeValue(ARMBuildAttrs::DIV_use);
+ Attr = Attributes.getAttributeValue("", ARMBuildAttrs::DIV_use);
if (Attr) {
switch (*Attr) {
default:
@@ -327,13 +327,13 @@ SubtargetFeatures ELFObjectFileBase::getHexagonFeatures() const {
}
std::optional<unsigned> Attr;
- if ((Attr = Parser.getAttributeValue(HexagonAttrs::ARCH))) {
+ if ((Attr = Parser.getAttributeValue("", HexagonAttrs::ARCH))) {
if (std::optional<std::string> FeatureString =
hexagonAttrToFeatureString(*Attr))
Features.AddFeature(*FeatureString);
}
- if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXARCH))) {
+ if ((Attr = Parser.getAttributeValue("", HexagonAttrs::HVXARCH))) {
std::optional<std::string> FeatureString =
hexagonAttrToFeatureString(*Attr);
// There is no corresponding hvx arch for v5 and v55.
@@ -341,23 +341,23 @@ SubtargetFeatures ELFObjectFileBase::getHexagonFeatures() const {
Features.AddFeature("hvx" + *FeatureString);
}
- if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXIEEEFP)))
+ if ((Attr = Parser.getAttributeValue("", HexagonAttrs::HVXIEEEFP)))
if (*Attr)
Features.AddFeature("hvx-ieee-fp");
- if ((Attr = Parser.getAttributeValue(HexagonAttrs::HVXQFLOAT)))
+ if ((Attr = Parser.getAttributeValue("", HexagonAttrs::HVXQFLOAT)))
if (*Attr)
Features.AddFeature("hvx-qfloat");
- if ((Attr = Parser.getAttributeValue(HexagonAttrs::ZREG)))
+ if ((Attr = Parser.getAttributeValue("", HexagonAttrs::ZREG)))
if (*Attr)
Features.AddFeature("zreg");
- if ((Attr = Parser.getAttributeValue(HexagonAttrs::AUDIO)))
+ if ((Attr = Parser.getAttributeValue("", HexagonAttrs::AUDIO)))
if (*Attr)
Features.AddFeature("audio");
- if ((Attr = Parser.getAttributeValue(HexagonAttrs::CABAC)))
+ if ((Attr = Parser.getAttributeValue("", HexagonAttrs::CABAC)))
if (*Attr)
Features.AddFeature("cabac");
@@ -378,7 +378,7 @@ Expected<SubtargetFeatures> ELFObjectFileBase::getRISCVFeatures() const {
}
std::optional<StringRef> Attr =
- Attributes.getAttributeString(RISCVAttrs::ARCH);
+ Attributes.getAttributeString("", RISCVAttrs::ARCH);
if (Attr) {
auto ParseResult = RISCVISAInfo::parseNormalizedArchString(*Attr);
if (!ParseResult)
@@ -703,7 +703,7 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
Triple = "arm";
std::optional<unsigned> Attr =
- Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
+ Attributes.getAttributeValue("", ARMBuildAttrs::CPU_arch);
if (Attr) {
switch (*Attr) {
case ARMBuildAttrs::v4:
@@ -735,7 +735,7 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
break;
case ARMBuildAttrs::v7: {
std::optional<unsigned> ArchProfileAttr =
- Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
+ Attributes.getAttributeValue("", ARMBuildAttrs::CPU_arch_profile);
if (ArchProfileAttr &&
*ArchProfileAttr == ARMBuildAttrs::MicroControllerProfile)
Triple += "v7m";
diff --git a/llvm/lib/Support/AArch64AttributeParser.cpp b/llvm/lib/Support/AArch64AttributeParser.cpp
new file mode 100644
index 0000000000000..031d871e3a2e7
--- /dev/null
+++ b/llvm/lib/Support/AArch64AttributeParser.cpp
@@ -0,0 +1,19 @@
+//===-- 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"
+
+const std::vector<llvm::SubsectionAndTagToTagName>
+llvm::AArch64AttributeParser::returnTagsNamesMap() {
+ return {{"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"}};
+}
diff --git a/llvm/lib/Support/AArch64BuildAttributes.cpp b/llvm/lib/Support/AArch64BuildAttributes.cpp
index e36667ca711e0..4a6b2fd538803 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<VendorID>(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<SubsectionOptional>(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<SubsectionType>(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<PauthABITags>(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<FeatureAndBitsTags>(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 a6d8a25818866..49a26a618de83 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 40ee617b981b2..1e46bf8127df6 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 85%
rename from llvm/lib/Support/ELFAttributeParser.cpp
rename to llvm/lib/Support/ELFAttrParserCompact.cpp
index 26c3d54e17ade..4880083177cb8 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<unsigned> tagNames[] = {
{"Tag_Symbol", ELFAttrs::Symbol},
};
-Error ELFAttributeParser::parseStringAttribute(const char *name, unsigned tag,
- ArrayRef<const char *> strings) {
+Error ELFCompactAttrParser::parseStringAttribute(
+ const char *name, unsigned tag, ArrayRef<const char *> 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<uint8_t> &indexList) {
+void ELFCompactAttrParser::parseIndexList(SmallVectorImpl<uint8_t> &indexList) {
for (;;) {
uint64_t value = de.getULEB128(cursor);
if (!cursor || !value)
@@ -91,7 +94,7 @@ void ELFAttributeParser::parseIndexList(SmallVectorImpl<uint8_t> &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) {
@@ -128,9 +131,8 @@ Error ELFAttributeParser::parseSubsection(uint32_t length) {
}
// Handle a subsection with an unrecognized vendor-name by skipping
- // over it to the next subsection. ADDENDA32 in the Arm ABI defines
- // that vendor attribute sections must not affect compatibility, so
- // this should always be safe.
+ // over it to the next subsection. vendor attribute sections must not
+ // affect compatibility, so this should always be safe.
if (vendorName.lower() != vendor) {
cursor.seek(end);
return Error::success();
@@ -188,8 +190,8 @@ Error ELFAttributeParser::parseSubsection(uint32_t length) {
return Error::success();
}
-Error ELFAttributeParser::parse(ArrayRef<uint8_t> section,
- llvm::endianness endian) {
+Error ELFCompactAttrParser::parse(ArrayRef<uint8_t> 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 0000000000000..138bc99aa69ff
--- /dev/null
+++ b/llvm/lib/Support/ELFAttrParserExtended.cpp
@@ -0,0 +1,176 @@
+//===-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 <cstdint>
+
+using namespace llvm;
+using namespace ELFAttrs;
+
+std::optional<unsigned>
+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<unsigned>(BAItem.IntValue);
+ }
+ }
+ return std::nullopt;
+}
+
+std::optional<StringRef>
+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<StringRef>(BAItem.StringValue);
+ }
+ }
+ return std::nullopt;
+}
+
+StringRef ELFExtendedAttrParser::getTagName(const StringRef &s,
+ const unsigned i) {
+ for (const auto &entry : TagsNamesMap) {
+ if (s == entry.SubsectionName) {
+ if (i == entry.Tag) {
+ return entry.TagName;
+ }
+ }
+ }
+ return "";
+}
+
+Error ELFExtendedAttrParser::parse(ArrayRef<uint8_t> 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:
+ <format-version: ‘A’> --> Currently, there is only one version: 'A' (0x41)
+ [ <uint32: subsection-length> <NTBS: vendor-name> <bytes: vendor-data> ]
+ --> 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:
+ [ <uint8: optional> <uint8: parameter type> <attribute>* ]
+ --> optional: 0 = required, 1 = optional.
+ --> parameter type: 0 = ULEB128, 1 = NTBS.
+ --> attribute: <tag, value>* pair. Tag is ULEB128, value is of
+ <parameter type>.
+ */
+
+ // 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);
+ std::string Str = utostr(Tag);
+ StringRef TagStr(Str);
+
+ StringRef TagAsString = getTagName(VendorName, Tag);
+ if ("" != TagAsString)
+ TagStr = TagAsString;
+
+ uint64_t ValueInt = 0;
+ std::string ValueStr = "";
+ if (Type) { // type==1 --> ntbs
+ StringRef Value = De.getCStrRef(Cursor);
+ if (Sw)
+ Sw->printString(TagStr, Value);
+ } else { // type==0 --> uleb128
+ uint64_t Value = De.getULEB128(Cursor);
+ if (Sw)
+ Sw->printNumber(TagStr, Value);
+ }
+
+ // populate data structure
+ BuildAttributeItem BAItem(static_cast<BuildAttributeItem::Types>(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 2143162d11c79..3baa976574930 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 20392e4bae19f..41c48859566e4 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 fc38bfe93c1e0..6216315766fc8 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<ConstantInt>(
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<ConstantInt>(
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<ConstantInt>(
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, "");
- }
-
- 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;
+ 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 & 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 6a973b0160e23..1e7296fa23486 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 08cff5a0fefac..fbd0d1f96f6ba 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 028d9196613cb..04defbc977462 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 9cbb104c0eb9e..43e099f919999 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
@@ -97,8 +97,8 @@ class AArch64TargetStreamer : public MCTargetStreamer {
/// 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 @@ class AArch64TargetELFStreamer : public AArch64TargetStreamer {
/// 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 0000000000000..aadbbcd507664
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-comprehensive.s
@@ -0,0 +1,81 @@
+# RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | 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 fdae09ac767e6..91f211bbe4156 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 <class ELFT> void ELFDumper<ELFT>::printArchSpecificInfo() {
ELF::SHT_ARM_ATTRIBUTES, std::make_unique<ARMAttributeParser>(&W),
Obj.isLE() ? llvm::endianness::little : llvm::endianness::big);
break;
+ case EM_AARCH64:
+ printAttributes(ELF::SHT_AARCH64_ATTRIBUTES,
+ std::make_unique<AArch64AttributeParser>(&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 a0568262b4da9..e06f7fab85fa7 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<unsigned> Attr = Parser.getAttributeValue(ExpectedTag);
+ std::optional<unsigned> Attr = Parser.getAttributeValue("", ExpectedTag);
return Attr && *Attr == ExpectedValue;
}
diff --git a/llvm/unittests/Support/CSKYAttributeParserTest.cpp b/llvm/unittests/Support/CSKYAttributeParserTest.cpp
index 2c5d93b0b7565..25b151fe5c1c1 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<unsigned> Attr = Parser.getAttributeValue(ExpectedTag);
+ std::optional<unsigned> 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<StringRef> Attr = Parser.getAttributeString(ExpectedTag);
+ std::optional<StringRef> Attr = Parser.getAttributeString("", ExpectedTag);
return Attr && *Attr == ExpectedValue;
}
diff --git a/llvm/unittests/Support/ELFAttributeParserTest.cpp b/llvm/unittests/Support/ELFAttributeParserTest.cpp
index 38e7b09cc3c7d..31cc594188e33 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 <string>
@@ -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<uint8_t> bytes, const char *msg) {
diff --git a/llvm/unittests/Support/RISCVAttributeParserTest.cpp b/llvm/unittests/Support/RISCVAttributeParserTest.cpp
index aa73bb92d6e3e..777dc4d0f4d42 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<unsigned> Attr = Parser.getAttributeValue(ExpectedTag);
+ std::optional<unsigned> Attr = Parser.getAttributeValue("", ExpectedTag);
return Attr && *Attr == ExpectedValue;
}
>From 16feaafe0ea47a125102ca3deb926d44fc2c00b0 Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 26 Feb 2025 10:13:02 +0000
Subject: [PATCH 2/5] Remove '-o -' from llvm-mc arguments since it is the
default.
---
.../llvm-readobj/ELF/AArch64/build-attributes-comprehensive.s | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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
index aadbbcd507664..d202bcbedf446 100644
--- a/llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-comprehensive.s
+++ b/llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-comprehensive.s
@@ -1,4 +1,4 @@
-# RUN: llvm-mc -triple=aarch64 -filetype=obj %s -o - | llvm-readelf --arch-specific - | FileCheck %s --check-prefix=ATTR
+# RUN: llvm-mc -triple=aarch64 -filetype=obj %s | llvm-readelf --arch-specific - | FileCheck %s --check-prefix=ATTR
# ATTR: BuildAttributes {
# ATTR-NEXT: FormatVersion: 0x41
>From 17ed192587154f34ae2d88f937020e714445b95f Mon Sep 17 00:00:00 2001
From: Sivan Shani <sivan.shani at arm.com>
Date: Wed, 26 Feb 2025 10:23:00 +0000
Subject: [PATCH 3/5] Provide default implementations for ELFAttributeParser
virtual functions to prevent compilation errors when no derived class is
initialized, such as on non-ELF platforms.
---
llvm/include/llvm/Support/ELFAttributeParser.h | 12 +++++++++---
tests.sh | 11 +++++++++++
tests_ra.sh | 11 +++++++++++
3 files changed, 31 insertions(+), 3 deletions(-)
create mode 100755 tests.sh
create mode 100755 tests_ra.sh
diff --git a/llvm/include/llvm/Support/ELFAttributeParser.h b/llvm/include/llvm/Support/ELFAttributeParser.h
index 1eeaaea3bf356..a033e580c8859 100644
--- a/llvm/include/llvm/Support/ELFAttributeParser.h
+++ b/llvm/include/llvm/Support/ELFAttributeParser.h
@@ -19,11 +19,17 @@ class ELFAttributeParser {
public:
virtual ~ELFAttributeParser() {}
- virtual Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian);
+ virtual Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian) {
+ return llvm::Error::success();
+ }
virtual std::optional<unsigned>
- getAttributeValue(StringRef BuildAttrSubsectionName, unsigned Tag) const;
+ getAttributeValue(StringRef BuildAttrSubsectionName, unsigned Tag) const {
+ return std::nullopt;
+ }
virtual std::optional<StringRef>
- getAttributeString(StringRef BuildAttrSubsectionName, unsigned Tag) const;
+ getAttributeString(StringRef BuildAttrSubsectionName, unsigned Tag) const {
+ return std::nullopt;
+ }
};
} // namespace llvm
diff --git a/tests.sh b/tests.sh
new file mode 100755
index 0000000000000..f505af1700eee
--- /dev/null
+++ b/tests.sh
@@ -0,0 +1,11 @@
+${binrl}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
+${binral}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
+${bindl}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
+
+${binrl}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
+${binral}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
+${bindl}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
+
+${binrl}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
+${binral}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
+${bindl}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
diff --git a/tests_ra.sh b/tests_ra.sh
new file mode 100755
index 0000000000000..388a02cbc6a6c
--- /dev/null
+++ b/tests_ra.sh
@@ -0,0 +1,11 @@
+# ${binrl}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
+${binral}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
+# ${bindl}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
+
+# ${binrl}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
+${binral}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
+# ${bindl}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
+
+# ${binrl}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
+${binral}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
+# ${bindl}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
>From e89d817d5540cc9820b354d72ba27538ef303f29 Mon Sep 17 00:00:00 2001
From: SivanShani-Arm <sivan.shani at arm.com>
Date: Wed, 26 Feb 2025 10:43:59 +0000
Subject: [PATCH 4/5] Delete tests_ra.sh
---
tests_ra.sh | 11 -----------
1 file changed, 11 deletions(-)
delete mode 100755 tests_ra.sh
diff --git a/tests_ra.sh b/tests_ra.sh
deleted file mode 100755
index 388a02cbc6a6c..0000000000000
--- a/tests_ra.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-# ${binrl}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
-${binral}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
-# ${bindl}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
-
-# ${binrl}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
-${binral}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
-# ${bindl}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
-
-# ${binrl}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
-${binral}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
-# ${bindl}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
>From ae9dd167327945d5ae887d1778b1b7dab3cd8c4f Mon Sep 17 00:00:00 2001
From: SivanShani-Arm <sivan.shani at arm.com>
Date: Wed, 26 Feb 2025 10:44:21 +0000
Subject: [PATCH 5/5] Delete tests.sh
---
tests.sh | 11 -----------
1 file changed, 11 deletions(-)
delete mode 100755 tests.sh
diff --git a/tests.sh b/tests.sh
deleted file mode 100755
index f505af1700eee..0000000000000
--- a/tests.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-${binrl}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
-${binral}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
-${bindl}/llvm-lit -v llvm/test/MC/AArch64/build-attributes-asm-*
-
-${binrl}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
-${binral}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
-${bindl}/llvm-lit -v llvm/test/CodeGen/AArch64/build-attributes-*
-
-${binrl}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
-${binral}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
-${bindl}/llvm-lit -v llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-*
More information about the llvm-commits
mailing list