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