Skip to content

Commit f3a8056

Browse files
committed
[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.
1 parent d21b2e6 commit f3a8056

34 files changed

+713
-266
lines changed

lld/ELF/Arch/RISCV.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,7 @@ mergeAttributesSection(Ctx &ctx,
11751175
switch (RISCVAttrs::AttrType(tag.attr)) {
11761176
// Integer attributes.
11771177
case RISCVAttrs::STACK_ALIGN:
1178-
if (auto i = parser.getAttributeValue(tag.attr)) {
1178+
if (auto i = parser.getAttributeValue("", tag.attr)) {
11791179
auto r = merged.intAttr.try_emplace(tag.attr, *i);
11801180
if (r.second) {
11811181
firstStackAlign = sec;
@@ -1188,13 +1188,13 @@ mergeAttributesSection(Ctx &ctx,
11881188
}
11891189
continue;
11901190
case RISCVAttrs::UNALIGNED_ACCESS:
1191-
if (auto i = parser.getAttributeValue(tag.attr))
1191+
if (auto i = parser.getAttributeValue("", tag.attr))
11921192
merged.intAttr[tag.attr] |= *i;
11931193
continue;
11941194

11951195
// String attributes.
11961196
case RISCVAttrs::ARCH:
1197-
if (auto s = parser.getAttributeString(tag.attr)) {
1197+
if (auto s = parser.getAttributeString("", tag.attr)) {
11981198
hasArch = true;
11991199
mergeArch(ctx, exts, xlen, sec, *s);
12001200
}
@@ -1207,7 +1207,7 @@ mergeAttributesSection(Ctx &ctx,
12071207
break;
12081208

12091209
case RISCVAttrs::AttrType::ATOMIC_ABI:
1210-
if (auto i = parser.getAttributeValue(tag.attr)) {
1210+
if (auto i = parser.getAttributeValue("", tag.attr)) {
12111211
auto r = merged.intAttr.try_emplace(tag.attr, *i);
12121212
if (r.second)
12131213
firstAtomicAbi = sec;
@@ -1225,12 +1225,12 @@ mergeAttributesSection(Ctx &ctx,
12251225
// TODO Adjust after resolution to
12261226
// https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/352
12271227
if (tag.attr % 2 == 0) {
1228-
if (auto i = parser.getAttributeValue(tag.attr)) {
1228+
if (auto i = parser.getAttributeValue("", tag.attr)) {
12291229
auto r = merged.intAttr.try_emplace(tag.attr, *i);
12301230
if (!r.second && r.first->second != *i)
12311231
r.first->second = 0;
12321232
}
1233-
} else if (auto s = parser.getAttributeString(tag.attr)) {
1233+
} else if (auto s = parser.getAttributeString("", tag.attr)) {
12341234
auto r = merged.strAttr.try_emplace(tag.attr, *s);
12351235
if (!r.second && r.first->second != *s)
12361236
r.first->second = {};

lld/ELF/InputFiles.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ static ELFKind getELFKind(Ctx &ctx, MemoryBufferRef mb, StringRef archiveName) {
107107
static void updateARMVFPArgs(Ctx &ctx, const ARMAttributeParser &attributes,
108108
const InputFile *f) {
109109
std::optional<unsigned> attr =
110-
attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args);
110+
attributes.getAttributeValue("", ARMBuildAttrs::ABI_VFP_args);
111111
if (!attr)
112112
// If an ABI tag isn't present then it is implicitly given the value of 0
113113
// which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files,
@@ -155,7 +155,7 @@ static void updateARMVFPArgs(Ctx &ctx, const ARMAttributeParser &attributes,
155155
static void updateSupportedARMFeatures(Ctx &ctx,
156156
const ARMAttributeParser &attributes) {
157157
std::optional<unsigned> attr =
158-
attributes.getAttributeValue(ARMBuildAttrs::CPU_arch);
158+
attributes.getAttributeValue("", ARMBuildAttrs::CPU_arch);
159159
if (!attr)
160160
return;
161161
auto arch = *attr;
@@ -189,7 +189,7 @@ static void updateSupportedARMFeatures(Ctx &ctx,
189189

190190
// Only ARMv8-M or later architectures have CMSE support.
191191
std::optional<unsigned> profile =
192-
attributes.getAttributeValue(ARMBuildAttrs::CPU_arch_profile);
192+
attributes.getAttributeValue("", ARMBuildAttrs::CPU_arch_profile);
193193
if (!profile)
194194
return;
195195
if (arch >= ARMBuildAttrs::CPUArch::v8_M_Base &&
@@ -200,9 +200,9 @@ static void updateSupportedARMFeatures(Ctx &ctx,
200200
// For now, let's limit it to ones where ARM isn't available and we know have
201201
// Thumb2.
202202
std::optional<unsigned> armISA =
203-
attributes.getAttributeValue(ARMBuildAttrs::ARM_ISA_use);
203+
attributes.getAttributeValue("", ARMBuildAttrs::ARM_ISA_use);
204204
std::optional<unsigned> thumb =
205-
attributes.getAttributeValue(ARMBuildAttrs::THUMB_ISA_use);
205+
attributes.getAttributeValue("", ARMBuildAttrs::THUMB_ISA_use);
206206
ctx.arg.armHasArmISA |= armISA && *armISA >= ARMBuildAttrs::Allowed;
207207
ctx.arg.armHasThumb2ISA |= thumb && *thumb >= ARMBuildAttrs::AllowThumb32;
208208
}

llvm/include/llvm/Object/ELFObjectFile.h

Lines changed: 3 additions & 0 deletions
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;
Lines changed: 29 additions & 0 deletions
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 const 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

Lines changed: 2 additions & 2 deletions
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

7575
#endif // LLVM_SUPPORT_AARCH64BUILDATTRIBUTES_H

llvm/include/llvm/Support/ARMAttributeParser.h

Lines changed: 5 additions & 4 deletions
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

Lines changed: 4 additions & 4 deletions
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
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
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>
64+
getAttributeValue(StringRef buildAttributeSubsectionName,
65+
unsigned tag) const override {
66+
auto I = attributes.find(tag);
67+
if (I == attributes.end())
68+
return std::nullopt;
69+
return I->second;
70+
}
71+
std::optional<StringRef>
72+
getAttributeString(StringRef buildAttributeSubsectionName,
73+
unsigned tag) const override {
74+
auto I = attributesStr.find(tag);
75+
if (I == attributesStr.end())
76+
return std::nullopt;
77+
return I->second;
78+
}
79+
};
80+
81+
} // namespace llvm
82+
#endif // LLVM_SUPPORT_ELFCOMPACTATTRPARSER_H
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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, 64> SubSectionVec;
32+
// Maps SubsectionName + Tag to tags names. Required for printing comments.
33+
const std::vector<SubsectionAndTagToTagName> TagsNamesMap;
34+
StringRef getTagName(const StringRef &s, const unsigned i);
35+
36+
public:
37+
Error parse(ArrayRef<uint8_t> Section, llvm::endianness Endian) override;
38+
39+
std::optional<unsigned> getAttributeValue(StringRef BuildAttrSubsectionName,
40+
unsigned Tag) const override;
41+
std::optional<StringRef> getAttributeString(StringRef BuildAttrSubsectionName,
42+
unsigned Tag) const override;
43+
44+
ELFExtendedAttrParser(ScopedPrinter *Sw,
45+
std::vector<SubsectionAndTagToTagName> TagsNamesMap)
46+
: Sw(Sw), TagsNamesMap(TagsNamesMap) {}
47+
ELFExtendedAttrParser(std::vector<SubsectionAndTagToTagName> TagsNamesMap)
48+
: Sw(nullptr), TagsNamesMap(TagsNamesMap) {}
49+
};
50+
} // namespace llvm
51+
#endif // LLVM_SUPPORT_ELFEXTENDEDATTRPARSER_H

0 commit comments

Comments
 (0)