1 //===- ARMAttributeParser.cpp - ARM 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 #include "llvm/Support/ARMAttributeParser.h" 10 #include "llvm/ADT/STLArrayExtras.h" 11 #include "llvm/ADT/StringExtras.h" 12 #include "llvm/Support/ScopedPrinter.h" 13 14 using namespace llvm; 15 using namespace llvm::ARMBuildAttrs; 16 17 #define ATTRIBUTE_HANDLER(attr) \ 18 { ARMBuildAttrs::attr, &ARMAttributeParser::attr } 19 20 const ARMAttributeParser::DisplayHandler ARMAttributeParser::displayRoutines[] = 21 { 22 {ARMBuildAttrs::CPU_raw_name, &ARMAttributeParser::stringAttribute}, 23 {ARMBuildAttrs::CPU_name, &ARMAttributeParser::stringAttribute}, 24 ATTRIBUTE_HANDLER(CPU_arch), 25 ATTRIBUTE_HANDLER(CPU_arch_profile), 26 ATTRIBUTE_HANDLER(ARM_ISA_use), 27 ATTRIBUTE_HANDLER(THUMB_ISA_use), 28 ATTRIBUTE_HANDLER(FP_arch), 29 ATTRIBUTE_HANDLER(WMMX_arch), 30 ATTRIBUTE_HANDLER(Advanced_SIMD_arch), 31 ATTRIBUTE_HANDLER(MVE_arch), 32 ATTRIBUTE_HANDLER(PCS_config), 33 ATTRIBUTE_HANDLER(ABI_PCS_R9_use), 34 ATTRIBUTE_HANDLER(ABI_PCS_RW_data), 35 ATTRIBUTE_HANDLER(ABI_PCS_RO_data), 36 ATTRIBUTE_HANDLER(ABI_PCS_GOT_use), 37 ATTRIBUTE_HANDLER(ABI_PCS_wchar_t), 38 ATTRIBUTE_HANDLER(ABI_FP_rounding), 39 ATTRIBUTE_HANDLER(ABI_FP_denormal), 40 ATTRIBUTE_HANDLER(ABI_FP_exceptions), 41 ATTRIBUTE_HANDLER(ABI_FP_user_exceptions), 42 ATTRIBUTE_HANDLER(ABI_FP_number_model), 43 ATTRIBUTE_HANDLER(ABI_align_needed), 44 ATTRIBUTE_HANDLER(ABI_align_preserved), 45 ATTRIBUTE_HANDLER(ABI_enum_size), 46 ATTRIBUTE_HANDLER(ABI_HardFP_use), 47 ATTRIBUTE_HANDLER(ABI_VFP_args), 48 ATTRIBUTE_HANDLER(ABI_WMMX_args), 49 ATTRIBUTE_HANDLER(ABI_optimization_goals), 50 ATTRIBUTE_HANDLER(ABI_FP_optimization_goals), 51 ATTRIBUTE_HANDLER(compatibility), 52 ATTRIBUTE_HANDLER(CPU_unaligned_access), 53 ATTRIBUTE_HANDLER(FP_HP_extension), 54 ATTRIBUTE_HANDLER(ABI_FP_16bit_format), 55 ATTRIBUTE_HANDLER(MPextension_use), 56 ATTRIBUTE_HANDLER(DIV_use), 57 ATTRIBUTE_HANDLER(DSP_extension), 58 ATTRIBUTE_HANDLER(T2EE_use), 59 ATTRIBUTE_HANDLER(Virtualization_use), 60 ATTRIBUTE_HANDLER(PAC_extension), 61 ATTRIBUTE_HANDLER(BTI_extension), 62 ATTRIBUTE_HANDLER(PACRET_use), 63 ATTRIBUTE_HANDLER(BTI_use), 64 ATTRIBUTE_HANDLER(nodefaults), 65 }; 66 67 #undef ATTRIBUTE_HANDLER 68 69 Error ARMAttributeParser::stringAttribute(AttrType tag) { 70 StringRef tagName = 71 ELFAttrs::attrTypeAsString(tag, tagToStringMap, /*hasTagPrefix=*/false); 72 StringRef desc = de.getCStrRef(cursor); 73 74 if (sw) { 75 DictScope scope(*sw, "Attribute"); 76 sw->printNumber("Tag", tag); 77 if (!tagName.empty()) 78 sw->printString("TagName", tagName); 79 sw->printString("Value", desc); 80 } 81 return Error::success(); 82 } 83 84 Error ARMAttributeParser::CPU_arch(AttrType tag) { 85 static const char *strings[] = { 86 "Pre-v4", "ARM v4", "ARM v4T", "ARM v5T", "ARM v5TE", "ARM v5TEJ", "ARM v6", 87 "ARM v6KZ", "ARM v6T2", "ARM v6K", "ARM v7", "ARM v6-M", "ARM v6S-M", 88 "ARM v7E-M", "ARM v8-A", "ARM v8-R", 89 "ARM v8-M Baseline", "ARM v8-M Mainline", nullptr, nullptr, nullptr, 90 "ARM v8.1-M Mainline", "ARM v9-A" 91 }; 92 return parseStringAttribute("CPU_arch", tag, makeArrayRef(strings)); 93 } 94 95 Error ARMAttributeParser::CPU_arch_profile(AttrType tag) { 96 uint64_t value = de.getULEB128(cursor); 97 98 StringRef profile; 99 switch (value) { 100 default: profile = "Unknown"; break; 101 case 'A': profile = "Application"; break; 102 case 'R': profile = "Real-time"; break; 103 case 'M': profile = "Microcontroller"; break; 104 case 'S': profile = "Classic"; break; 105 case 0: profile = "None"; break; 106 } 107 108 printAttribute(tag, value, profile); 109 return Error::success(); 110 } 111 112 Error ARMAttributeParser::ARM_ISA_use(AttrType tag) { 113 static const char *strings[] = {"Not Permitted", "Permitted"}; 114 return parseStringAttribute("ARM_ISA_use", tag, makeArrayRef(strings)); 115 } 116 117 Error ARMAttributeParser::THUMB_ISA_use(AttrType tag) { 118 static const char *strings[] = {"Not Permitted", "Thumb-1", "Thumb-2", "Permitted"}; 119 return parseStringAttribute("THUMB_ISA_use", tag, makeArrayRef(strings)); 120 } 121 122 Error ARMAttributeParser::FP_arch(AttrType tag) { 123 static const char *strings[] = { 124 "Not Permitted", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", 125 "VFPv4", "VFPv4-D16", "ARMv8-a FP", "ARMv8-a FP-D16"}; 126 return parseStringAttribute("FP_arch", tag, makeArrayRef(strings)); 127 } 128 129 Error ARMAttributeParser::WMMX_arch(AttrType tag) { 130 static const char *strings[] = {"Not Permitted", "WMMXv1", "WMMXv2"}; 131 return parseStringAttribute("WMMX_arch", tag, makeArrayRef(strings)); 132 } 133 134 Error ARMAttributeParser::Advanced_SIMD_arch(AttrType tag) { 135 static const char *strings[] = {"Not Permitted", "NEONv1", "NEONv2+FMA", 136 "ARMv8-a NEON", "ARMv8.1-a NEON"}; 137 return parseStringAttribute("Advanced_SIMD_arch", tag, makeArrayRef(strings)); 138 } 139 140 Error ARMAttributeParser::MVE_arch(AttrType tag) { 141 static const char *strings[] = {"Not Permitted", "MVE integer", 142 "MVE integer and float"}; 143 return parseStringAttribute("MVE_arch", tag, makeArrayRef(strings)); 144 } 145 146 Error ARMAttributeParser::PCS_config(AttrType tag) { 147 static const char *strings[] = { 148 "None", "Bare Platform", "Linux Application", "Linux DSO", "Palm OS 2004", 149 "Reserved (Palm OS)", "Symbian OS 2004", "Reserved (Symbian OS)"}; 150 return parseStringAttribute("PCS_config", tag, makeArrayRef(strings)); 151 } 152 153 Error ARMAttributeParser::ABI_PCS_R9_use(AttrType tag) { 154 static const char *strings[] = {"v6", "Static Base", "TLS", "Unused"}; 155 return parseStringAttribute("ABI_PCS_R9_use", tag, makeArrayRef(strings)); 156 } 157 158 Error ARMAttributeParser::ABI_PCS_RW_data(AttrType tag) { 159 static const char *strings[] = {"Absolute", "PC-relative", "SB-relative", 160 "Not Permitted"}; 161 return parseStringAttribute("ABI_PCS_RW_data", tag, makeArrayRef(strings)); 162 } 163 164 Error ARMAttributeParser::ABI_PCS_RO_data(AttrType tag) { 165 static const char *strings[] = {"Absolute", "PC-relative", "Not Permitted"}; 166 return parseStringAttribute("ABI_PCS_RO_data", tag, makeArrayRef(strings)); 167 } 168 169 Error ARMAttributeParser::ABI_PCS_GOT_use(AttrType tag) { 170 static const char *strings[] = {"Not Permitted", "Direct", "GOT-Indirect"}; 171 return parseStringAttribute("ABI_PCS_GOT_use", tag, makeArrayRef(strings)); 172 } 173 174 Error ARMAttributeParser::ABI_PCS_wchar_t(AttrType tag) { 175 static const char *strings[] = {"Not Permitted", "Unknown", "2-byte", 176 "Unknown", "4-byte"}; 177 return parseStringAttribute("ABI_PCS_wchar_t", tag, makeArrayRef(strings)); 178 } 179 180 Error ARMAttributeParser::ABI_FP_rounding(AttrType tag) { 181 static const char *strings[] = {"IEEE-754", "Runtime"}; 182 return parseStringAttribute("ABI_FP_rounding", tag, makeArrayRef(strings)); 183 } 184 185 Error ARMAttributeParser::ABI_FP_denormal(AttrType tag) { 186 static const char *strings[] = {"Unsupported", "IEEE-754", "Sign Only"}; 187 return parseStringAttribute("ABI_FP_denormal", tag, makeArrayRef(strings)); 188 } 189 190 Error ARMAttributeParser::ABI_FP_exceptions(AttrType tag) { 191 static const char *strings[] = {"Not Permitted", "IEEE-754"}; 192 return parseStringAttribute("ABI_FP_exceptions", tag, makeArrayRef(strings)); 193 } 194 Error ARMAttributeParser::ABI_FP_user_exceptions(AttrType tag) { 195 static const char *strings[] = {"Not Permitted", "IEEE-754"}; 196 return parseStringAttribute("ABI_FP_user_exceptions", tag, 197 makeArrayRef(strings)); 198 } 199 200 Error ARMAttributeParser::ABI_FP_number_model(AttrType tag) { 201 static const char *strings[] = {"Not Permitted", "Finite Only", "RTABI", 202 "IEEE-754"}; 203 return parseStringAttribute("ABI_FP_number_model", tag, 204 makeArrayRef(strings)); 205 } 206 207 Error ARMAttributeParser::ABI_align_needed(AttrType tag) { 208 static const char *strings[] = {"Not Permitted", "8-byte alignment", 209 "4-byte alignment", "Reserved"}; 210 211 uint64_t value = de.getULEB128(cursor); 212 213 std::string description; 214 if (value < array_lengthof(strings)) 215 description = strings[value]; 216 else if (value <= 12) 217 description = "8-byte alignment, " + utostr(1ULL << value) + 218 "-byte extended alignment"; 219 else 220 description = "Invalid"; 221 222 printAttribute(tag, value, description); 223 return Error::success(); 224 } 225 226 Error ARMAttributeParser::ABI_align_preserved(AttrType tag) { 227 static const char *strings[] = {"Not Required", "8-byte data alignment", 228 "8-byte data and code alignment", "Reserved"}; 229 230 uint64_t value = de.getULEB128(cursor); 231 232 std::string description; 233 if (value < array_lengthof(strings)) 234 description = std::string(strings[value]); 235 else if (value <= 12) 236 description = std::string("8-byte stack alignment, ") + 237 utostr(1ULL << value) + std::string("-byte data alignment"); 238 else 239 description = "Invalid"; 240 241 printAttribute(tag, value, description); 242 return Error::success(); 243 } 244 245 Error ARMAttributeParser::ABI_enum_size(AttrType tag) { 246 static const char *strings[] = {"Not Permitted", "Packed", "Int32", 247 "External Int32"}; 248 return parseStringAttribute("ABI_enum_size", tag, makeArrayRef(strings)); 249 } 250 251 Error ARMAttributeParser::ABI_HardFP_use(AttrType tag) { 252 static const char *strings[] = {"Tag_FP_arch", "Single-Precision", "Reserved", 253 "Tag_FP_arch (deprecated)"}; 254 return parseStringAttribute("ABI_HardFP_use", tag, makeArrayRef(strings)); 255 } 256 257 Error ARMAttributeParser::ABI_VFP_args(AttrType tag) { 258 static const char *strings[] = {"AAPCS", "AAPCS VFP", "Custom", 259 "Not Permitted"}; 260 return parseStringAttribute("ABI_VFP_args", tag, makeArrayRef(strings)); 261 } 262 263 Error ARMAttributeParser::ABI_WMMX_args(AttrType tag) { 264 static const char *strings[] = {"AAPCS", "iWMMX", "Custom"}; 265 return parseStringAttribute("ABI_WMMX_args", tag, makeArrayRef(strings)); 266 } 267 268 Error ARMAttributeParser::ABI_optimization_goals(AttrType tag) { 269 static const char *strings[] = { 270 "None", "Speed", "Aggressive Speed", "Size", "Aggressive Size", "Debugging", 271 "Best Debugging" 272 }; 273 return parseStringAttribute("ABI_optimization_goals", tag, 274 makeArrayRef(strings)); 275 } 276 277 Error ARMAttributeParser::ABI_FP_optimization_goals(AttrType tag) { 278 static const char *strings[] = { 279 "None", "Speed", "Aggressive Speed", "Size", "Aggressive Size", 280 "Accuracy", "Best Accuracy"}; 281 return parseStringAttribute("ABI_FP_optimization_goals", tag, 282 makeArrayRef(strings)); 283 } 284 285 Error ARMAttributeParser::compatibility(AttrType tag) { 286 uint64_t integer = de.getULEB128(cursor); 287 StringRef string = de.getCStrRef(cursor); 288 289 if (sw) { 290 DictScope scope(*sw, "Attribute"); 291 sw->printNumber("Tag", tag); 292 sw->startLine() << "Value: " << integer << ", " << string << '\n'; 293 sw->printString("TagName", 294 ELFAttrs::attrTypeAsString(tag, tagToStringMap, 295 /*hasTagPrefix=*/false)); 296 switch (integer) { 297 case 0: 298 sw->printString("Description", StringRef("No Specific Requirements")); 299 break; 300 case 1: 301 sw->printString("Description", StringRef("AEABI Conformant")); 302 break; 303 default: 304 sw->printString("Description", StringRef("AEABI Non-Conformant")); 305 break; 306 } 307 } 308 return Error::success(); 309 } 310 311 Error ARMAttributeParser::CPU_unaligned_access(AttrType tag) { 312 static const char *strings[] = {"Not Permitted", "v6-style"}; 313 return parseStringAttribute("CPU_unaligned_access", tag, 314 makeArrayRef(strings)); 315 } 316 317 Error ARMAttributeParser::FP_HP_extension(AttrType tag) { 318 static const char *strings[] = {"If Available", "Permitted"}; 319 return parseStringAttribute("FP_HP_extension", tag, makeArrayRef(strings)); 320 } 321 322 Error ARMAttributeParser::ABI_FP_16bit_format(AttrType tag) { 323 static const char *strings[] = {"Not Permitted", "IEEE-754", "VFPv3"}; 324 return parseStringAttribute("ABI_FP_16bit_format", tag, 325 makeArrayRef(strings)); 326 } 327 328 Error ARMAttributeParser::MPextension_use(AttrType tag) { 329 static const char *strings[] = {"Not Permitted", "Permitted"}; 330 return parseStringAttribute("MPextension_use", tag, makeArrayRef(strings)); 331 } 332 333 Error ARMAttributeParser::DIV_use(AttrType tag) { 334 static const char *strings[] = {"If Available", "Not Permitted", "Permitted"}; 335 return parseStringAttribute("DIV_use", tag, makeArrayRef(strings)); 336 } 337 338 Error ARMAttributeParser::DSP_extension(AttrType tag) { 339 static const char *strings[] = {"Not Permitted", "Permitted"}; 340 return parseStringAttribute("DSP_extension", tag, makeArrayRef(strings)); 341 } 342 343 Error ARMAttributeParser::T2EE_use(AttrType tag) { 344 static const char *strings[] = {"Not Permitted", "Permitted"}; 345 return parseStringAttribute("T2EE_use", tag, makeArrayRef(strings)); 346 } 347 348 Error ARMAttributeParser::Virtualization_use(AttrType tag) { 349 static const char *strings[] = {"Not Permitted", "TrustZone", 350 "Virtualization Extensions", 351 "TrustZone + Virtualization Extensions"}; 352 return parseStringAttribute("Virtualization_use", tag, makeArrayRef(strings)); 353 } 354 355 Error ARMAttributeParser::PAC_extension(ARMBuildAttrs::AttrType tag) { 356 static const char *strings[] = {"Not Permitted", "Permitted in NOP space", 357 "Permitted"}; 358 return parseStringAttribute("PAC_extension", tag, makeArrayRef(strings)); 359 } 360 361 Error ARMAttributeParser::BTI_extension(ARMBuildAttrs::AttrType tag) { 362 static const char *strings[] = {"Not Permitted", "Permitted in NOP space", 363 "Permitted"}; 364 return parseStringAttribute("BTI_extension", tag, makeArrayRef(strings)); 365 } 366 367 Error ARMAttributeParser::PACRET_use(ARMBuildAttrs::AttrType tag) { 368 static const char *strings[] = {"Not Used", "Used"}; 369 return parseStringAttribute("PACRET_use", tag, makeArrayRef(strings)); 370 } 371 372 Error ARMAttributeParser::BTI_use(ARMBuildAttrs::AttrType tag) { 373 static const char *strings[] = {"Not Used", "Used"}; 374 return parseStringAttribute("BTI_use", tag, makeArrayRef(strings)); 375 } 376 377 Error ARMAttributeParser::nodefaults(AttrType tag) { 378 uint64_t value = de.getULEB128(cursor); 379 printAttribute(tag, value, "Unspecified Tags UNDEFINED"); 380 return Error::success(); 381 } 382 383 Error ARMAttributeParser::handler(uint64_t tag, bool &handled) { 384 handled = false; 385 for (unsigned AHI = 0, AHE = array_lengthof(displayRoutines); AHI != AHE; 386 ++AHI) { 387 if (uint64_t(displayRoutines[AHI].attribute) == tag) { 388 if (Error e = 389 (this->*displayRoutines[AHI].routine)(static_cast<AttrType>(tag))) 390 return e; 391 handled = true; 392 break; 393 } 394 } 395 396 return Error::success(); 397 } 398