xref: /aosp_15_r20/external/llvm/tools/llvm-readobj/ARMAttributeParser.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===--- ARMAttributeParser.cpp - ARM Attribute Information Printer -------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "ARMAttributeParser.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/LEB128.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ScopedPrinter.h"
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker using namespace llvm;
17*9880d681SAndroid Build Coastguard Worker using namespace llvm::ARMBuildAttrs;
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker 
20*9880d681SAndroid Build Coastguard Worker static const EnumEntry<unsigned> TagNames[] = {
21*9880d681SAndroid Build Coastguard Worker   { "Tag_File", ARMBuildAttrs::File },
22*9880d681SAndroid Build Coastguard Worker   { "Tag_Section", ARMBuildAttrs::Section },
23*9880d681SAndroid Build Coastguard Worker   { "Tag_Symbol", ARMBuildAttrs::Symbol },
24*9880d681SAndroid Build Coastguard Worker };
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker namespace llvm {
27*9880d681SAndroid Build Coastguard Worker #define ATTRIBUTE_HANDLER(Attr_)                                                \
28*9880d681SAndroid Build Coastguard Worker   { ARMBuildAttrs::Attr_, &ARMAttributeParser::Attr_ }
29*9880d681SAndroid Build Coastguard Worker 
30*9880d681SAndroid Build Coastguard Worker const ARMAttributeParser::DisplayHandler
31*9880d681SAndroid Build Coastguard Worker ARMAttributeParser::DisplayRoutines[] = {
32*9880d681SAndroid Build Coastguard Worker   { ARMBuildAttrs::CPU_raw_name, &ARMAttributeParser::StringAttribute, },
33*9880d681SAndroid Build Coastguard Worker   { ARMBuildAttrs::CPU_name, &ARMAttributeParser::StringAttribute },
34*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(CPU_arch),
35*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(CPU_arch_profile),
36*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ARM_ISA_use),
37*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(THUMB_ISA_use),
38*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(FP_arch),
39*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(WMMX_arch),
40*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(Advanced_SIMD_arch),
41*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(PCS_config),
42*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_PCS_R9_use),
43*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_PCS_RW_data),
44*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_PCS_RO_data),
45*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_PCS_GOT_use),
46*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_PCS_wchar_t),
47*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_FP_rounding),
48*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_FP_denormal),
49*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_FP_exceptions),
50*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_FP_user_exceptions),
51*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_FP_number_model),
52*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_align_needed),
53*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_align_preserved),
54*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_enum_size),
55*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_HardFP_use),
56*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_VFP_args),
57*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_WMMX_args),
58*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_optimization_goals),
59*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_FP_optimization_goals),
60*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(compatibility),
61*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(CPU_unaligned_access),
62*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(FP_HP_extension),
63*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(ABI_FP_16bit_format),
64*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(MPextension_use),
65*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(DIV_use),
66*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(DSP_extension),
67*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(T2EE_use),
68*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(Virtualization_use),
69*9880d681SAndroid Build Coastguard Worker   ATTRIBUTE_HANDLER(nodefaults)
70*9880d681SAndroid Build Coastguard Worker };
71*9880d681SAndroid Build Coastguard Worker 
72*9880d681SAndroid Build Coastguard Worker #undef ATTRIBUTE_HANDLER
73*9880d681SAndroid Build Coastguard Worker 
ParseInteger(const uint8_t * Data,uint32_t & Offset)74*9880d681SAndroid Build Coastguard Worker uint64_t ARMAttributeParser::ParseInteger(const uint8_t *Data,
75*9880d681SAndroid Build Coastguard Worker                                           uint32_t &Offset) {
76*9880d681SAndroid Build Coastguard Worker   unsigned Length;
77*9880d681SAndroid Build Coastguard Worker   uint64_t Value = decodeULEB128(Data + Offset, &Length);
78*9880d681SAndroid Build Coastguard Worker   Offset = Offset + Length;
79*9880d681SAndroid Build Coastguard Worker   return Value;
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker 
ParseString(const uint8_t * Data,uint32_t & Offset)82*9880d681SAndroid Build Coastguard Worker StringRef ARMAttributeParser::ParseString(const uint8_t *Data,
83*9880d681SAndroid Build Coastguard Worker                                           uint32_t &Offset) {
84*9880d681SAndroid Build Coastguard Worker   const char *String = reinterpret_cast<const char*>(Data + Offset);
85*9880d681SAndroid Build Coastguard Worker   size_t Length = std::strlen(String);
86*9880d681SAndroid Build Coastguard Worker   Offset = Offset + Length + 1;
87*9880d681SAndroid Build Coastguard Worker   return StringRef(String, Length);
88*9880d681SAndroid Build Coastguard Worker }
89*9880d681SAndroid Build Coastguard Worker 
IntegerAttribute(AttrType Tag,const uint8_t * Data,uint32_t & Offset)90*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::IntegerAttribute(AttrType Tag, const uint8_t *Data,
91*9880d681SAndroid Build Coastguard Worker                                           uint32_t &Offset) {
92*9880d681SAndroid Build Coastguard Worker   SW.printNumber(ARMBuildAttrs::AttrTypeAsString(Tag),
93*9880d681SAndroid Build Coastguard Worker                  ParseInteger(Data, Offset));
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker 
StringAttribute(AttrType Tag,const uint8_t * Data,uint32_t & Offset)96*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::StringAttribute(AttrType Tag, const uint8_t *Data,
97*9880d681SAndroid Build Coastguard Worker                                          uint32_t &Offset) {
98*9880d681SAndroid Build Coastguard Worker   StringRef TagName = ARMBuildAttrs::AttrTypeAsString(Tag, /*TagPrefix*/false);
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker   DictScope AS(SW, "Attribute");
101*9880d681SAndroid Build Coastguard Worker   SW.printNumber("Tag", Tag);
102*9880d681SAndroid Build Coastguard Worker   if (!TagName.empty())
103*9880d681SAndroid Build Coastguard Worker     SW.printString("TagName", TagName);
104*9880d681SAndroid Build Coastguard Worker   SW.printString("Value", ParseString(Data, Offset));
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker 
PrintAttribute(unsigned Tag,unsigned Value,StringRef ValueDesc)107*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::PrintAttribute(unsigned Tag, unsigned Value,
108*9880d681SAndroid Build Coastguard Worker                                         StringRef ValueDesc) {
109*9880d681SAndroid Build Coastguard Worker   StringRef TagName = ARMBuildAttrs::AttrTypeAsString(Tag, /*TagPrefix*/false);
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker   DictScope AS(SW, "Attribute");
112*9880d681SAndroid Build Coastguard Worker   SW.printNumber("Tag", Tag);
113*9880d681SAndroid Build Coastguard Worker   SW.printNumber("Value", Value);
114*9880d681SAndroid Build Coastguard Worker   if (!TagName.empty())
115*9880d681SAndroid Build Coastguard Worker     SW.printString("TagName", TagName);
116*9880d681SAndroid Build Coastguard Worker   if (!ValueDesc.empty())
117*9880d681SAndroid Build Coastguard Worker     SW.printString("Description", ValueDesc);
118*9880d681SAndroid Build Coastguard Worker }
119*9880d681SAndroid Build Coastguard Worker 
CPU_arch(AttrType Tag,const uint8_t * Data,uint32_t & Offset)120*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::CPU_arch(AttrType Tag, const uint8_t *Data,
121*9880d681SAndroid Build Coastguard Worker                                   uint32_t &Offset) {
122*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
123*9880d681SAndroid Build Coastguard Worker     "Pre-v4", "ARM v4", "ARM v4T", "ARM v5T", "ARM v5TE", "ARM v5TEJ", "ARM v6",
124*9880d681SAndroid Build Coastguard Worker     "ARM v6KZ", "ARM v6T2", "ARM v6K", "ARM v7", "ARM v6-M", "ARM v6S-M",
125*9880d681SAndroid Build Coastguard Worker     "ARM v7E-M", "ARM v8"
126*9880d681SAndroid Build Coastguard Worker   };
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
129*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
130*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
131*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
132*9880d681SAndroid Build Coastguard Worker }
133*9880d681SAndroid Build Coastguard Worker 
CPU_arch_profile(AttrType Tag,const uint8_t * Data,uint32_t & Offset)134*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::CPU_arch_profile(AttrType Tag, const uint8_t *Data,
135*9880d681SAndroid Build Coastguard Worker                                           uint32_t &Offset) {
136*9880d681SAndroid Build Coastguard Worker   uint64_t Encoded = ParseInteger(Data, Offset);
137*9880d681SAndroid Build Coastguard Worker 
138*9880d681SAndroid Build Coastguard Worker   StringRef Profile;
139*9880d681SAndroid Build Coastguard Worker   switch (Encoded) {
140*9880d681SAndroid Build Coastguard Worker   default:  Profile = "Unknown"; break;
141*9880d681SAndroid Build Coastguard Worker   case 'A': Profile = "Application"; break;
142*9880d681SAndroid Build Coastguard Worker   case 'R': Profile = "Real-time"; break;
143*9880d681SAndroid Build Coastguard Worker   case 'M': Profile = "Microcontroller"; break;
144*9880d681SAndroid Build Coastguard Worker   case 'S': Profile = "Classic"; break;
145*9880d681SAndroid Build Coastguard Worker   case 0: Profile = "None"; break;
146*9880d681SAndroid Build Coastguard Worker   }
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Encoded, Profile);
149*9880d681SAndroid Build Coastguard Worker }
150*9880d681SAndroid Build Coastguard Worker 
ARM_ISA_use(AttrType Tag,const uint8_t * Data,uint32_t & Offset)151*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ARM_ISA_use(AttrType Tag, const uint8_t *Data,
152*9880d681SAndroid Build Coastguard Worker                                      uint32_t &Offset) {
153*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "Permitted" };
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
156*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
157*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
158*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
159*9880d681SAndroid Build Coastguard Worker }
160*9880d681SAndroid Build Coastguard Worker 
THUMB_ISA_use(AttrType Tag,const uint8_t * Data,uint32_t & Offset)161*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::THUMB_ISA_use(AttrType Tag, const uint8_t *Data,
162*9880d681SAndroid Build Coastguard Worker                                        uint32_t &Offset) {
163*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "Thumb-1", "Thumb-2" };
164*9880d681SAndroid Build Coastguard Worker 
165*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
166*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
167*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
168*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker 
FP_arch(AttrType Tag,const uint8_t * Data,uint32_t & Offset)171*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::FP_arch(AttrType Tag, const uint8_t *Data,
172*9880d681SAndroid Build Coastguard Worker                                  uint32_t &Offset) {
173*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
174*9880d681SAndroid Build Coastguard Worker     "Not Permitted", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4",
175*9880d681SAndroid Build Coastguard Worker     "VFPv4-D16", "ARMv8-a FP", "ARMv8-a FP-D16"
176*9880d681SAndroid Build Coastguard Worker   };
177*9880d681SAndroid Build Coastguard Worker 
178*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
179*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
180*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
181*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
182*9880d681SAndroid Build Coastguard Worker }
183*9880d681SAndroid Build Coastguard Worker 
WMMX_arch(AttrType Tag,const uint8_t * Data,uint32_t & Offset)184*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::WMMX_arch(AttrType Tag, const uint8_t *Data,
185*9880d681SAndroid Build Coastguard Worker                                    uint32_t &Offset) {
186*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "WMMXv1", "WMMXv2" };
187*9880d681SAndroid Build Coastguard Worker 
188*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
189*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
190*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
191*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker 
Advanced_SIMD_arch(AttrType Tag,const uint8_t * Data,uint32_t & Offset)194*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::Advanced_SIMD_arch(AttrType Tag, const uint8_t *Data,
195*9880d681SAndroid Build Coastguard Worker                                             uint32_t &Offset) {
196*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
197*9880d681SAndroid Build Coastguard Worker     "Not Permitted", "NEONv1", "NEONv2+FMA", "ARMv8-a NEON", "ARMv8.1-a NEON"
198*9880d681SAndroid Build Coastguard Worker   };
199*9880d681SAndroid Build Coastguard Worker 
200*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
201*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
202*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
203*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
204*9880d681SAndroid Build Coastguard Worker }
205*9880d681SAndroid Build Coastguard Worker 
PCS_config(AttrType Tag,const uint8_t * Data,uint32_t & Offset)206*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::PCS_config(AttrType Tag, const uint8_t *Data,
207*9880d681SAndroid Build Coastguard Worker                                     uint32_t &Offset) {
208*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
209*9880d681SAndroid Build Coastguard Worker     "None", "Bare Platform", "Linux Application", "Linux DSO", "Palm OS 2004",
210*9880d681SAndroid Build Coastguard Worker     "Reserved (Palm OS)", "Symbian OS 2004", "Reserved (Symbian OS)"
211*9880d681SAndroid Build Coastguard Worker   };
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
214*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
215*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
216*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
217*9880d681SAndroid Build Coastguard Worker }
218*9880d681SAndroid Build Coastguard Worker 
ABI_PCS_R9_use(AttrType Tag,const uint8_t * Data,uint32_t & Offset)219*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_PCS_R9_use(AttrType Tag, const uint8_t *Data,
220*9880d681SAndroid Build Coastguard Worker                                         uint32_t &Offset) {
221*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "v6", "Static Base", "TLS", "Unused" };
222*9880d681SAndroid Build Coastguard Worker 
223*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
224*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
225*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
226*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
227*9880d681SAndroid Build Coastguard Worker }
228*9880d681SAndroid Build Coastguard Worker 
ABI_PCS_RW_data(AttrType Tag,const uint8_t * Data,uint32_t & Offset)229*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_PCS_RW_data(AttrType Tag, const uint8_t *Data,
230*9880d681SAndroid Build Coastguard Worker                                          uint32_t &Offset) {
231*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
232*9880d681SAndroid Build Coastguard Worker     "Absolute", "PC-relative", "SB-relative", "Not Permitted"
233*9880d681SAndroid Build Coastguard Worker   };
234*9880d681SAndroid Build Coastguard Worker 
235*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
236*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
237*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
238*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
239*9880d681SAndroid Build Coastguard Worker }
240*9880d681SAndroid Build Coastguard Worker 
ABI_PCS_RO_data(AttrType Tag,const uint8_t * Data,uint32_t & Offset)241*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_PCS_RO_data(AttrType Tag, const uint8_t *Data,
242*9880d681SAndroid Build Coastguard Worker                                          uint32_t &Offset) {
243*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
244*9880d681SAndroid Build Coastguard Worker     "Absolute", "PC-relative", "Not Permitted"
245*9880d681SAndroid Build Coastguard Worker   };
246*9880d681SAndroid Build Coastguard Worker 
247*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
248*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
249*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
250*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
251*9880d681SAndroid Build Coastguard Worker }
252*9880d681SAndroid Build Coastguard Worker 
ABI_PCS_GOT_use(AttrType Tag,const uint8_t * Data,uint32_t & Offset)253*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_PCS_GOT_use(AttrType Tag, const uint8_t *Data,
254*9880d681SAndroid Build Coastguard Worker                                          uint32_t &Offset) {
255*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
256*9880d681SAndroid Build Coastguard Worker     "Not Permitted", "Direct", "GOT-Indirect"
257*9880d681SAndroid Build Coastguard Worker   };
258*9880d681SAndroid Build Coastguard Worker 
259*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
260*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
261*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
262*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
263*9880d681SAndroid Build Coastguard Worker }
264*9880d681SAndroid Build Coastguard Worker 
ABI_PCS_wchar_t(AttrType Tag,const uint8_t * Data,uint32_t & Offset)265*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_PCS_wchar_t(AttrType Tag, const uint8_t *Data,
266*9880d681SAndroid Build Coastguard Worker                                          uint32_t &Offset) {
267*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
268*9880d681SAndroid Build Coastguard Worker     "Not Permitted", "Unknown", "2-byte", "Unknown", "4-byte"
269*9880d681SAndroid Build Coastguard Worker   };
270*9880d681SAndroid Build Coastguard Worker 
271*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
272*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
273*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
274*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker 
ABI_FP_rounding(AttrType Tag,const uint8_t * Data,uint32_t & Offset)277*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_FP_rounding(AttrType Tag, const uint8_t *Data,
278*9880d681SAndroid Build Coastguard Worker                                          uint32_t &Offset) {
279*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "IEEE-754", "Runtime" };
280*9880d681SAndroid Build Coastguard Worker 
281*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
282*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
283*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
284*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker 
ABI_FP_denormal(AttrType Tag,const uint8_t * Data,uint32_t & Offset)287*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_FP_denormal(AttrType Tag, const uint8_t *Data,
288*9880d681SAndroid Build Coastguard Worker                                          uint32_t &Offset) {
289*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
290*9880d681SAndroid Build Coastguard Worker     "Unsupported", "IEEE-754", "Sign Only"
291*9880d681SAndroid Build Coastguard Worker   };
292*9880d681SAndroid Build Coastguard Worker 
293*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
294*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
295*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
296*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
297*9880d681SAndroid Build Coastguard Worker }
298*9880d681SAndroid Build Coastguard Worker 
ABI_FP_exceptions(AttrType Tag,const uint8_t * Data,uint32_t & Offset)299*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_FP_exceptions(AttrType Tag, const uint8_t *Data,
300*9880d681SAndroid Build Coastguard Worker                                            uint32_t &Offset) {
301*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "IEEE-754" };
302*9880d681SAndroid Build Coastguard Worker 
303*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
304*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
305*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
306*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
307*9880d681SAndroid Build Coastguard Worker }
308*9880d681SAndroid Build Coastguard Worker 
ABI_FP_user_exceptions(AttrType Tag,const uint8_t * Data,uint32_t & Offset)309*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_FP_user_exceptions(AttrType Tag,
310*9880d681SAndroid Build Coastguard Worker                                                 const uint8_t *Data,
311*9880d681SAndroid Build Coastguard Worker                                                 uint32_t &Offset) {
312*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "IEEE-754" };
313*9880d681SAndroid Build Coastguard Worker 
314*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
315*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
316*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
317*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
318*9880d681SAndroid Build Coastguard Worker }
319*9880d681SAndroid Build Coastguard Worker 
ABI_FP_number_model(AttrType Tag,const uint8_t * Data,uint32_t & Offset)320*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_FP_number_model(AttrType Tag, const uint8_t *Data,
321*9880d681SAndroid Build Coastguard Worker                                              uint32_t &Offset) {
322*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
323*9880d681SAndroid Build Coastguard Worker     "Not Permitted", "Finite Only", "RTABI", "IEEE-754"
324*9880d681SAndroid Build Coastguard Worker   };
325*9880d681SAndroid Build Coastguard Worker 
326*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
327*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
328*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
329*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
330*9880d681SAndroid Build Coastguard Worker }
331*9880d681SAndroid Build Coastguard Worker 
ABI_align_needed(AttrType Tag,const uint8_t * Data,uint32_t & Offset)332*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_align_needed(AttrType Tag, const uint8_t *Data,
333*9880d681SAndroid Build Coastguard Worker                                           uint32_t &Offset) {
334*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
335*9880d681SAndroid Build Coastguard Worker     "Not Permitted", "8-byte alignment", "4-byte alignment", "Reserved"
336*9880d681SAndroid Build Coastguard Worker   };
337*9880d681SAndroid Build Coastguard Worker 
338*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
339*9880d681SAndroid Build Coastguard Worker 
340*9880d681SAndroid Build Coastguard Worker   std::string Description;
341*9880d681SAndroid Build Coastguard Worker   if (Value < array_lengthof(Strings))
342*9880d681SAndroid Build Coastguard Worker     Description = std::string(Strings[Value]);
343*9880d681SAndroid Build Coastguard Worker   else if (Value <= 12)
344*9880d681SAndroid Build Coastguard Worker     Description = std::string("8-byte alignment, ") + utostr(1ULL << Value)
345*9880d681SAndroid Build Coastguard Worker                 + std::string("-byte extended alignment");
346*9880d681SAndroid Build Coastguard Worker   else
347*9880d681SAndroid Build Coastguard Worker     Description = "Invalid";
348*9880d681SAndroid Build Coastguard Worker 
349*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, Description);
350*9880d681SAndroid Build Coastguard Worker }
351*9880d681SAndroid Build Coastguard Worker 
ABI_align_preserved(AttrType Tag,const uint8_t * Data,uint32_t & Offset)352*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_align_preserved(AttrType Tag, const uint8_t *Data,
353*9880d681SAndroid Build Coastguard Worker                                              uint32_t &Offset) {
354*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
355*9880d681SAndroid Build Coastguard Worker     "Not Required", "8-byte data alignment", "8-byte data and code alignment",
356*9880d681SAndroid Build Coastguard Worker     "Reserved"
357*9880d681SAndroid Build Coastguard Worker   };
358*9880d681SAndroid Build Coastguard Worker 
359*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
360*9880d681SAndroid Build Coastguard Worker 
361*9880d681SAndroid Build Coastguard Worker   std::string Description;
362*9880d681SAndroid Build Coastguard Worker   if (Value < array_lengthof(Strings))
363*9880d681SAndroid Build Coastguard Worker     Description = std::string(Strings[Value]);
364*9880d681SAndroid Build Coastguard Worker   else if (Value <= 12)
365*9880d681SAndroid Build Coastguard Worker     Description = std::string("8-byte stack alignment, ") +
366*9880d681SAndroid Build Coastguard Worker                   utostr(1ULL << Value) + std::string("-byte data alignment");
367*9880d681SAndroid Build Coastguard Worker   else
368*9880d681SAndroid Build Coastguard Worker     Description = "Invalid";
369*9880d681SAndroid Build Coastguard Worker 
370*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, Description);
371*9880d681SAndroid Build Coastguard Worker }
372*9880d681SAndroid Build Coastguard Worker 
ABI_enum_size(AttrType Tag,const uint8_t * Data,uint32_t & Offset)373*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_enum_size(AttrType Tag, const uint8_t *Data,
374*9880d681SAndroid Build Coastguard Worker                                        uint32_t &Offset) {
375*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
376*9880d681SAndroid Build Coastguard Worker     "Not Permitted", "Packed", "Int32", "External Int32"
377*9880d681SAndroid Build Coastguard Worker   };
378*9880d681SAndroid Build Coastguard Worker 
379*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
380*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
381*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
382*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
383*9880d681SAndroid Build Coastguard Worker }
384*9880d681SAndroid Build Coastguard Worker 
ABI_HardFP_use(AttrType Tag,const uint8_t * Data,uint32_t & Offset)385*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_HardFP_use(AttrType Tag, const uint8_t *Data,
386*9880d681SAndroid Build Coastguard Worker                                         uint32_t &Offset) {
387*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
388*9880d681SAndroid Build Coastguard Worker     "Tag_FP_arch", "Single-Precision", "Reserved", "Tag_FP_arch (deprecated)"
389*9880d681SAndroid Build Coastguard Worker   };
390*9880d681SAndroid Build Coastguard Worker 
391*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
392*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
393*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
394*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
395*9880d681SAndroid Build Coastguard Worker }
396*9880d681SAndroid Build Coastguard Worker 
ABI_VFP_args(AttrType Tag,const uint8_t * Data,uint32_t & Offset)397*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_VFP_args(AttrType Tag, const uint8_t *Data,
398*9880d681SAndroid Build Coastguard Worker                                       uint32_t &Offset) {
399*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
400*9880d681SAndroid Build Coastguard Worker     "AAPCS", "AAPCS VFP", "Custom", "Not Permitted"
401*9880d681SAndroid Build Coastguard Worker   };
402*9880d681SAndroid Build Coastguard Worker 
403*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
404*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
405*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
406*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
407*9880d681SAndroid Build Coastguard Worker }
408*9880d681SAndroid Build Coastguard Worker 
ABI_WMMX_args(AttrType Tag,const uint8_t * Data,uint32_t & Offset)409*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_WMMX_args(AttrType Tag, const uint8_t *Data,
410*9880d681SAndroid Build Coastguard Worker                                        uint32_t &Offset) {
411*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "AAPCS", "iWMMX", "Custom" };
412*9880d681SAndroid Build Coastguard Worker 
413*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
414*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
415*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
416*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
417*9880d681SAndroid Build Coastguard Worker }
418*9880d681SAndroid Build Coastguard Worker 
ABI_optimization_goals(AttrType Tag,const uint8_t * Data,uint32_t & Offset)419*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_optimization_goals(AttrType Tag,
420*9880d681SAndroid Build Coastguard Worker                                                 const uint8_t *Data,
421*9880d681SAndroid Build Coastguard Worker                                                 uint32_t &Offset) {
422*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
423*9880d681SAndroid Build Coastguard Worker     "None", "Speed", "Aggressive Speed", "Size", "Aggressive Size", "Debugging",
424*9880d681SAndroid Build Coastguard Worker     "Best Debugging"
425*9880d681SAndroid Build Coastguard Worker   };
426*9880d681SAndroid Build Coastguard Worker 
427*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
428*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
429*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
430*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker 
ABI_FP_optimization_goals(AttrType Tag,const uint8_t * Data,uint32_t & Offset)433*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_FP_optimization_goals(AttrType Tag,
434*9880d681SAndroid Build Coastguard Worker                                                    const uint8_t *Data,
435*9880d681SAndroid Build Coastguard Worker                                                    uint32_t &Offset) {
436*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
437*9880d681SAndroid Build Coastguard Worker     "None", "Speed", "Aggressive Speed", "Size", "Aggressive Size", "Accuracy",
438*9880d681SAndroid Build Coastguard Worker     "Best Accuracy"
439*9880d681SAndroid Build Coastguard Worker   };
440*9880d681SAndroid Build Coastguard Worker 
441*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
442*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
443*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
444*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
445*9880d681SAndroid Build Coastguard Worker }
446*9880d681SAndroid Build Coastguard Worker 
compatibility(AttrType Tag,const uint8_t * Data,uint32_t & Offset)447*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::compatibility(AttrType Tag, const uint8_t *Data,
448*9880d681SAndroid Build Coastguard Worker                                        uint32_t &Offset) {
449*9880d681SAndroid Build Coastguard Worker   uint64_t Integer = ParseInteger(Data, Offset);
450*9880d681SAndroid Build Coastguard Worker   StringRef String = ParseString(Data, Offset);
451*9880d681SAndroid Build Coastguard Worker 
452*9880d681SAndroid Build Coastguard Worker   DictScope AS(SW, "Attribute");
453*9880d681SAndroid Build Coastguard Worker   SW.printNumber("Tag", Tag);
454*9880d681SAndroid Build Coastguard Worker   SW.startLine() << "Value: " << Integer << ", " << String << '\n';
455*9880d681SAndroid Build Coastguard Worker   SW.printString("TagName", AttrTypeAsString(Tag, /*TagPrefix*/false));
456*9880d681SAndroid Build Coastguard Worker   switch (Integer) {
457*9880d681SAndroid Build Coastguard Worker   case 0:
458*9880d681SAndroid Build Coastguard Worker     SW.printString("Description", StringRef("No Specific Requirements"));
459*9880d681SAndroid Build Coastguard Worker     break;
460*9880d681SAndroid Build Coastguard Worker   case 1:
461*9880d681SAndroid Build Coastguard Worker     SW.printString("Description", StringRef("AEABI Conformant"));
462*9880d681SAndroid Build Coastguard Worker     break;
463*9880d681SAndroid Build Coastguard Worker   default:
464*9880d681SAndroid Build Coastguard Worker     SW.printString("Description", StringRef("AEABI Non-Conformant"));
465*9880d681SAndroid Build Coastguard Worker     break;
466*9880d681SAndroid Build Coastguard Worker   }
467*9880d681SAndroid Build Coastguard Worker }
468*9880d681SAndroid Build Coastguard Worker 
CPU_unaligned_access(AttrType Tag,const uint8_t * Data,uint32_t & Offset)469*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::CPU_unaligned_access(AttrType Tag, const uint8_t *Data,
470*9880d681SAndroid Build Coastguard Worker                                               uint32_t &Offset) {
471*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "v6-style" };
472*9880d681SAndroid Build Coastguard Worker 
473*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
474*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
475*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
476*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
477*9880d681SAndroid Build Coastguard Worker }
478*9880d681SAndroid Build Coastguard Worker 
FP_HP_extension(AttrType Tag,const uint8_t * Data,uint32_t & Offset)479*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::FP_HP_extension(AttrType Tag, const uint8_t *Data,
480*9880d681SAndroid Build Coastguard Worker                                          uint32_t &Offset) {
481*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "If Available", "Permitted" };
482*9880d681SAndroid Build Coastguard Worker 
483*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
484*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
485*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
486*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
487*9880d681SAndroid Build Coastguard Worker }
488*9880d681SAndroid Build Coastguard Worker 
ABI_FP_16bit_format(AttrType Tag,const uint8_t * Data,uint32_t & Offset)489*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ABI_FP_16bit_format(AttrType Tag, const uint8_t *Data,
490*9880d681SAndroid Build Coastguard Worker                                              uint32_t &Offset) {
491*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "IEEE-754", "VFPv3" };
492*9880d681SAndroid Build Coastguard Worker 
493*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
494*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
495*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
496*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
497*9880d681SAndroid Build Coastguard Worker }
498*9880d681SAndroid Build Coastguard Worker 
MPextension_use(AttrType Tag,const uint8_t * Data,uint32_t & Offset)499*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::MPextension_use(AttrType Tag, const uint8_t *Data,
500*9880d681SAndroid Build Coastguard Worker                                          uint32_t &Offset) {
501*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "Permitted" };
502*9880d681SAndroid Build Coastguard Worker 
503*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
504*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
505*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
506*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
507*9880d681SAndroid Build Coastguard Worker }
508*9880d681SAndroid Build Coastguard Worker 
DIV_use(AttrType Tag,const uint8_t * Data,uint32_t & Offset)509*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::DIV_use(AttrType Tag, const uint8_t *Data,
510*9880d681SAndroid Build Coastguard Worker                                  uint32_t &Offset) {
511*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
512*9880d681SAndroid Build Coastguard Worker     "If Available", "Not Permitted", "Permitted"
513*9880d681SAndroid Build Coastguard Worker   };
514*9880d681SAndroid Build Coastguard Worker 
515*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
516*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
517*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
518*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
519*9880d681SAndroid Build Coastguard Worker }
520*9880d681SAndroid Build Coastguard Worker 
DSP_extension(AttrType Tag,const uint8_t * Data,uint32_t & Offset)521*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::DSP_extension(AttrType Tag, const uint8_t *Data,
522*9880d681SAndroid Build Coastguard Worker                                        uint32_t &Offset) {
523*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "Permitted" };
524*9880d681SAndroid Build Coastguard Worker 
525*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
526*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
527*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
528*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
529*9880d681SAndroid Build Coastguard Worker }
530*9880d681SAndroid Build Coastguard Worker 
T2EE_use(AttrType Tag,const uint8_t * Data,uint32_t & Offset)531*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::T2EE_use(AttrType Tag, const uint8_t *Data,
532*9880d681SAndroid Build Coastguard Worker                                   uint32_t &Offset) {
533*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = { "Not Permitted", "Permitted" };
534*9880d681SAndroid Build Coastguard Worker 
535*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
536*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
537*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
538*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
539*9880d681SAndroid Build Coastguard Worker }
540*9880d681SAndroid Build Coastguard Worker 
Virtualization_use(AttrType Tag,const uint8_t * Data,uint32_t & Offset)541*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::Virtualization_use(AttrType Tag, const uint8_t *Data,
542*9880d681SAndroid Build Coastguard Worker                                             uint32_t &Offset) {
543*9880d681SAndroid Build Coastguard Worker   static const char *const Strings[] = {
544*9880d681SAndroid Build Coastguard Worker     "Not Permitted", "TrustZone", "Virtualization Extensions",
545*9880d681SAndroid Build Coastguard Worker     "TrustZone + Virtualization Extensions"
546*9880d681SAndroid Build Coastguard Worker   };
547*9880d681SAndroid Build Coastguard Worker 
548*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
549*9880d681SAndroid Build Coastguard Worker   StringRef ValueDesc =
550*9880d681SAndroid Build Coastguard Worker     (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
551*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, ValueDesc);
552*9880d681SAndroid Build Coastguard Worker }
553*9880d681SAndroid Build Coastguard Worker 
nodefaults(AttrType Tag,const uint8_t * Data,uint32_t & Offset)554*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::nodefaults(AttrType Tag, const uint8_t *Data,
555*9880d681SAndroid Build Coastguard Worker                                     uint32_t &Offset) {
556*9880d681SAndroid Build Coastguard Worker   uint64_t Value = ParseInteger(Data, Offset);
557*9880d681SAndroid Build Coastguard Worker   PrintAttribute(Tag, Value, "Unspecified Tags UNDEFINED");
558*9880d681SAndroid Build Coastguard Worker }
559*9880d681SAndroid Build Coastguard Worker 
ParseIndexList(const uint8_t * Data,uint32_t & Offset,SmallVectorImpl<uint8_t> & IndexList)560*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ParseIndexList(const uint8_t *Data, uint32_t &Offset,
561*9880d681SAndroid Build Coastguard Worker                                         SmallVectorImpl<uint8_t> &IndexList) {
562*9880d681SAndroid Build Coastguard Worker   for (;;) {
563*9880d681SAndroid Build Coastguard Worker     unsigned Length;
564*9880d681SAndroid Build Coastguard Worker     uint64_t Value = decodeULEB128(Data + Offset, &Length);
565*9880d681SAndroid Build Coastguard Worker     Offset = Offset + Length;
566*9880d681SAndroid Build Coastguard Worker     if (Value == 0)
567*9880d681SAndroid Build Coastguard Worker       break;
568*9880d681SAndroid Build Coastguard Worker     IndexList.push_back(Value);
569*9880d681SAndroid Build Coastguard Worker   }
570*9880d681SAndroid Build Coastguard Worker }
571*9880d681SAndroid Build Coastguard Worker 
ParseAttributeList(const uint8_t * Data,uint32_t & Offset,uint32_t Length)572*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ParseAttributeList(const uint8_t *Data,
573*9880d681SAndroid Build Coastguard Worker                                             uint32_t &Offset, uint32_t Length) {
574*9880d681SAndroid Build Coastguard Worker   while (Offset < Length) {
575*9880d681SAndroid Build Coastguard Worker     unsigned Length;
576*9880d681SAndroid Build Coastguard Worker     uint64_t Tag = decodeULEB128(Data + Offset, &Length);
577*9880d681SAndroid Build Coastguard Worker     Offset += Length;
578*9880d681SAndroid Build Coastguard Worker 
579*9880d681SAndroid Build Coastguard Worker     bool Handled = false;
580*9880d681SAndroid Build Coastguard Worker     for (unsigned AHI = 0, AHE = array_lengthof(DisplayRoutines);
581*9880d681SAndroid Build Coastguard Worker          AHI != AHE && !Handled; ++AHI) {
582*9880d681SAndroid Build Coastguard Worker       if (DisplayRoutines[AHI].Attribute == Tag) {
583*9880d681SAndroid Build Coastguard Worker         (this->*DisplayRoutines[AHI].Routine)(ARMBuildAttrs::AttrType(Tag),
584*9880d681SAndroid Build Coastguard Worker                                               Data, Offset);
585*9880d681SAndroid Build Coastguard Worker         Handled = true;
586*9880d681SAndroid Build Coastguard Worker         break;
587*9880d681SAndroid Build Coastguard Worker       }
588*9880d681SAndroid Build Coastguard Worker     }
589*9880d681SAndroid Build Coastguard Worker     if (!Handled) {
590*9880d681SAndroid Build Coastguard Worker       if (Tag < 32) {
591*9880d681SAndroid Build Coastguard Worker         errs() << "unhandled AEABI Tag " << Tag
592*9880d681SAndroid Build Coastguard Worker                << " (" << ARMBuildAttrs::AttrTypeAsString(Tag) << ")\n";
593*9880d681SAndroid Build Coastguard Worker         continue;
594*9880d681SAndroid Build Coastguard Worker       }
595*9880d681SAndroid Build Coastguard Worker 
596*9880d681SAndroid Build Coastguard Worker       if (Tag % 2 == 0)
597*9880d681SAndroid Build Coastguard Worker         IntegerAttribute(ARMBuildAttrs::AttrType(Tag), Data, Offset);
598*9880d681SAndroid Build Coastguard Worker       else
599*9880d681SAndroid Build Coastguard Worker         StringAttribute(ARMBuildAttrs::AttrType(Tag), Data, Offset);
600*9880d681SAndroid Build Coastguard Worker     }
601*9880d681SAndroid Build Coastguard Worker   }
602*9880d681SAndroid Build Coastguard Worker }
603*9880d681SAndroid Build Coastguard Worker 
ParseSubsection(const uint8_t * Data,uint32_t Length)604*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::ParseSubsection(const uint8_t *Data, uint32_t Length) {
605*9880d681SAndroid Build Coastguard Worker   uint32_t Offset = sizeof(uint32_t); /* SectionLength */
606*9880d681SAndroid Build Coastguard Worker 
607*9880d681SAndroid Build Coastguard Worker   SW.printNumber("SectionLength", Length);
608*9880d681SAndroid Build Coastguard Worker 
609*9880d681SAndroid Build Coastguard Worker   const char *VendorName = reinterpret_cast<const char*>(Data + Offset);
610*9880d681SAndroid Build Coastguard Worker   size_t VendorNameLength = std::strlen(VendorName);
611*9880d681SAndroid Build Coastguard Worker   SW.printString("Vendor", StringRef(VendorName, VendorNameLength));
612*9880d681SAndroid Build Coastguard Worker   Offset = Offset + VendorNameLength + 1;
613*9880d681SAndroid Build Coastguard Worker 
614*9880d681SAndroid Build Coastguard Worker   if (StringRef(VendorName, VendorNameLength).lower() != "aeabi")
615*9880d681SAndroid Build Coastguard Worker     return;
616*9880d681SAndroid Build Coastguard Worker 
617*9880d681SAndroid Build Coastguard Worker   while (Offset < Length) {
618*9880d681SAndroid Build Coastguard Worker     /// Tag_File | Tag_Section | Tag_Symbol   uleb128:byte-size
619*9880d681SAndroid Build Coastguard Worker     uint8_t Tag = Data[Offset];
620*9880d681SAndroid Build Coastguard Worker     SW.printEnum("Tag", Tag, makeArrayRef(TagNames));
621*9880d681SAndroid Build Coastguard Worker     Offset = Offset + sizeof(Tag);
622*9880d681SAndroid Build Coastguard Worker 
623*9880d681SAndroid Build Coastguard Worker     uint32_t Size =
624*9880d681SAndroid Build Coastguard Worker       *reinterpret_cast<const support::ulittle32_t*>(Data + Offset);
625*9880d681SAndroid Build Coastguard Worker     SW.printNumber("Size", Size);
626*9880d681SAndroid Build Coastguard Worker     Offset = Offset + sizeof(Size);
627*9880d681SAndroid Build Coastguard Worker 
628*9880d681SAndroid Build Coastguard Worker     if (Size > Length) {
629*9880d681SAndroid Build Coastguard Worker       errs() << "subsection length greater than section length\n";
630*9880d681SAndroid Build Coastguard Worker       return;
631*9880d681SAndroid Build Coastguard Worker     }
632*9880d681SAndroid Build Coastguard Worker 
633*9880d681SAndroid Build Coastguard Worker     StringRef ScopeName, IndexName;
634*9880d681SAndroid Build Coastguard Worker     SmallVector<uint8_t, 8> Indicies;
635*9880d681SAndroid Build Coastguard Worker     switch (Tag) {
636*9880d681SAndroid Build Coastguard Worker     case ARMBuildAttrs::File:
637*9880d681SAndroid Build Coastguard Worker       ScopeName = "FileAttributes";
638*9880d681SAndroid Build Coastguard Worker       break;
639*9880d681SAndroid Build Coastguard Worker     case ARMBuildAttrs::Section:
640*9880d681SAndroid Build Coastguard Worker       ScopeName = "SectionAttributes";
641*9880d681SAndroid Build Coastguard Worker       IndexName = "Sections";
642*9880d681SAndroid Build Coastguard Worker       ParseIndexList(Data, Offset, Indicies);
643*9880d681SAndroid Build Coastguard Worker       break;
644*9880d681SAndroid Build Coastguard Worker     case ARMBuildAttrs::Symbol:
645*9880d681SAndroid Build Coastguard Worker       ScopeName = "SymbolAttributes";
646*9880d681SAndroid Build Coastguard Worker       IndexName = "Symbols";
647*9880d681SAndroid Build Coastguard Worker       ParseIndexList(Data, Offset, Indicies);
648*9880d681SAndroid Build Coastguard Worker       break;
649*9880d681SAndroid Build Coastguard Worker     default:
650*9880d681SAndroid Build Coastguard Worker       errs() << "unrecognised tag: 0x" << utohexstr(Tag) << '\n';
651*9880d681SAndroid Build Coastguard Worker       return;
652*9880d681SAndroid Build Coastguard Worker     }
653*9880d681SAndroid Build Coastguard Worker 
654*9880d681SAndroid Build Coastguard Worker     DictScope ASS(SW, ScopeName);
655*9880d681SAndroid Build Coastguard Worker 
656*9880d681SAndroid Build Coastguard Worker     if (!Indicies.empty())
657*9880d681SAndroid Build Coastguard Worker       SW.printList(IndexName, Indicies);
658*9880d681SAndroid Build Coastguard Worker 
659*9880d681SAndroid Build Coastguard Worker     ParseAttributeList(Data, Offset, Length);
660*9880d681SAndroid Build Coastguard Worker   }
661*9880d681SAndroid Build Coastguard Worker }
662*9880d681SAndroid Build Coastguard Worker 
Parse(ArrayRef<uint8_t> Section)663*9880d681SAndroid Build Coastguard Worker void ARMAttributeParser::Parse(ArrayRef<uint8_t> Section) {
664*9880d681SAndroid Build Coastguard Worker   size_t Offset = 1;
665*9880d681SAndroid Build Coastguard Worker   unsigned SectionNumber = 0;
666*9880d681SAndroid Build Coastguard Worker 
667*9880d681SAndroid Build Coastguard Worker   while (Offset < Section.size()) {
668*9880d681SAndroid Build Coastguard Worker     uint32_t SectionLength =
669*9880d681SAndroid Build Coastguard Worker       *reinterpret_cast<const support::ulittle32_t*>(Section.data() + Offset);
670*9880d681SAndroid Build Coastguard Worker 
671*9880d681SAndroid Build Coastguard Worker     SW.startLine() << "Section " << ++SectionNumber << " {\n";
672*9880d681SAndroid Build Coastguard Worker     SW.indent();
673*9880d681SAndroid Build Coastguard Worker 
674*9880d681SAndroid Build Coastguard Worker     ParseSubsection(Section.data() + Offset, SectionLength);
675*9880d681SAndroid Build Coastguard Worker     Offset = Offset + SectionLength;
676*9880d681SAndroid Build Coastguard Worker 
677*9880d681SAndroid Build Coastguard Worker     SW.unindent();
678*9880d681SAndroid Build Coastguard Worker     SW.startLine() << "}\n";
679*9880d681SAndroid Build Coastguard Worker   }
680*9880d681SAndroid Build Coastguard Worker }
681*9880d681SAndroid Build Coastguard Worker }
682*9880d681SAndroid Build Coastguard Worker 
683