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