[lld] [llvm] [readobj][Arm][AArch64] Refactor build attribute parsing under ELFAtributeParser and add support for AArch64 Build Attributes (PR #128727)

via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 25 07:17:46 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-support

@llvm/pr-subscribers-backend-risc-v

Author: SivanShani-Arm (sivan-shani)

<details>
<summary>Changes</summary>

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.

---

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


35 Files Affected:

- (modified) lld/ELF/Arch/RISCV.cpp (+6-6) 
- (modified) lld/ELF/InputFiles.cpp (+5-5) 
- (modified) llvm/include/llvm/Object/ELFObjectFile.h (+3) 
- (added) llvm/include/llvm/Support/AArch64AttributeParser.h (+29) 
- (modified) llvm/include/llvm/Support/AArch64BuildAttributes.h (+2-2) 
- (modified) llvm/include/llvm/Support/ARMAttributeParser.h (+5-4) 
- (modified) llvm/include/llvm/Support/CSKYAttributeParser.h (+4-4) 
- (added) llvm/include/llvm/Support/ELFAttrParserCompact.h (+82) 
- (added) llvm/include/llvm/Support/ELFAttrParserExtended.h (+51) 
- (modified) llvm/include/llvm/Support/ELFAttributeParser.h (+8-55) 
- (modified) llvm/include/llvm/Support/ELFAttributes.h (+29) 
- (modified) llvm/include/llvm/Support/HexagonAttributeParser.h (+6-6) 
- (modified) llvm/include/llvm/Support/MSP430AttributeParser.h (+5-5) 
- (modified) llvm/include/llvm/Support/RISCVAttributeParser.h (+5-4) 
- (modified) llvm/lib/Object/ELFObjectFile.cpp (+17-17) 
- (added) llvm/lib/Support/AArch64AttributeParser.cpp (+19) 
- (modified) llvm/lib/Support/AArch64BuildAttributes.cpp (+13-13) 
- (modified) llvm/lib/Support/CMakeLists.txt (+3-1) 
- (modified) llvm/lib/Support/CSKYAttributeParser.cpp (+5-5) 
- (renamed) llvm/lib/Support/ELFAttrParserCompact.cpp (+19-17) 
- (added) llvm/lib/Support/ELFAttrParserExtended.cpp (+176) 
- (modified) llvm/lib/Support/HexagonAttributeParser.cpp (+7-7) 
- (modified) llvm/lib/Support/RISCVAttributeParser.cpp (+4-4) 
- (modified) llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp (+37-30) 
- (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+44-42) 
- (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp (+26-25) 
- (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp (+2-2) 
- (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h (+5-4) 
- (added) llvm/test/tools/llvm-readobj/ELF/AArch64/aarch64-build-attributes-comprehensive.s (+81) 
- (added) llvm/test/tools/llvm-readobj/ELF/AArch64/build-attributes-comprehensive.s (+81) 
- (modified) llvm/tools/llvm-readobj/ELFDumper.cpp (+7) 
- (modified) llvm/unittests/Support/ARMAttributeParser.cpp (+1-1) 
- (modified) llvm/unittests/Support/CSKYAttributeParserTest.cpp (+2-2) 
- (modified) llvm/unittests/Support/ELFAttributeParserTest.cpp (+4-4) 
- (modified) llvm/unittests/Support/RISCVAttributeParserTest.cpp (+1-1) 


``````````diff
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::getHexag...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list