Skip to content

Commit b1ebfac

Browse files
authored
[readobj][Arm][AArch64] Refactor Build Attributes parsing under ELFAtributeParser and add support for AArch64 Build Attributes (#128727)
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.
1 parent 4a59d0c commit b1ebfac

31 files changed

+722
-234
lines changed

llvm/include/llvm/Object/ELFObjectFile.h

+3
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
410410
case ELF::EM_ARM:
411411
Type = ELF::SHT_ARM_ATTRIBUTES;
412412
break;
413+
case ELF::EM_AARCH64:
414+
Type = ELF::SHT_AARCH64_ATTRIBUTES;
415+
break;
413416
case ELF::EM_RISCV:
414417
Type = ELF::SHT_RISCV_ATTRIBUTES;
415418
break;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//=== - AArch64AttributeParser.h-AArch64 Attribute Information Printer - ===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===--------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H
10+
#define LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H
11+
12+
#include "llvm/Support/ELFAttrParserExtended.h"
13+
#include "llvm/Support/ELFAttributes.h"
14+
15+
namespace llvm {
16+
17+
class AArch64AttributeParser : public ELFExtendedAttrParser {
18+
static std::vector<SubsectionAndTagToTagName> &returnTagsNamesMap();
19+
20+
public:
21+
AArch64AttributeParser(ScopedPrinter *Sw)
22+
: ELFExtendedAttrParser(Sw, returnTagsNamesMap()) {}
23+
AArch64AttributeParser()
24+
: ELFExtendedAttrParser(nullptr, returnTagsNamesMap()) {}
25+
};
26+
27+
} // namespace llvm
28+
29+
#endif // LLVM_SUPPORT_AARCH64ATTRIBUTEPARSER_H

llvm/include/llvm/Support/AArch64BuildAttributes.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
namespace llvm {
2424

25-
namespace AArch64BuildAttrs {
25+
namespace AArch64BuildAttributes {
2626

2727
/// AArch64 build attributes vendors IDs (a.k.a subsection name)
2828
enum VendorID : unsigned {
@@ -69,7 +69,7 @@ enum FeatureAndBitsFlag : unsigned {
6969
Feature_PAC_Flag = 1 << 1,
7070
Feature_GCS_Flag = 1 << 2
7171
};
72-
} // namespace AArch64BuildAttrs
72+
} // namespace AArch64BuildAttributes
7373
} // namespace llvm
7474

75-
#endif // LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H
75+
#endif // LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H

llvm/include/llvm/Support/ARMAttributeParser.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@
1010
#define LLVM_SUPPORT_ARMATTRIBUTEPARSER_H
1111

1212
#include "ARMBuildAttributes.h"
13-
#include "ELFAttributeParser.h"
1413
#include "llvm/ADT/StringRef.h"
14+
#include "llvm/Support/ELFAttrParserCompact.h"
1515
#include "llvm/Support/Error.h"
1616

1717
namespace llvm {
1818

1919
class ScopedPrinter;
2020

21-
class ARMAttributeParser : public ELFAttributeParser {
21+
class ARMAttributeParser : public ELFCompactAttrParser {
2222
struct DisplayHandler {
2323
ARMBuildAttrs::AttrType attribute;
2424
Error (ARMAttributeParser::*routine)(ARMBuildAttrs::AttrType);
@@ -74,9 +74,10 @@ class ARMAttributeParser : public ELFAttributeParser {
7474

7575
public:
7676
ARMAttributeParser(ScopedPrinter *sw)
77-
: ELFAttributeParser(sw, ARMBuildAttrs::getARMAttributeTags(), "aeabi") {}
77+
: ELFCompactAttrParser(sw, ARMBuildAttrs::getARMAttributeTags(),
78+
"aeabi") {}
7879
ARMAttributeParser()
79-
: ELFAttributeParser(ARMBuildAttrs::getARMAttributeTags(), "aeabi") {}
80+
: ELFCompactAttrParser(ARMBuildAttrs::getARMAttributeTags(), "aeabi") {}
8081
};
8182
}
8283

llvm/include/llvm/Support/CSKYAttributeParser.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
#define LLVM_SUPPORT_CSKYATTRIBUTEPARSER_H
1111

1212
#include "llvm/Support/CSKYAttributes.h"
13-
#include "llvm/Support/ELFAttributeParser.h"
13+
#include "llvm/Support/ELFAttrParserCompact.h"
1414

1515
namespace llvm {
16-
class CSKYAttributeParser : public ELFAttributeParser {
16+
class CSKYAttributeParser : public ELFCompactAttrParser {
1717
struct DisplayHandler {
1818
CSKYAttrs::AttrType attribute;
1919
Error (CSKYAttributeParser::*routine)(unsigned);
@@ -33,9 +33,9 @@ class CSKYAttributeParser : public ELFAttributeParser {
3333

3434
public:
3535
CSKYAttributeParser(ScopedPrinter *sw)
36-
: ELFAttributeParser(sw, CSKYAttrs::getCSKYAttributeTags(), "csky") {}
36+
: ELFCompactAttrParser(sw, CSKYAttrs::getCSKYAttributeTags(), "csky") {}
3737
CSKYAttributeParser()
38-
: ELFAttributeParser(CSKYAttrs::getCSKYAttributeTags(), "csky") {}
38+
: ELFCompactAttrParser(CSKYAttrs::getCSKYAttributeTags(), "csky") {}
3939
};
4040

4141
} // namespace llvm
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//===- ELF AttributeParser.h - ELF Attribute Parser -------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H
10+
#define LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H
11+
12+
#include "llvm/ADT/ArrayRef.h"
13+
#include "llvm/Support/DataExtractor.h"
14+
#include "llvm/Support/ELFAttributeParser.h"
15+
#include "llvm/Support/ELFAttributes.h"
16+
#include "llvm/Support/Error.h"
17+
18+
#include <optional>
19+
#include <unordered_map>
20+
21+
namespace llvm {
22+
class StringRef;
23+
class ScopedPrinter;
24+
25+
class ELFCompactAttrParser : public ELFAttributeParser {
26+
StringRef vendor;
27+
std::unordered_map<unsigned, unsigned> attributes;
28+
std::unordered_map<unsigned, StringRef> attributesStr;
29+
30+
virtual Error handler(uint64_t tag, bool &handled) = 0;
31+
32+
protected:
33+
ScopedPrinter *sw;
34+
TagNameMap tagToStringMap;
35+
DataExtractor de{ArrayRef<uint8_t>{}, true, 0};
36+
DataExtractor::Cursor cursor{0};
37+
38+
void printAttribute(unsigned tag, unsigned value, StringRef valueDesc);
39+
40+
Error parseStringAttribute(const char *name, unsigned tag,
41+
ArrayRef<const char *> strings);
42+
Error parseAttributeList(uint32_t length);
43+
void parseIndexList(SmallVectorImpl<uint8_t> &indexList);
44+
Error parseSubsection(uint32_t length);
45+
46+
void setAttributeString(unsigned tag, StringRef value) {
47+
attributesStr.emplace(tag, value);
48+
}
49+
50+
public:
51+
virtual ~ELFCompactAttrParser() { static_cast<void>(!cursor.takeError()); }
52+
Error integerAttribute(unsigned tag);
53+
Error stringAttribute(unsigned tag);
54+
55+
ELFCompactAttrParser(ScopedPrinter *sw, TagNameMap tagNameMap,
56+
StringRef vendor)
57+
: vendor(vendor), sw(sw), tagToStringMap(tagNameMap) {}
58+
ELFCompactAttrParser(TagNameMap tagNameMap, StringRef vendor)
59+
: vendor(vendor), sw(nullptr), tagToStringMap(tagNameMap) {}
60+
61+
Error parse(ArrayRef<uint8_t> section, llvm::endianness endian) override;
62+
63+
std::optional<unsigned> getAttributeValue(unsigned tag) const override {
64+
auto I = attributes.find(tag);
65+
if (I == attributes.end())
66+
return std::nullopt;
67+
return I->second;
68+
}
69+
std::optional<unsigned>
70+
getAttributeValue(StringRef buildAttributeSubsectionName,
71+
unsigned tag) const override {
72+
assert("" == buildAttributeSubsectionName &&
73+
"buildAttributeSubsectionName must be an empty string");
74+
return getAttributeValue(tag);
75+
}
76+
std::optional<StringRef> getAttributeString(unsigned tag) const override {
77+
auto I = attributesStr.find(tag);
78+
if (I == attributesStr.end())
79+
return std::nullopt;
80+
return I->second;
81+
}
82+
std::optional<StringRef>
83+
getAttributeString(StringRef buildAttributeSubsectionName,
84+
unsigned tag) const override {
85+
assert("" == buildAttributeSubsectionName &&
86+
"buildAttributeSubsectionName must be an empty string");
87+
return getAttributeString(tag);
88+
}
89+
};
90+
91+
} // namespace llvm
92+
#endif // LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//===- ELF AttributeParser.h - ELF Attribute Parser -------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H
10+
#define LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H
11+
12+
#include "llvm/ADT/ArrayRef.h"
13+
#include "llvm/Support/DataExtractor.h"
14+
#include "llvm/Support/ELFAttributeParser.h"
15+
#include "llvm/Support/ELFAttributes.h"
16+
#include "llvm/Support/Error.h"
17+
#include <optional>
18+
#include <vector>
19+
20+
namespace llvm {
21+
class StringRef;
22+
class ScopedPrinter;
23+
24+
class ELFExtendedAttrParser : public ELFAttributeParser {
25+
protected:
26+
ScopedPrinter *Sw;
27+
DataExtractor De{ArrayRef<uint8_t>{}, true, 0};
28+
DataExtractor::Cursor Cursor{0};
29+
30+
// Data structure for holding Extended ELF Build Attribute subsection
31+
SmallVector<BuildAttributeSubSection, 8> SubSectionVec;
32+
// Maps SubsectionName + Tag to tags names. Required for printing comments.
33+
const std::vector<SubsectionAndTagToTagName> TagsNamesMap;
34+
StringRef getTagName(const StringRef &BuildAttrSubsectionName,
35+
const unsigned Tag);
36+
37+
public:
38+
Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian) override;
39+
40+
std::optional<unsigned> getAttributeValue(unsigned Tag) const override;
41+
std::optional<unsigned> getAttributeValue(StringRef BuildAttrSubsectionName,
42+
unsigned Tag) const override;
43+
std::optional<StringRef> getAttributeString(unsigned Tag) const override;
44+
std::optional<StringRef> getAttributeString(StringRef BuildAttrSubsectionName,
45+
unsigned Tag) const override;
46+
47+
ELFExtendedAttrParser(
48+
ScopedPrinter *Sw,
49+
const std::vector<SubsectionAndTagToTagName> TagsNamesMap)
50+
: Sw(Sw), TagsNamesMap(TagsNamesMap) {}
51+
ELFExtendedAttrParser(
52+
const std::vector<SubsectionAndTagToTagName> TagsNamesMap)
53+
: Sw(nullptr), TagsNamesMap(TagsNamesMap) {}
54+
};
55+
} // namespace llvm
56+
#endif // LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H

llvm/include/llvm/Support/ELFAttributeParser.h

+18-53
Original file line numberDiff line numberDiff line change
@@ -9,69 +9,34 @@
99
#ifndef LLVM_SUPPORT_ELFATTRIBUTEPARSER_H
1010
#define LLVM_SUPPORT_ELFATTRIBUTEPARSER_H
1111

12-
#include "ELFAttributes.h"
1312
#include "llvm/ADT/ArrayRef.h"
14-
#include "llvm/Support/DataExtractor.h"
13+
#include "llvm/ADT/StringRef.h"
1514
#include "llvm/Support/Error.h"
1615

17-
#include <optional>
18-
#include <unordered_map>
19-
2016
namespace llvm {
21-
class StringRef;
22-
class ScopedPrinter;
2317

2418
class ELFAttributeParser {
25-
StringRef vendor;
26-
std::unordered_map<unsigned, unsigned> attributes;
27-
std::unordered_map<unsigned, StringRef> attributesStr;
28-
29-
virtual Error handler(uint64_t tag, bool &handled) = 0;
30-
31-
protected:
32-
ScopedPrinter *sw;
33-
TagNameMap tagToStringMap;
34-
DataExtractor de{ArrayRef<uint8_t>{}, true, 0};
35-
DataExtractor::Cursor cursor{0};
36-
37-
void printAttribute(unsigned tag, unsigned value, StringRef valueDesc);
38-
39-
Error parseStringAttribute(const char *name, unsigned tag,
40-
ArrayRef<const char *> strings);
41-
Error parseAttributeList(uint32_t length);
42-
void parseIndexList(SmallVectorImpl<uint8_t> &indexList);
43-
Error parseSubsection(uint32_t length);
44-
45-
void setAttributeString(unsigned tag, StringRef value) {
46-
attributesStr.emplace(tag, value);
47-
}
48-
4919
public:
50-
virtual ~ELFAttributeParser() { static_cast<void>(!cursor.takeError()); }
51-
Error integerAttribute(unsigned tag);
52-
Error stringAttribute(unsigned tag);
53-
54-
ELFAttributeParser(ScopedPrinter *sw, TagNameMap tagNameMap, StringRef vendor)
55-
: vendor(vendor), sw(sw), tagToStringMap(tagNameMap) {}
56-
57-
ELFAttributeParser(TagNameMap tagNameMap, StringRef vendor)
58-
: vendor(vendor), sw(nullptr), tagToStringMap(tagNameMap) {}
59-
60-
Error parse(ArrayRef<uint8_t> section, llvm::endianness endian);
20+
virtual ~ELFAttributeParser() {}
6121

62-
std::optional<unsigned> getAttributeValue(unsigned tag) const {
63-
auto I = attributes.find(tag);
64-
if (I == attributes.end())
65-
return std::nullopt;
66-
return I->second;
22+
virtual Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian) {
23+
return llvm::Error::success();
24+
}
25+
virtual std::optional<unsigned>
26+
getAttributeValue(StringRef BuildAttrSubsectionName, unsigned Tag) const {
27+
return std::nullopt;
28+
}
29+
virtual std::optional<unsigned> getAttributeValue(unsigned Tag) const {
30+
return std::nullopt;
31+
}
32+
virtual std::optional<StringRef>
33+
getAttributeString(StringRef BuildAttrSubsectionName, unsigned Tag) const {
34+
return std::nullopt;
6735
}
68-
std::optional<StringRef> getAttributeString(unsigned tag) const {
69-
auto I = attributesStr.find(tag);
70-
if (I == attributesStr.end())
71-
return std::nullopt;
72-
return I->second;
36+
virtual std::optional<StringRef> getAttributeString(unsigned Tag) const {
37+
return std::nullopt;
7338
}
7439
};
7540

7641
} // namespace llvm
77-
#endif
42+
#endif // LLVM_SUPPORT_ELFATTRIBUTEPARSER_H

llvm/include/llvm/Support/ELFAttributes.h

+29
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,42 @@
1515

1616
namespace llvm {
1717

18+
// Tag to string: ELF compact build attribute section
1819
struct TagNameItem {
1920
unsigned attr;
2021
StringRef tagName;
2122
};
2223

2324
using TagNameMap = ArrayRef<TagNameItem>;
2425

26+
// Build Attribute storage for ELF extended attribute section
27+
struct BuildAttributeItem {
28+
enum Types : uint8_t {
29+
NumericAttribute = 0,
30+
TextAttribute,
31+
} Type;
32+
unsigned Tag;
33+
unsigned IntValue;
34+
std::string StringValue;
35+
BuildAttributeItem(Types Ty, unsigned Tg, unsigned IV, std::string SV)
36+
: Type(Ty), Tag(Tg), IntValue(IV), StringValue(std::move(SV)) {}
37+
};
38+
struct BuildAttributeSubSection {
39+
StringRef Name;
40+
unsigned IsOptional;
41+
unsigned ParameterType;
42+
SmallVector<BuildAttributeItem, 64> Content;
43+
};
44+
45+
// Tag to string: ELF extended build attribute section
46+
struct SubsectionAndTagToTagName {
47+
StringRef SubsectionName;
48+
unsigned Tag;
49+
StringRef TagName;
50+
SubsectionAndTagToTagName(StringRef SN, unsigned Tg, StringRef TN)
51+
: SubsectionName(SN), Tag(Tg), TagName(TN) {}
52+
};
53+
2554
namespace ELFAttrs {
2655

2756
enum AttrType : unsigned { File = 1, Section = 2, Symbol = 3 };

0 commit comments

Comments
 (0)