1097a140dSpatrick //===- ARMAttributeParser.cpp - ARM Attribute Information Printer ---------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick
909467b48Spatrick #include "llvm/Support/ARMAttributeParser.h"
1009467b48Spatrick #include "llvm/ADT/StringExtras.h"
11*d415bd75Srobert #include "llvm/Support/ARMBuildAttributes.h"
12097a140dSpatrick #include "llvm/Support/Errc.h"
1309467b48Spatrick #include "llvm/Support/ScopedPrinter.h"
14*d415bd75Srobert #include <optional>
1509467b48Spatrick
1609467b48Spatrick using namespace llvm;
1709467b48Spatrick using namespace llvm::ARMBuildAttrs;
1809467b48Spatrick
19097a140dSpatrick #define ATTRIBUTE_HANDLER(attr) \
20097a140dSpatrick { ARMBuildAttrs::attr, &ARMAttributeParser::attr }
2109467b48Spatrick
22097a140dSpatrick const ARMAttributeParser::DisplayHandler ARMAttributeParser::displayRoutines[] =
23097a140dSpatrick {
24097a140dSpatrick {ARMBuildAttrs::CPU_raw_name, &ARMAttributeParser::stringAttribute},
25097a140dSpatrick {ARMBuildAttrs::CPU_name, &ARMAttributeParser::stringAttribute},
2609467b48Spatrick ATTRIBUTE_HANDLER(CPU_arch),
2709467b48Spatrick ATTRIBUTE_HANDLER(CPU_arch_profile),
2809467b48Spatrick ATTRIBUTE_HANDLER(ARM_ISA_use),
2909467b48Spatrick ATTRIBUTE_HANDLER(THUMB_ISA_use),
3009467b48Spatrick ATTRIBUTE_HANDLER(FP_arch),
3109467b48Spatrick ATTRIBUTE_HANDLER(WMMX_arch),
3209467b48Spatrick ATTRIBUTE_HANDLER(Advanced_SIMD_arch),
3309467b48Spatrick ATTRIBUTE_HANDLER(MVE_arch),
3409467b48Spatrick ATTRIBUTE_HANDLER(PCS_config),
3509467b48Spatrick ATTRIBUTE_HANDLER(ABI_PCS_R9_use),
3609467b48Spatrick ATTRIBUTE_HANDLER(ABI_PCS_RW_data),
3709467b48Spatrick ATTRIBUTE_HANDLER(ABI_PCS_RO_data),
3809467b48Spatrick ATTRIBUTE_HANDLER(ABI_PCS_GOT_use),
3909467b48Spatrick ATTRIBUTE_HANDLER(ABI_PCS_wchar_t),
4009467b48Spatrick ATTRIBUTE_HANDLER(ABI_FP_rounding),
4109467b48Spatrick ATTRIBUTE_HANDLER(ABI_FP_denormal),
4209467b48Spatrick ATTRIBUTE_HANDLER(ABI_FP_exceptions),
4309467b48Spatrick ATTRIBUTE_HANDLER(ABI_FP_user_exceptions),
4409467b48Spatrick ATTRIBUTE_HANDLER(ABI_FP_number_model),
4509467b48Spatrick ATTRIBUTE_HANDLER(ABI_align_needed),
4609467b48Spatrick ATTRIBUTE_HANDLER(ABI_align_preserved),
4709467b48Spatrick ATTRIBUTE_HANDLER(ABI_enum_size),
4809467b48Spatrick ATTRIBUTE_HANDLER(ABI_HardFP_use),
4909467b48Spatrick ATTRIBUTE_HANDLER(ABI_VFP_args),
5009467b48Spatrick ATTRIBUTE_HANDLER(ABI_WMMX_args),
5109467b48Spatrick ATTRIBUTE_HANDLER(ABI_optimization_goals),
5209467b48Spatrick ATTRIBUTE_HANDLER(ABI_FP_optimization_goals),
5309467b48Spatrick ATTRIBUTE_HANDLER(compatibility),
5409467b48Spatrick ATTRIBUTE_HANDLER(CPU_unaligned_access),
5509467b48Spatrick ATTRIBUTE_HANDLER(FP_HP_extension),
5609467b48Spatrick ATTRIBUTE_HANDLER(ABI_FP_16bit_format),
5709467b48Spatrick ATTRIBUTE_HANDLER(MPextension_use),
5809467b48Spatrick ATTRIBUTE_HANDLER(DIV_use),
5909467b48Spatrick ATTRIBUTE_HANDLER(DSP_extension),
6009467b48Spatrick ATTRIBUTE_HANDLER(T2EE_use),
6109467b48Spatrick ATTRIBUTE_HANDLER(Virtualization_use),
62*d415bd75Srobert ATTRIBUTE_HANDLER(PAC_extension),
63*d415bd75Srobert ATTRIBUTE_HANDLER(BTI_extension),
64*d415bd75Srobert ATTRIBUTE_HANDLER(PACRET_use),
65*d415bd75Srobert ATTRIBUTE_HANDLER(BTI_use),
66097a140dSpatrick ATTRIBUTE_HANDLER(nodefaults),
67*d415bd75Srobert ATTRIBUTE_HANDLER(also_compatible_with),
6809467b48Spatrick };
6909467b48Spatrick
7009467b48Spatrick #undef ATTRIBUTE_HANDLER
7109467b48Spatrick
stringAttribute(AttrType tag)72097a140dSpatrick Error ARMAttributeParser::stringAttribute(AttrType tag) {
73097a140dSpatrick StringRef tagName =
74*d415bd75Srobert ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false);
75097a140dSpatrick StringRef desc = de.getCStrRef(cursor);
76097a140dSpatrick
77097a140dSpatrick if (sw) {
78097a140dSpatrick DictScope scope(*sw, "Attribute");
79097a140dSpatrick sw->printNumber("Tag", tag);
80097a140dSpatrick if (!tagName.empty())
81097a140dSpatrick sw->printString("TagName", tagName);
82097a140dSpatrick sw->printString("Value", desc);
83097a140dSpatrick }
84097a140dSpatrick return Error::success();
8509467b48Spatrick }
8609467b48Spatrick
87*d415bd75Srobert static const char *CPU_arch_strings[] = {
88*d415bd75Srobert "Pre-v4", "ARM v4", "ARM v4T", "ARM v5T", "ARM v5TE", "ARM v5TEJ",
89*d415bd75Srobert "ARM v6", "ARM v6KZ", "ARM v6T2", "ARM v6K", "ARM v7", "ARM v6-M",
90*d415bd75Srobert "ARM v6S-M", "ARM v7E-M", "ARM v8-A", "ARM v8-R", "ARM v8-M Baseline",
91*d415bd75Srobert "ARM v8-M Mainline", nullptr, nullptr, nullptr, "ARM v8.1-M Mainline",
92*d415bd75Srobert "ARM v9-A"};
93*d415bd75Srobert
CPU_arch(AttrType tag)94097a140dSpatrick Error ARMAttributeParser::CPU_arch(AttrType tag) {
95*d415bd75Srobert return parseStringAttribute("CPU_arch", tag, ArrayRef(CPU_arch_strings));
9609467b48Spatrick }
9709467b48Spatrick
CPU_arch_profile(AttrType tag)98097a140dSpatrick Error ARMAttributeParser::CPU_arch_profile(AttrType tag) {
99097a140dSpatrick uint64_t value = de.getULEB128(cursor);
10009467b48Spatrick
101097a140dSpatrick StringRef profile;
102097a140dSpatrick switch (value) {
103097a140dSpatrick default: profile = "Unknown"; break;
104097a140dSpatrick case 'A': profile = "Application"; break;
105097a140dSpatrick case 'R': profile = "Real-time"; break;
106097a140dSpatrick case 'M': profile = "Microcontroller"; break;
107097a140dSpatrick case 'S': profile = "Classic"; break;
108097a140dSpatrick case 0: profile = "None"; break;
10909467b48Spatrick }
11009467b48Spatrick
111097a140dSpatrick printAttribute(tag, value, profile);
112097a140dSpatrick return Error::success();
11309467b48Spatrick }
11409467b48Spatrick
ARM_ISA_use(AttrType tag)115097a140dSpatrick Error ARMAttributeParser::ARM_ISA_use(AttrType tag) {
116097a140dSpatrick static const char *strings[] = {"Not Permitted", "Permitted"};
117*d415bd75Srobert return parseStringAttribute("ARM_ISA_use", tag, ArrayRef(strings));
11809467b48Spatrick }
11909467b48Spatrick
THUMB_ISA_use(AttrType tag)120097a140dSpatrick Error ARMAttributeParser::THUMB_ISA_use(AttrType tag) {
12173471bf0Spatrick static const char *strings[] = {"Not Permitted", "Thumb-1", "Thumb-2", "Permitted"};
122*d415bd75Srobert return parseStringAttribute("THUMB_ISA_use", tag, ArrayRef(strings));
12309467b48Spatrick }
12409467b48Spatrick
FP_arch(AttrType tag)125097a140dSpatrick Error ARMAttributeParser::FP_arch(AttrType tag) {
126097a140dSpatrick static const char *strings[] = {
127097a140dSpatrick "Not Permitted", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16",
128097a140dSpatrick "VFPv4", "VFPv4-D16", "ARMv8-a FP", "ARMv8-a FP-D16"};
129*d415bd75Srobert return parseStringAttribute("FP_arch", tag, ArrayRef(strings));
13009467b48Spatrick }
13109467b48Spatrick
WMMX_arch(AttrType tag)132097a140dSpatrick Error ARMAttributeParser::WMMX_arch(AttrType tag) {
133097a140dSpatrick static const char *strings[] = {"Not Permitted", "WMMXv1", "WMMXv2"};
134*d415bd75Srobert return parseStringAttribute("WMMX_arch", tag, ArrayRef(strings));
13509467b48Spatrick }
13609467b48Spatrick
Advanced_SIMD_arch(AttrType tag)137097a140dSpatrick Error ARMAttributeParser::Advanced_SIMD_arch(AttrType tag) {
138097a140dSpatrick static const char *strings[] = {"Not Permitted", "NEONv1", "NEONv2+FMA",
139097a140dSpatrick "ARMv8-a NEON", "ARMv8.1-a NEON"};
140*d415bd75Srobert return parseStringAttribute("Advanced_SIMD_arch", tag, ArrayRef(strings));
14109467b48Spatrick }
14209467b48Spatrick
MVE_arch(AttrType tag)143097a140dSpatrick Error ARMAttributeParser::MVE_arch(AttrType tag) {
144097a140dSpatrick static const char *strings[] = {"Not Permitted", "MVE integer",
145097a140dSpatrick "MVE integer and float"};
146*d415bd75Srobert return parseStringAttribute("MVE_arch", tag, ArrayRef(strings));
14709467b48Spatrick }
14809467b48Spatrick
PCS_config(AttrType tag)149097a140dSpatrick Error ARMAttributeParser::PCS_config(AttrType tag) {
150097a140dSpatrick static const char *strings[] = {
15109467b48Spatrick "None", "Bare Platform", "Linux Application", "Linux DSO", "Palm OS 2004",
152097a140dSpatrick "Reserved (Palm OS)", "Symbian OS 2004", "Reserved (Symbian OS)"};
153*d415bd75Srobert return parseStringAttribute("PCS_config", tag, ArrayRef(strings));
15409467b48Spatrick }
15509467b48Spatrick
ABI_PCS_R9_use(AttrType tag)156097a140dSpatrick Error ARMAttributeParser::ABI_PCS_R9_use(AttrType tag) {
157097a140dSpatrick static const char *strings[] = {"v6", "Static Base", "TLS", "Unused"};
158*d415bd75Srobert return parseStringAttribute("ABI_PCS_R9_use", tag, ArrayRef(strings));
15909467b48Spatrick }
16009467b48Spatrick
ABI_PCS_RW_data(AttrType tag)161097a140dSpatrick Error ARMAttributeParser::ABI_PCS_RW_data(AttrType tag) {
162097a140dSpatrick static const char *strings[] = {"Absolute", "PC-relative", "SB-relative",
163097a140dSpatrick "Not Permitted"};
164*d415bd75Srobert return parseStringAttribute("ABI_PCS_RW_data", tag, ArrayRef(strings));
16509467b48Spatrick }
16609467b48Spatrick
ABI_PCS_RO_data(AttrType tag)167097a140dSpatrick Error ARMAttributeParser::ABI_PCS_RO_data(AttrType tag) {
168097a140dSpatrick static const char *strings[] = {"Absolute", "PC-relative", "Not Permitted"};
169*d415bd75Srobert return parseStringAttribute("ABI_PCS_RO_data", tag, ArrayRef(strings));
17009467b48Spatrick }
17109467b48Spatrick
ABI_PCS_GOT_use(AttrType tag)172097a140dSpatrick Error ARMAttributeParser::ABI_PCS_GOT_use(AttrType tag) {
173097a140dSpatrick static const char *strings[] = {"Not Permitted", "Direct", "GOT-Indirect"};
174*d415bd75Srobert return parseStringAttribute("ABI_PCS_GOT_use", tag, ArrayRef(strings));
17509467b48Spatrick }
17609467b48Spatrick
ABI_PCS_wchar_t(AttrType tag)177097a140dSpatrick Error ARMAttributeParser::ABI_PCS_wchar_t(AttrType tag) {
178097a140dSpatrick static const char *strings[] = {"Not Permitted", "Unknown", "2-byte",
179097a140dSpatrick "Unknown", "4-byte"};
180*d415bd75Srobert return parseStringAttribute("ABI_PCS_wchar_t", tag, ArrayRef(strings));
18109467b48Spatrick }
18209467b48Spatrick
ABI_FP_rounding(AttrType tag)183097a140dSpatrick Error ARMAttributeParser::ABI_FP_rounding(AttrType tag) {
184097a140dSpatrick static const char *strings[] = {"IEEE-754", "Runtime"};
185*d415bd75Srobert return parseStringAttribute("ABI_FP_rounding", tag, ArrayRef(strings));
18609467b48Spatrick }
18709467b48Spatrick
ABI_FP_denormal(AttrType tag)188097a140dSpatrick Error ARMAttributeParser::ABI_FP_denormal(AttrType tag) {
189097a140dSpatrick static const char *strings[] = {"Unsupported", "IEEE-754", "Sign Only"};
190*d415bd75Srobert return parseStringAttribute("ABI_FP_denormal", tag, ArrayRef(strings));
19109467b48Spatrick }
19209467b48Spatrick
ABI_FP_exceptions(AttrType tag)193097a140dSpatrick Error ARMAttributeParser::ABI_FP_exceptions(AttrType tag) {
194097a140dSpatrick static const char *strings[] = {"Not Permitted", "IEEE-754"};
195*d415bd75Srobert return parseStringAttribute("ABI_FP_exceptions", tag, ArrayRef(strings));
196097a140dSpatrick }
ABI_FP_user_exceptions(AttrType tag)197097a140dSpatrick Error ARMAttributeParser::ABI_FP_user_exceptions(AttrType tag) {
198097a140dSpatrick static const char *strings[] = {"Not Permitted", "IEEE-754"};
199*d415bd75Srobert return parseStringAttribute("ABI_FP_user_exceptions", tag, ArrayRef(strings));
20009467b48Spatrick }
20109467b48Spatrick
ABI_FP_number_model(AttrType tag)202097a140dSpatrick Error ARMAttributeParser::ABI_FP_number_model(AttrType tag) {
203097a140dSpatrick static const char *strings[] = {"Not Permitted", "Finite Only", "RTABI",
204097a140dSpatrick "IEEE-754"};
205*d415bd75Srobert return parseStringAttribute("ABI_FP_number_model", tag, ArrayRef(strings));
20609467b48Spatrick }
20709467b48Spatrick
ABI_align_needed(AttrType tag)208097a140dSpatrick Error ARMAttributeParser::ABI_align_needed(AttrType tag) {
209097a140dSpatrick static const char *strings[] = {"Not Permitted", "8-byte alignment",
210097a140dSpatrick "4-byte alignment", "Reserved"};
21109467b48Spatrick
212097a140dSpatrick uint64_t value = de.getULEB128(cursor);
21309467b48Spatrick
214097a140dSpatrick std::string description;
215*d415bd75Srobert if (value < std::size(strings))
216097a140dSpatrick description = strings[value];
217097a140dSpatrick else if (value <= 12)
218097a140dSpatrick description = "8-byte alignment, " + utostr(1ULL << value) +
219097a140dSpatrick "-byte extended alignment";
22009467b48Spatrick else
221097a140dSpatrick description = "Invalid";
22209467b48Spatrick
223097a140dSpatrick printAttribute(tag, value, description);
224097a140dSpatrick return Error::success();
22509467b48Spatrick }
22609467b48Spatrick
ABI_align_preserved(AttrType tag)227097a140dSpatrick Error ARMAttributeParser::ABI_align_preserved(AttrType tag) {
228097a140dSpatrick static const char *strings[] = {"Not Required", "8-byte data alignment",
229097a140dSpatrick "8-byte data and code alignment", "Reserved"};
23009467b48Spatrick
231097a140dSpatrick uint64_t value = de.getULEB128(cursor);
23209467b48Spatrick
233097a140dSpatrick std::string description;
234*d415bd75Srobert if (value < std::size(strings))
235097a140dSpatrick description = std::string(strings[value]);
236097a140dSpatrick else if (value <= 12)
237097a140dSpatrick description = std::string("8-byte stack alignment, ") +
238097a140dSpatrick utostr(1ULL << value) + std::string("-byte data alignment");
23909467b48Spatrick else
240097a140dSpatrick description = "Invalid";
24109467b48Spatrick
242097a140dSpatrick printAttribute(tag, value, description);
243097a140dSpatrick return Error::success();
24409467b48Spatrick }
24509467b48Spatrick
ABI_enum_size(AttrType tag)246097a140dSpatrick Error ARMAttributeParser::ABI_enum_size(AttrType tag) {
247097a140dSpatrick static const char *strings[] = {"Not Permitted", "Packed", "Int32",
248097a140dSpatrick "External Int32"};
249*d415bd75Srobert return parseStringAttribute("ABI_enum_size", tag, ArrayRef(strings));
25009467b48Spatrick }
25109467b48Spatrick
ABI_HardFP_use(AttrType tag)252097a140dSpatrick Error ARMAttributeParser::ABI_HardFP_use(AttrType tag) {
253097a140dSpatrick static const char *strings[] = {"Tag_FP_arch", "Single-Precision", "Reserved",
254097a140dSpatrick "Tag_FP_arch (deprecated)"};
255*d415bd75Srobert return parseStringAttribute("ABI_HardFP_use", tag, ArrayRef(strings));
25609467b48Spatrick }
25709467b48Spatrick
ABI_VFP_args(AttrType tag)258097a140dSpatrick Error ARMAttributeParser::ABI_VFP_args(AttrType tag) {
259097a140dSpatrick static const char *strings[] = {"AAPCS", "AAPCS VFP", "Custom",
260097a140dSpatrick "Not Permitted"};
261*d415bd75Srobert return parseStringAttribute("ABI_VFP_args", tag, ArrayRef(strings));
26209467b48Spatrick }
26309467b48Spatrick
ABI_WMMX_args(AttrType tag)264097a140dSpatrick Error ARMAttributeParser::ABI_WMMX_args(AttrType tag) {
265097a140dSpatrick static const char *strings[] = {"AAPCS", "iWMMX", "Custom"};
266*d415bd75Srobert return parseStringAttribute("ABI_WMMX_args", tag, ArrayRef(strings));
26709467b48Spatrick }
26809467b48Spatrick
ABI_optimization_goals(AttrType tag)269097a140dSpatrick Error ARMAttributeParser::ABI_optimization_goals(AttrType tag) {
270097a140dSpatrick static const char *strings[] = {
27109467b48Spatrick "None", "Speed", "Aggressive Speed", "Size", "Aggressive Size", "Debugging",
27209467b48Spatrick "Best Debugging"
27309467b48Spatrick };
274*d415bd75Srobert return parseStringAttribute("ABI_optimization_goals", tag, ArrayRef(strings));
27509467b48Spatrick }
27609467b48Spatrick
ABI_FP_optimization_goals(AttrType tag)277097a140dSpatrick Error ARMAttributeParser::ABI_FP_optimization_goals(AttrType tag) {
278097a140dSpatrick static const char *strings[] = {
279097a140dSpatrick "None", "Speed", "Aggressive Speed", "Size", "Aggressive Size",
280097a140dSpatrick "Accuracy", "Best Accuracy"};
281097a140dSpatrick return parseStringAttribute("ABI_FP_optimization_goals", tag,
282*d415bd75Srobert ArrayRef(strings));
28309467b48Spatrick }
28409467b48Spatrick
compatibility(AttrType tag)285097a140dSpatrick Error ARMAttributeParser::compatibility(AttrType tag) {
286097a140dSpatrick uint64_t integer = de.getULEB128(cursor);
287097a140dSpatrick StringRef string = de.getCStrRef(cursor);
28809467b48Spatrick
289097a140dSpatrick if (sw) {
290097a140dSpatrick DictScope scope(*sw, "Attribute");
291097a140dSpatrick sw->printNumber("Tag", tag);
292097a140dSpatrick sw->startLine() << "Value: " << integer << ", " << string << '\n';
293097a140dSpatrick sw->printString("TagName",
294097a140dSpatrick ELFAttrs::attrTypeAsString(tag, tagToStringMap,
295097a140dSpatrick /*hasTagPrefix=*/false));
296097a140dSpatrick switch (integer) {
29709467b48Spatrick case 0:
298097a140dSpatrick sw->printString("Description", StringRef("No Specific Requirements"));
29909467b48Spatrick break;
30009467b48Spatrick case 1:
301097a140dSpatrick sw->printString("Description", StringRef("AEABI Conformant"));
30209467b48Spatrick break;
30309467b48Spatrick default:
304097a140dSpatrick sw->printString("Description", StringRef("AEABI Non-Conformant"));
30509467b48Spatrick break;
30609467b48Spatrick }
30709467b48Spatrick }
308097a140dSpatrick return Error::success();
30909467b48Spatrick }
31009467b48Spatrick
CPU_unaligned_access(AttrType tag)311097a140dSpatrick Error ARMAttributeParser::CPU_unaligned_access(AttrType tag) {
312097a140dSpatrick static const char *strings[] = {"Not Permitted", "v6-style"};
313*d415bd75Srobert return parseStringAttribute("CPU_unaligned_access", tag, ArrayRef(strings));
31409467b48Spatrick }
31509467b48Spatrick
FP_HP_extension(AttrType tag)316097a140dSpatrick Error ARMAttributeParser::FP_HP_extension(AttrType tag) {
317097a140dSpatrick static const char *strings[] = {"If Available", "Permitted"};
318*d415bd75Srobert return parseStringAttribute("FP_HP_extension", tag, ArrayRef(strings));
31909467b48Spatrick }
32009467b48Spatrick
ABI_FP_16bit_format(AttrType tag)321097a140dSpatrick Error ARMAttributeParser::ABI_FP_16bit_format(AttrType tag) {
322097a140dSpatrick static const char *strings[] = {"Not Permitted", "IEEE-754", "VFPv3"};
323*d415bd75Srobert return parseStringAttribute("ABI_FP_16bit_format", tag, ArrayRef(strings));
32409467b48Spatrick }
32509467b48Spatrick
MPextension_use(AttrType tag)326097a140dSpatrick Error ARMAttributeParser::MPextension_use(AttrType tag) {
327097a140dSpatrick static const char *strings[] = {"Not Permitted", "Permitted"};
328*d415bd75Srobert return parseStringAttribute("MPextension_use", tag, ArrayRef(strings));
32909467b48Spatrick }
33009467b48Spatrick
DIV_use(AttrType tag)331097a140dSpatrick Error ARMAttributeParser::DIV_use(AttrType tag) {
332097a140dSpatrick static const char *strings[] = {"If Available", "Not Permitted", "Permitted"};
333*d415bd75Srobert return parseStringAttribute("DIV_use", tag, ArrayRef(strings));
33409467b48Spatrick }
33509467b48Spatrick
DSP_extension(AttrType tag)336097a140dSpatrick Error ARMAttributeParser::DSP_extension(AttrType tag) {
337097a140dSpatrick static const char *strings[] = {"Not Permitted", "Permitted"};
338*d415bd75Srobert return parseStringAttribute("DSP_extension", tag, ArrayRef(strings));
33909467b48Spatrick }
34009467b48Spatrick
T2EE_use(AttrType tag)341097a140dSpatrick Error ARMAttributeParser::T2EE_use(AttrType tag) {
342097a140dSpatrick static const char *strings[] = {"Not Permitted", "Permitted"};
343*d415bd75Srobert return parseStringAttribute("T2EE_use", tag, ArrayRef(strings));
34409467b48Spatrick }
34509467b48Spatrick
Virtualization_use(AttrType tag)346097a140dSpatrick Error ARMAttributeParser::Virtualization_use(AttrType tag) {
347097a140dSpatrick static const char *strings[] = {"Not Permitted", "TrustZone",
348097a140dSpatrick "Virtualization Extensions",
349097a140dSpatrick "TrustZone + Virtualization Extensions"};
350*d415bd75Srobert return parseStringAttribute("Virtualization_use", tag, ArrayRef(strings));
351*d415bd75Srobert }
352*d415bd75Srobert
PAC_extension(ARMBuildAttrs::AttrType tag)353*d415bd75Srobert Error ARMAttributeParser::PAC_extension(ARMBuildAttrs::AttrType tag) {
354*d415bd75Srobert static const char *strings[] = {"Not Permitted", "Permitted in NOP space",
355*d415bd75Srobert "Permitted"};
356*d415bd75Srobert return parseStringAttribute("PAC_extension", tag, ArrayRef(strings));
357*d415bd75Srobert }
358*d415bd75Srobert
BTI_extension(ARMBuildAttrs::AttrType tag)359*d415bd75Srobert Error ARMAttributeParser::BTI_extension(ARMBuildAttrs::AttrType tag) {
360*d415bd75Srobert static const char *strings[] = {"Not Permitted", "Permitted in NOP space",
361*d415bd75Srobert "Permitted"};
362*d415bd75Srobert return parseStringAttribute("BTI_extension", tag, ArrayRef(strings));
363*d415bd75Srobert }
364*d415bd75Srobert
PACRET_use(ARMBuildAttrs::AttrType tag)365*d415bd75Srobert Error ARMAttributeParser::PACRET_use(ARMBuildAttrs::AttrType tag) {
366*d415bd75Srobert static const char *strings[] = {"Not Used", "Used"};
367*d415bd75Srobert return parseStringAttribute("PACRET_use", tag, ArrayRef(strings));
368*d415bd75Srobert }
369*d415bd75Srobert
BTI_use(ARMBuildAttrs::AttrType tag)370*d415bd75Srobert Error ARMAttributeParser::BTI_use(ARMBuildAttrs::AttrType tag) {
371*d415bd75Srobert static const char *strings[] = {"Not Used", "Used"};
372*d415bd75Srobert return parseStringAttribute("BTI_use", tag, ArrayRef(strings));
37309467b48Spatrick }
37409467b48Spatrick
nodefaults(AttrType tag)375097a140dSpatrick Error ARMAttributeParser::nodefaults(AttrType tag) {
376097a140dSpatrick uint64_t value = de.getULEB128(cursor);
377097a140dSpatrick printAttribute(tag, value, "Unspecified Tags UNDEFINED");
378097a140dSpatrick return Error::success();
37909467b48Spatrick }
38009467b48Spatrick
also_compatible_with(AttrType tag)381*d415bd75Srobert Error ARMAttributeParser::also_compatible_with(AttrType tag) {
382*d415bd75Srobert // Parse value as a C string first in order to print it in escaped form later.
383*d415bd75Srobert // Then, parse it again to catch errors or to pretty print if Tag_CPU_arch.
384*d415bd75Srobert std::optional<Error> returnValue;
385*d415bd75Srobert
386*d415bd75Srobert SmallString<8> Description;
387*d415bd75Srobert raw_svector_ostream DescStream(Description);
388*d415bd75Srobert
389*d415bd75Srobert uint64_t InitialOffset = cursor.tell();
390*d415bd75Srobert StringRef RawStringValue = de.getCStrRef(cursor);
391*d415bd75Srobert uint64_t FinalOffset = cursor.tell();
392*d415bd75Srobert cursor.seek(InitialOffset);
393*d415bd75Srobert uint64_t InnerTag = de.getULEB128(cursor);
394*d415bd75Srobert
395*d415bd75Srobert bool ValidInnerTag =
396*d415bd75Srobert any_of(tagToStringMap, [InnerTag](const TagNameItem &Item) {
397*d415bd75Srobert return Item.attr == InnerTag;
398*d415bd75Srobert });
399*d415bd75Srobert
400*d415bd75Srobert if (!ValidInnerTag) {
401*d415bd75Srobert returnValue =
402*d415bd75Srobert createStringError(errc::argument_out_of_domain,
403*d415bd75Srobert Twine(InnerTag) + " is not a valid tag number");
404*d415bd75Srobert } else {
405*d415bd75Srobert switch (InnerTag) {
406*d415bd75Srobert case ARMBuildAttrs::CPU_arch: {
407*d415bd75Srobert uint64_t InnerValue = de.getULEB128(cursor);
408*d415bd75Srobert auto strings = ArrayRef(CPU_arch_strings);
409*d415bd75Srobert if (InnerValue >= strings.size()) {
410*d415bd75Srobert returnValue = createStringError(
411*d415bd75Srobert errc::argument_out_of_domain,
412*d415bd75Srobert Twine(InnerValue) + " is not a valid " +
413*d415bd75Srobert ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap) +
414*d415bd75Srobert " value");
415*d415bd75Srobert } else {
416*d415bd75Srobert DescStream << ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap)
417*d415bd75Srobert << " = " << InnerValue;
418*d415bd75Srobert if (strings[InnerValue])
419*d415bd75Srobert DescStream << " (" << strings[InnerValue] << ')';
420*d415bd75Srobert }
421*d415bd75Srobert break;
422*d415bd75Srobert }
423*d415bd75Srobert case ARMBuildAttrs::also_compatible_with:
424*d415bd75Srobert returnValue = createStringError(
425*d415bd75Srobert errc::invalid_argument,
426*d415bd75Srobert ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap) +
427*d415bd75Srobert " cannot be recursively defined");
428*d415bd75Srobert break;
429*d415bd75Srobert case ARMBuildAttrs::CPU_raw_name:
430*d415bd75Srobert case ARMBuildAttrs::CPU_name:
431*d415bd75Srobert case ARMBuildAttrs::compatibility:
432*d415bd75Srobert case ARMBuildAttrs::conformance: {
433*d415bd75Srobert StringRef InnerValue = de.getCStrRef(cursor);
434*d415bd75Srobert DescStream << ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap)
435*d415bd75Srobert << " = " << InnerValue;
436*d415bd75Srobert break;
437*d415bd75Srobert }
438*d415bd75Srobert default: {
439*d415bd75Srobert uint64_t InnerValue = de.getULEB128(cursor);
440*d415bd75Srobert DescStream << ELFAttrs::attrTypeAsString(InnerTag, tagToStringMap)
441*d415bd75Srobert << " = " << InnerValue;
442*d415bd75Srobert }
443*d415bd75Srobert }
444*d415bd75Srobert }
445*d415bd75Srobert
446*d415bd75Srobert setAttributeString(tag, RawStringValue);
447*d415bd75Srobert if (sw) {
448*d415bd75Srobert DictScope scope(*sw, "Attribute");
449*d415bd75Srobert sw->printNumber("Tag", tag);
450*d415bd75Srobert sw->printString("TagName",
451*d415bd75Srobert ELFAttrs::attrTypeAsString(tag, tagToStringMap, false));
452*d415bd75Srobert sw->printStringEscaped("Value", RawStringValue);
453*d415bd75Srobert if (!Description.empty()) {
454*d415bd75Srobert sw->printString("Description", Description);
455*d415bd75Srobert }
456*d415bd75Srobert }
457*d415bd75Srobert
458*d415bd75Srobert cursor.seek(FinalOffset);
459*d415bd75Srobert
460*d415bd75Srobert return returnValue ? std::move(*returnValue) : Error::success();
461*d415bd75Srobert }
462*d415bd75Srobert
handler(uint64_t tag,bool & handled)463097a140dSpatrick Error ARMAttributeParser::handler(uint64_t tag, bool &handled) {
464097a140dSpatrick handled = false;
465*d415bd75Srobert for (const auto &AH : displayRoutines) {
466*d415bd75Srobert if (uint64_t(AH.attribute) == tag) {
467*d415bd75Srobert if (Error e = (this->*AH.routine)(static_cast<AttrType>(tag)))
468097a140dSpatrick return e;
469097a140dSpatrick handled = true;
47009467b48Spatrick break;
47109467b48Spatrick }
47209467b48Spatrick }
47309467b48Spatrick
474097a140dSpatrick return Error::success();
47509467b48Spatrick }
476