1 //===-- ABISysV_arm.cpp ---------------------------------------------------===// 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 "ABISysV_arm.h" 10 11 #include <optional> 12 #include <vector> 13 14 #include "llvm/ADT/STLExtras.h" 15 #include "llvm/TargetParser/Triple.h" 16 17 #include "lldb/Core/Module.h" 18 #include "lldb/Core/PluginManager.h" 19 #include "lldb/Core/Value.h" 20 #include "lldb/Core/ValueObjectConstResult.h" 21 #include "lldb/Symbol/UnwindPlan.h" 22 #include "lldb/Target/Process.h" 23 #include "lldb/Target/RegisterContext.h" 24 #include "lldb/Target/Target.h" 25 #include "lldb/Target/Thread.h" 26 #include "lldb/Utility/ConstString.h" 27 #include "lldb/Utility/RegisterValue.h" 28 #include "lldb/Utility/Scalar.h" 29 #include "lldb/Utility/Status.h" 30 31 #include "Plugins/Process/Utility/ARMDefines.h" 32 #include "Utility/ARM_DWARF_Registers.h" 33 #include "Utility/ARM_ehframe_Registers.h" 34 35 using namespace lldb; 36 using namespace lldb_private; 37 38 LLDB_PLUGIN_DEFINE(ABISysV_arm) 39 40 static const RegisterInfo g_register_infos[] = { 41 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME 42 // DWARF GENERIC PROCESS PLUGIN 43 // LLDB NATIVE VALUE REGS INVALIDATE REGS 44 // ========== ======= == === ============= ============ 45 // ======================= =================== =========================== 46 // ======================= ====================== ========== 47 // =============== 48 {"r0", 49 nullptr, 50 4, 51 0, 52 eEncodingUint, 53 eFormatHex, 54 {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM, 55 LLDB_INVALID_REGNUM}, 56 nullptr, 57 nullptr, 58 nullptr, 59 }, 60 {"r1", 61 nullptr, 62 4, 63 0, 64 eEncodingUint, 65 eFormatHex, 66 {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM, 67 LLDB_INVALID_REGNUM}, 68 nullptr, 69 nullptr, 70 nullptr, 71 }, 72 {"r2", 73 nullptr, 74 4, 75 0, 76 eEncodingUint, 77 eFormatHex, 78 {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM, 79 LLDB_INVALID_REGNUM}, 80 nullptr, 81 nullptr, 82 nullptr, 83 }, 84 {"r3", 85 nullptr, 86 4, 87 0, 88 eEncodingUint, 89 eFormatHex, 90 {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM, 91 LLDB_INVALID_REGNUM}, 92 nullptr, 93 nullptr, 94 nullptr, 95 }, 96 {"r4", 97 nullptr, 98 4, 99 0, 100 eEncodingUint, 101 eFormatHex, 102 {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 103 LLDB_INVALID_REGNUM}, 104 nullptr, 105 nullptr, 106 nullptr, 107 }, 108 {"r5", 109 nullptr, 110 4, 111 0, 112 eEncodingUint, 113 eFormatHex, 114 {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 115 LLDB_INVALID_REGNUM}, 116 nullptr, 117 nullptr, 118 nullptr, 119 }, 120 {"r6", 121 nullptr, 122 4, 123 0, 124 eEncodingUint, 125 eFormatHex, 126 {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 127 LLDB_INVALID_REGNUM}, 128 nullptr, 129 nullptr, 130 nullptr, 131 }, 132 {"r7", 133 nullptr, 134 4, 135 0, 136 eEncodingUint, 137 eFormatHex, 138 {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, 139 LLDB_INVALID_REGNUM}, 140 nullptr, 141 nullptr, 142 nullptr, 143 }, 144 {"r8", 145 nullptr, 146 4, 147 0, 148 eEncodingUint, 149 eFormatHex, 150 {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 151 LLDB_INVALID_REGNUM}, 152 nullptr, 153 nullptr, 154 nullptr, 155 }, 156 {"r9", 157 nullptr, 158 4, 159 0, 160 eEncodingUint, 161 eFormatHex, 162 {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 163 LLDB_INVALID_REGNUM}, 164 nullptr, 165 nullptr, 166 nullptr, 167 }, 168 {"r10", 169 nullptr, 170 4, 171 0, 172 eEncodingUint, 173 eFormatHex, 174 {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 175 LLDB_INVALID_REGNUM}, 176 nullptr, 177 nullptr, 178 nullptr, 179 }, 180 {"r11", 181 nullptr, 182 4, 183 0, 184 eEncodingUint, 185 eFormatHex, 186 {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 187 LLDB_INVALID_REGNUM}, 188 nullptr, 189 nullptr, 190 nullptr, 191 }, 192 {"r12", 193 nullptr, 194 4, 195 0, 196 eEncodingUint, 197 eFormatHex, 198 {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 199 LLDB_INVALID_REGNUM}, 200 nullptr, 201 nullptr, 202 nullptr, 203 }, 204 {"sp", 205 "r13", 206 4, 207 0, 208 eEncodingUint, 209 eFormatHex, 210 {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, 211 LLDB_INVALID_REGNUM}, 212 nullptr, 213 nullptr, 214 nullptr, 215 }, 216 {"lr", 217 "r14", 218 4, 219 0, 220 eEncodingUint, 221 eFormatHex, 222 {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM, 223 LLDB_INVALID_REGNUM}, 224 nullptr, 225 nullptr, 226 nullptr, 227 }, 228 {"pc", 229 "r15", 230 4, 231 0, 232 eEncodingUint, 233 eFormatHex, 234 {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, 235 LLDB_INVALID_REGNUM}, 236 nullptr, 237 nullptr, 238 nullptr, 239 }, 240 {"cpsr", 241 "psr", 242 4, 243 0, 244 eEncodingUint, 245 eFormatHex, 246 {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, 247 LLDB_INVALID_REGNUM}, 248 nullptr, 249 nullptr, 250 nullptr, 251 }, 252 {"s0", 253 nullptr, 254 4, 255 0, 256 eEncodingIEEE754, 257 eFormatFloat, 258 {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 259 LLDB_INVALID_REGNUM}, 260 nullptr, 261 nullptr, 262 nullptr, 263 }, 264 {"s1", 265 nullptr, 266 4, 267 0, 268 eEncodingIEEE754, 269 eFormatFloat, 270 {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 271 LLDB_INVALID_REGNUM}, 272 nullptr, 273 nullptr, 274 nullptr, 275 }, 276 {"s2", 277 nullptr, 278 4, 279 0, 280 eEncodingIEEE754, 281 eFormatFloat, 282 {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 283 LLDB_INVALID_REGNUM}, 284 nullptr, 285 nullptr, 286 nullptr, 287 }, 288 {"s3", 289 nullptr, 290 4, 291 0, 292 eEncodingIEEE754, 293 eFormatFloat, 294 {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 295 LLDB_INVALID_REGNUM}, 296 nullptr, 297 nullptr, 298 nullptr, 299 }, 300 {"s4", 301 nullptr, 302 4, 303 0, 304 eEncodingIEEE754, 305 eFormatFloat, 306 {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 307 LLDB_INVALID_REGNUM}, 308 nullptr, 309 nullptr, 310 nullptr, 311 }, 312 {"s5", 313 nullptr, 314 4, 315 0, 316 eEncodingIEEE754, 317 eFormatFloat, 318 {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 319 LLDB_INVALID_REGNUM}, 320 nullptr, 321 nullptr, 322 nullptr, 323 }, 324 {"s6", 325 nullptr, 326 4, 327 0, 328 eEncodingIEEE754, 329 eFormatFloat, 330 {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 331 LLDB_INVALID_REGNUM}, 332 nullptr, 333 nullptr, 334 nullptr, 335 }, 336 {"s7", 337 nullptr, 338 4, 339 0, 340 eEncodingIEEE754, 341 eFormatFloat, 342 {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 343 LLDB_INVALID_REGNUM}, 344 nullptr, 345 nullptr, 346 nullptr, 347 }, 348 {"s8", 349 nullptr, 350 4, 351 0, 352 eEncodingIEEE754, 353 eFormatFloat, 354 {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 355 LLDB_INVALID_REGNUM}, 356 nullptr, 357 nullptr, 358 nullptr, 359 }, 360 {"s9", 361 nullptr, 362 4, 363 0, 364 eEncodingIEEE754, 365 eFormatFloat, 366 {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 367 LLDB_INVALID_REGNUM}, 368 nullptr, 369 nullptr, 370 nullptr, 371 }, 372 {"s10", 373 nullptr, 374 4, 375 0, 376 eEncodingIEEE754, 377 eFormatFloat, 378 {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 379 LLDB_INVALID_REGNUM}, 380 nullptr, 381 nullptr, 382 nullptr, 383 }, 384 {"s11", 385 nullptr, 386 4, 387 0, 388 eEncodingIEEE754, 389 eFormatFloat, 390 {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 391 LLDB_INVALID_REGNUM}, 392 nullptr, 393 nullptr, 394 nullptr, 395 }, 396 {"s12", 397 nullptr, 398 4, 399 0, 400 eEncodingIEEE754, 401 eFormatFloat, 402 {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 403 LLDB_INVALID_REGNUM}, 404 nullptr, 405 nullptr, 406 nullptr, 407 }, 408 {"s13", 409 nullptr, 410 4, 411 0, 412 eEncodingIEEE754, 413 eFormatFloat, 414 {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 415 LLDB_INVALID_REGNUM}, 416 nullptr, 417 nullptr, 418 nullptr, 419 }, 420 {"s14", 421 nullptr, 422 4, 423 0, 424 eEncodingIEEE754, 425 eFormatFloat, 426 {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 427 LLDB_INVALID_REGNUM}, 428 nullptr, 429 nullptr, 430 nullptr, 431 }, 432 {"s15", 433 nullptr, 434 4, 435 0, 436 eEncodingIEEE754, 437 eFormatFloat, 438 {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 439 LLDB_INVALID_REGNUM}, 440 nullptr, 441 nullptr, 442 nullptr, 443 }, 444 {"s16", 445 nullptr, 446 4, 447 0, 448 eEncodingIEEE754, 449 eFormatFloat, 450 {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 451 LLDB_INVALID_REGNUM}, 452 nullptr, 453 nullptr, 454 nullptr, 455 }, 456 {"s17", 457 nullptr, 458 4, 459 0, 460 eEncodingIEEE754, 461 eFormatFloat, 462 {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 463 LLDB_INVALID_REGNUM}, 464 nullptr, 465 nullptr, 466 nullptr, 467 }, 468 {"s18", 469 nullptr, 470 4, 471 0, 472 eEncodingIEEE754, 473 eFormatFloat, 474 {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 475 LLDB_INVALID_REGNUM}, 476 nullptr, 477 nullptr, 478 nullptr, 479 }, 480 {"s19", 481 nullptr, 482 4, 483 0, 484 eEncodingIEEE754, 485 eFormatFloat, 486 {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 487 LLDB_INVALID_REGNUM}, 488 nullptr, 489 nullptr, 490 nullptr, 491 }, 492 {"s20", 493 nullptr, 494 4, 495 0, 496 eEncodingIEEE754, 497 eFormatFloat, 498 {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 499 LLDB_INVALID_REGNUM}, 500 nullptr, 501 nullptr, 502 nullptr, 503 }, 504 {"s21", 505 nullptr, 506 4, 507 0, 508 eEncodingIEEE754, 509 eFormatFloat, 510 {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 511 LLDB_INVALID_REGNUM}, 512 nullptr, 513 nullptr, 514 nullptr, 515 }, 516 {"s22", 517 nullptr, 518 4, 519 0, 520 eEncodingIEEE754, 521 eFormatFloat, 522 {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 523 LLDB_INVALID_REGNUM}, 524 nullptr, 525 nullptr, 526 nullptr, 527 }, 528 {"s23", 529 nullptr, 530 4, 531 0, 532 eEncodingIEEE754, 533 eFormatFloat, 534 {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 535 LLDB_INVALID_REGNUM}, 536 nullptr, 537 nullptr, 538 nullptr, 539 }, 540 {"s24", 541 nullptr, 542 4, 543 0, 544 eEncodingIEEE754, 545 eFormatFloat, 546 {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 547 LLDB_INVALID_REGNUM}, 548 nullptr, 549 nullptr, 550 nullptr, 551 }, 552 {"s25", 553 nullptr, 554 4, 555 0, 556 eEncodingIEEE754, 557 eFormatFloat, 558 {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 559 LLDB_INVALID_REGNUM}, 560 nullptr, 561 nullptr, 562 nullptr, 563 }, 564 {"s26", 565 nullptr, 566 4, 567 0, 568 eEncodingIEEE754, 569 eFormatFloat, 570 {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 571 LLDB_INVALID_REGNUM}, 572 nullptr, 573 nullptr, 574 nullptr, 575 }, 576 {"s27", 577 nullptr, 578 4, 579 0, 580 eEncodingIEEE754, 581 eFormatFloat, 582 {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 583 LLDB_INVALID_REGNUM}, 584 nullptr, 585 nullptr, 586 nullptr, 587 }, 588 {"s28", 589 nullptr, 590 4, 591 0, 592 eEncodingIEEE754, 593 eFormatFloat, 594 {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 595 LLDB_INVALID_REGNUM}, 596 nullptr, 597 nullptr, 598 nullptr, 599 }, 600 {"s29", 601 nullptr, 602 4, 603 0, 604 eEncodingIEEE754, 605 eFormatFloat, 606 {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 607 LLDB_INVALID_REGNUM}, 608 nullptr, 609 nullptr, 610 nullptr, 611 }, 612 {"s30", 613 nullptr, 614 4, 615 0, 616 eEncodingIEEE754, 617 eFormatFloat, 618 {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 619 LLDB_INVALID_REGNUM}, 620 nullptr, 621 nullptr, 622 nullptr, 623 }, 624 {"s31", 625 nullptr, 626 4, 627 0, 628 eEncodingIEEE754, 629 eFormatFloat, 630 {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 631 LLDB_INVALID_REGNUM}, 632 nullptr, 633 nullptr, 634 nullptr, 635 }, 636 {"fpscr", 637 nullptr, 638 4, 639 0, 640 eEncodingUint, 641 eFormatHex, 642 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 643 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 644 nullptr, 645 nullptr, 646 nullptr, 647 }, 648 {"d0", 649 nullptr, 650 8, 651 0, 652 eEncodingIEEE754, 653 eFormatFloat, 654 {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 655 LLDB_INVALID_REGNUM}, 656 nullptr, 657 nullptr, 658 nullptr, 659 }, 660 {"d1", 661 nullptr, 662 8, 663 0, 664 eEncodingIEEE754, 665 eFormatFloat, 666 {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 667 LLDB_INVALID_REGNUM}, 668 nullptr, 669 nullptr, 670 nullptr, 671 }, 672 {"d2", 673 nullptr, 674 8, 675 0, 676 eEncodingIEEE754, 677 eFormatFloat, 678 {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 679 LLDB_INVALID_REGNUM}, 680 nullptr, 681 nullptr, 682 nullptr, 683 }, 684 {"d3", 685 nullptr, 686 8, 687 0, 688 eEncodingIEEE754, 689 eFormatFloat, 690 {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 691 LLDB_INVALID_REGNUM}, 692 nullptr, 693 nullptr, 694 nullptr, 695 }, 696 {"d4", 697 nullptr, 698 8, 699 0, 700 eEncodingIEEE754, 701 eFormatFloat, 702 {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 703 LLDB_INVALID_REGNUM}, 704 nullptr, 705 nullptr, 706 nullptr, 707 }, 708 {"d5", 709 nullptr, 710 8, 711 0, 712 eEncodingIEEE754, 713 eFormatFloat, 714 {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 715 LLDB_INVALID_REGNUM}, 716 nullptr, 717 nullptr, 718 nullptr, 719 }, 720 {"d6", 721 nullptr, 722 8, 723 0, 724 eEncodingIEEE754, 725 eFormatFloat, 726 {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 727 LLDB_INVALID_REGNUM}, 728 nullptr, 729 nullptr, 730 nullptr, 731 }, 732 {"d7", 733 nullptr, 734 8, 735 0, 736 eEncodingIEEE754, 737 eFormatFloat, 738 {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 739 LLDB_INVALID_REGNUM}, 740 nullptr, 741 nullptr, 742 nullptr, 743 }, 744 {"d8", 745 nullptr, 746 8, 747 0, 748 eEncodingIEEE754, 749 eFormatFloat, 750 {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 751 LLDB_INVALID_REGNUM}, 752 nullptr, 753 nullptr, 754 nullptr, 755 }, 756 {"d9", 757 nullptr, 758 8, 759 0, 760 eEncodingIEEE754, 761 eFormatFloat, 762 {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 763 LLDB_INVALID_REGNUM}, 764 nullptr, 765 nullptr, 766 nullptr, 767 }, 768 {"d10", 769 nullptr, 770 8, 771 0, 772 eEncodingIEEE754, 773 eFormatFloat, 774 {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 775 LLDB_INVALID_REGNUM}, 776 nullptr, 777 nullptr, 778 nullptr, 779 }, 780 {"d11", 781 nullptr, 782 8, 783 0, 784 eEncodingIEEE754, 785 eFormatFloat, 786 {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 787 LLDB_INVALID_REGNUM}, 788 nullptr, 789 nullptr, 790 nullptr, 791 }, 792 {"d12", 793 nullptr, 794 8, 795 0, 796 eEncodingIEEE754, 797 eFormatFloat, 798 {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 799 LLDB_INVALID_REGNUM}, 800 nullptr, 801 nullptr, 802 nullptr, 803 }, 804 {"d13", 805 nullptr, 806 8, 807 0, 808 eEncodingIEEE754, 809 eFormatFloat, 810 {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 811 LLDB_INVALID_REGNUM}, 812 nullptr, 813 nullptr, 814 nullptr, 815 }, 816 {"d14", 817 nullptr, 818 8, 819 0, 820 eEncodingIEEE754, 821 eFormatFloat, 822 {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 823 LLDB_INVALID_REGNUM}, 824 nullptr, 825 nullptr, 826 nullptr, 827 }, 828 {"d15", 829 nullptr, 830 8, 831 0, 832 eEncodingIEEE754, 833 eFormatFloat, 834 {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 835 LLDB_INVALID_REGNUM}, 836 nullptr, 837 nullptr, 838 nullptr, 839 }, 840 {"d16", 841 nullptr, 842 8, 843 0, 844 eEncodingIEEE754, 845 eFormatFloat, 846 {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 847 LLDB_INVALID_REGNUM}, 848 nullptr, 849 nullptr, 850 nullptr, 851 }, 852 {"d17", 853 nullptr, 854 8, 855 0, 856 eEncodingIEEE754, 857 eFormatFloat, 858 {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 859 LLDB_INVALID_REGNUM}, 860 nullptr, 861 nullptr, 862 nullptr, 863 }, 864 {"d18", 865 nullptr, 866 8, 867 0, 868 eEncodingIEEE754, 869 eFormatFloat, 870 {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 871 LLDB_INVALID_REGNUM}, 872 nullptr, 873 nullptr, 874 nullptr, 875 }, 876 {"d19", 877 nullptr, 878 8, 879 0, 880 eEncodingIEEE754, 881 eFormatFloat, 882 {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 883 LLDB_INVALID_REGNUM}, 884 nullptr, 885 nullptr, 886 nullptr, 887 }, 888 {"d20", 889 nullptr, 890 8, 891 0, 892 eEncodingIEEE754, 893 eFormatFloat, 894 {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 895 LLDB_INVALID_REGNUM}, 896 nullptr, 897 nullptr, 898 nullptr, 899 }, 900 {"d21", 901 nullptr, 902 8, 903 0, 904 eEncodingIEEE754, 905 eFormatFloat, 906 {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 907 LLDB_INVALID_REGNUM}, 908 nullptr, 909 nullptr, 910 nullptr, 911 }, 912 {"d22", 913 nullptr, 914 8, 915 0, 916 eEncodingIEEE754, 917 eFormatFloat, 918 {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 919 LLDB_INVALID_REGNUM}, 920 nullptr, 921 nullptr, 922 nullptr, 923 }, 924 {"d23", 925 nullptr, 926 8, 927 0, 928 eEncodingIEEE754, 929 eFormatFloat, 930 {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 931 LLDB_INVALID_REGNUM}, 932 nullptr, 933 nullptr, 934 nullptr, 935 }, 936 {"d24", 937 nullptr, 938 8, 939 0, 940 eEncodingIEEE754, 941 eFormatFloat, 942 {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 943 LLDB_INVALID_REGNUM}, 944 nullptr, 945 nullptr, 946 nullptr, 947 }, 948 {"d25", 949 nullptr, 950 8, 951 0, 952 eEncodingIEEE754, 953 eFormatFloat, 954 {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 955 LLDB_INVALID_REGNUM}, 956 nullptr, 957 nullptr, 958 nullptr, 959 }, 960 {"d26", 961 nullptr, 962 8, 963 0, 964 eEncodingIEEE754, 965 eFormatFloat, 966 {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 967 LLDB_INVALID_REGNUM}, 968 nullptr, 969 nullptr, 970 nullptr, 971 }, 972 {"d27", 973 nullptr, 974 8, 975 0, 976 eEncodingIEEE754, 977 eFormatFloat, 978 {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 979 LLDB_INVALID_REGNUM}, 980 nullptr, 981 nullptr, 982 nullptr, 983 }, 984 {"d28", 985 nullptr, 986 8, 987 0, 988 eEncodingIEEE754, 989 eFormatFloat, 990 {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 991 LLDB_INVALID_REGNUM}, 992 nullptr, 993 nullptr, 994 nullptr, 995 }, 996 {"d29", 997 nullptr, 998 8, 999 0, 1000 eEncodingIEEE754, 1001 eFormatFloat, 1002 {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 1003 LLDB_INVALID_REGNUM}, 1004 nullptr, 1005 nullptr, 1006 nullptr, 1007 }, 1008 {"d30", 1009 nullptr, 1010 8, 1011 0, 1012 eEncodingIEEE754, 1013 eFormatFloat, 1014 {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 1015 LLDB_INVALID_REGNUM}, 1016 nullptr, 1017 nullptr, 1018 nullptr, 1019 }, 1020 {"d31", 1021 nullptr, 1022 8, 1023 0, 1024 eEncodingIEEE754, 1025 eFormatFloat, 1026 {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 1027 LLDB_INVALID_REGNUM}, 1028 nullptr, 1029 nullptr, 1030 nullptr, 1031 }, 1032 {"r8_usr", 1033 nullptr, 1034 4, 1035 0, 1036 eEncodingUint, 1037 eFormatHex, 1038 {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM, 1039 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1040 nullptr, 1041 nullptr, 1042 nullptr, 1043 }, 1044 {"r9_usr", 1045 nullptr, 1046 4, 1047 0, 1048 eEncodingUint, 1049 eFormatHex, 1050 {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM, 1051 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1052 nullptr, 1053 nullptr, 1054 nullptr, 1055 }, 1056 {"r10_usr", 1057 nullptr, 1058 4, 1059 0, 1060 eEncodingUint, 1061 eFormatHex, 1062 {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM, 1063 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1064 nullptr, 1065 nullptr, 1066 nullptr, 1067 }, 1068 {"r11_usr", 1069 nullptr, 1070 4, 1071 0, 1072 eEncodingUint, 1073 eFormatHex, 1074 {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM, 1075 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1076 nullptr, 1077 nullptr, 1078 nullptr, 1079 }, 1080 {"r12_usr", 1081 nullptr, 1082 4, 1083 0, 1084 eEncodingUint, 1085 eFormatHex, 1086 {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM, 1087 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1088 nullptr, 1089 nullptr, 1090 nullptr, 1091 }, 1092 {"r13_usr", 1093 "sp_usr", 1094 4, 1095 0, 1096 eEncodingUint, 1097 eFormatHex, 1098 {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM, 1099 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1100 nullptr, 1101 nullptr, 1102 nullptr, 1103 }, 1104 {"r14_usr", 1105 "lr_usr", 1106 4, 1107 0, 1108 eEncodingUint, 1109 eFormatHex, 1110 {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM, 1111 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1112 nullptr, 1113 nullptr, 1114 nullptr, 1115 }, 1116 {"r8_fiq", 1117 nullptr, 1118 4, 1119 0, 1120 eEncodingUint, 1121 eFormatHex, 1122 {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM, 1123 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1124 nullptr, 1125 nullptr, 1126 nullptr, 1127 }, 1128 {"r9_fiq", 1129 nullptr, 1130 4, 1131 0, 1132 eEncodingUint, 1133 eFormatHex, 1134 {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM, 1135 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1136 nullptr, 1137 nullptr, 1138 nullptr, 1139 }, 1140 {"r10_fiq", 1141 nullptr, 1142 4, 1143 0, 1144 eEncodingUint, 1145 eFormatHex, 1146 {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM, 1147 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1148 nullptr, 1149 nullptr, 1150 nullptr, 1151 }, 1152 {"r11_fiq", 1153 nullptr, 1154 4, 1155 0, 1156 eEncodingUint, 1157 eFormatHex, 1158 {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM, 1159 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1160 nullptr, 1161 nullptr, 1162 nullptr, 1163 }, 1164 {"r12_fiq", 1165 nullptr, 1166 4, 1167 0, 1168 eEncodingUint, 1169 eFormatHex, 1170 {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM, 1171 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1172 nullptr, 1173 nullptr, 1174 nullptr, 1175 }, 1176 {"r13_fiq", 1177 "sp_fiq", 1178 4, 1179 0, 1180 eEncodingUint, 1181 eFormatHex, 1182 {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM, 1183 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1184 nullptr, 1185 nullptr, 1186 nullptr, 1187 }, 1188 {"r14_fiq", 1189 "lr_fiq", 1190 4, 1191 0, 1192 eEncodingUint, 1193 eFormatHex, 1194 {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM, 1195 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1196 nullptr, 1197 nullptr, 1198 nullptr, 1199 }, 1200 {"r13_irq", 1201 "sp_irq", 1202 4, 1203 0, 1204 eEncodingUint, 1205 eFormatHex, 1206 {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM, 1207 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1208 nullptr, 1209 nullptr, 1210 nullptr, 1211 }, 1212 {"r14_irq", 1213 "lr_irq", 1214 4, 1215 0, 1216 eEncodingUint, 1217 eFormatHex, 1218 {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM, 1219 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1220 nullptr, 1221 nullptr, 1222 nullptr, 1223 }, 1224 {"r13_abt", 1225 "sp_abt", 1226 4, 1227 0, 1228 eEncodingUint, 1229 eFormatHex, 1230 {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM, 1231 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1232 nullptr, 1233 nullptr, 1234 nullptr, 1235 }, 1236 {"r14_abt", 1237 "lr_abt", 1238 4, 1239 0, 1240 eEncodingUint, 1241 eFormatHex, 1242 {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM, 1243 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1244 nullptr, 1245 nullptr, 1246 nullptr, 1247 }, 1248 {"r13_und", 1249 "sp_und", 1250 4, 1251 0, 1252 eEncodingUint, 1253 eFormatHex, 1254 {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM, 1255 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1256 nullptr, 1257 nullptr, 1258 nullptr, 1259 }, 1260 {"r14_und", 1261 "lr_und", 1262 4, 1263 0, 1264 eEncodingUint, 1265 eFormatHex, 1266 {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM, 1267 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1268 nullptr, 1269 nullptr, 1270 nullptr, 1271 1272 }, 1273 {"r13_svc", 1274 "sp_svc", 1275 4, 1276 0, 1277 eEncodingUint, 1278 eFormatHex, 1279 {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM, 1280 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1281 nullptr, 1282 nullptr, 1283 nullptr, 1284 }, 1285 {"r14_svc", 1286 "lr_svc", 1287 4, 1288 0, 1289 eEncodingUint, 1290 eFormatHex, 1291 {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM, 1292 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, 1293 nullptr, 1294 nullptr, 1295 nullptr, 1296 }}; 1297 1298 static const uint32_t k_num_register_infos = std::size(g_register_infos); 1299 1300 const lldb_private::RegisterInfo * 1301 ABISysV_arm::GetRegisterInfoArray(uint32_t &count) { 1302 count = k_num_register_infos; 1303 return g_register_infos; 1304 } 1305 1306 size_t ABISysV_arm::GetRedZoneSize() const { return 0; } 1307 1308 // Static Functions 1309 1310 ABISP 1311 ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { 1312 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); 1313 const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor(); 1314 1315 if (vendor_type != llvm::Triple::Apple) { 1316 if ((arch_type == llvm::Triple::arm) || 1317 (arch_type == llvm::Triple::thumb)) { 1318 return ABISP( 1319 new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch))); 1320 } 1321 } 1322 1323 return ABISP(); 1324 } 1325 1326 bool ABISysV_arm::PrepareTrivialCall(Thread &thread, addr_t sp, 1327 addr_t function_addr, addr_t return_addr, 1328 llvm::ArrayRef<addr_t> args) const { 1329 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 1330 if (!reg_ctx) 1331 return false; 1332 1333 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 1334 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 1335 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 1336 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 1337 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( 1338 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 1339 1340 RegisterValue reg_value; 1341 1342 const uint8_t reg_names[] = { 1343 LLDB_REGNUM_GENERIC_ARG1, LLDB_REGNUM_GENERIC_ARG2, 1344 LLDB_REGNUM_GENERIC_ARG3, LLDB_REGNUM_GENERIC_ARG4}; 1345 1346 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end(); 1347 1348 for (size_t i = 0; i < std::size(reg_names); ++i) { 1349 if (ai == ae) 1350 break; 1351 1352 reg_value.SetUInt32(*ai); 1353 if (!reg_ctx->WriteRegister( 1354 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]), 1355 reg_value)) 1356 return false; 1357 1358 ++ai; 1359 } 1360 1361 if (ai != ae) { 1362 // Spill onto the stack 1363 size_t num_stack_regs = ae - ai; 1364 1365 sp -= (num_stack_regs * 4); 1366 // Keep the stack 8 byte aligned, not that we need to 1367 sp &= ~(8ull - 1ull); 1368 1369 // just using arg1 to get the right size 1370 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( 1371 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); 1372 1373 addr_t arg_pos = sp; 1374 1375 for (; ai != ae; ++ai) { 1376 reg_value.SetUInt32(*ai); 1377 if (reg_ctx 1378 ->WriteRegisterValueToMemory(reg_info, arg_pos, 1379 reg_info->byte_size, reg_value) 1380 .Fail()) 1381 return false; 1382 arg_pos += reg_info->byte_size; 1383 } 1384 } 1385 1386 TargetSP target_sp(thread.CalculateTarget()); 1387 Address so_addr; 1388 1389 // Figure out if our return address is ARM or Thumb by using the 1390 // Address::GetCallableLoadAddress(Target*) which will figure out the ARM 1391 // thumb-ness and set the correct address bits for us. 1392 so_addr.SetLoadAddress(return_addr, target_sp.get()); 1393 return_addr = so_addr.GetCallableLoadAddress(target_sp.get()); 1394 1395 // Set "lr" to the return address 1396 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr)) 1397 return false; 1398 1399 // Set "sp" to the requested value 1400 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp)) 1401 return false; 1402 1403 // If bit zero or 1 is set, this must be a thumb function, no need to figure 1404 // this out from the symbols. 1405 so_addr.SetLoadAddress(function_addr, target_sp.get()); 1406 function_addr = so_addr.GetCallableLoadAddress(target_sp.get()); 1407 1408 const RegisterInfo *cpsr_reg_info = 1409 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); 1410 const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0); 1411 1412 // Make a new CPSR and mask out any Thumb IT (if/then) bits 1413 uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK; 1414 // If bit zero or 1 is set, this must be thumb... 1415 if (function_addr & 1ull) 1416 new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR 1417 else 1418 new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR 1419 1420 if (new_cpsr != curr_cpsr) { 1421 if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr)) 1422 return false; 1423 } 1424 1425 function_addr &= 1426 ~1ull; // clear bit zero since the CPSR will take care of the mode for us 1427 1428 // Set "pc" to the address requested 1429 return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr); 1430 } 1431 1432 bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const { 1433 uint32_t num_values = values.GetSize(); 1434 1435 ExecutionContext exe_ctx(thread.shared_from_this()); 1436 // For now, assume that the types in the AST values come from the Target's 1437 // scratch AST. 1438 1439 // Extract the register context so we can read arguments from registers 1440 1441 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 1442 1443 if (!reg_ctx) 1444 return false; 1445 1446 addr_t sp = 0; 1447 1448 for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) { 1449 // We currently only support extracting values with Clang QualTypes. Do we 1450 // care about others? 1451 Value *value = values.GetValueAtIndex(value_idx); 1452 1453 if (!value) 1454 return false; 1455 1456 CompilerType compiler_type = value->GetCompilerType(); 1457 if (compiler_type) { 1458 bool is_signed = false; 1459 size_t bit_width = 0; 1460 if (compiler_type.IsIntegerOrEnumerationType(is_signed) || 1461 compiler_type.IsPointerOrReferenceType()) { 1462 if (std::optional<uint64_t> size = compiler_type.GetBitSize(&thread)) 1463 bit_width = *size; 1464 } else { 1465 // We only handle integer, pointer and reference types currently... 1466 return false; 1467 } 1468 1469 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) { 1470 if (value_idx < 4) { 1471 // Arguments 1-4 are in r0-r3... 1472 const RegisterInfo *arg_reg_info = nullptr; 1473 arg_reg_info = reg_ctx->GetRegisterInfo( 1474 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx); 1475 if (arg_reg_info) { 1476 RegisterValue reg_value; 1477 1478 if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) { 1479 if (is_signed) 1480 reg_value.SignExtend(bit_width); 1481 if (!reg_value.GetScalarValue(value->GetScalar())) 1482 return false; 1483 continue; 1484 } 1485 } 1486 return false; 1487 } else { 1488 if (sp == 0) { 1489 // Read the stack pointer if it already hasn't been read 1490 sp = reg_ctx->GetSP(0); 1491 if (sp == 0) 1492 return false; 1493 } 1494 1495 // Arguments 5 on up are on the stack 1496 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8; 1497 Status error; 1498 if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory( 1499 sp, arg_byte_size, is_signed, value->GetScalar(), error)) 1500 return false; 1501 1502 sp += arg_byte_size; 1503 } 1504 } 1505 } 1506 } 1507 return true; 1508 } 1509 1510 static bool GetReturnValuePassedInMemory(Thread &thread, 1511 RegisterContext *reg_ctx, 1512 size_t byte_size, Value &value) { 1513 Status error; 1514 DataBufferHeap buffer(byte_size, 0); 1515 1516 const RegisterInfo *r0_reg_info = 1517 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); 1518 uint32_t address = 1519 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; 1520 thread.GetProcess()->ReadMemory(address, buffer.GetBytes(), 1521 buffer.GetByteSize(), error); 1522 1523 if (error.Fail()) 1524 return false; 1525 1526 value.SetBytes(buffer.GetBytes(), buffer.GetByteSize()); 1527 return true; 1528 } 1529 1530 bool ABISysV_arm::IsArmHardFloat(Thread &thread) const { 1531 ProcessSP process_sp(thread.GetProcess()); 1532 if (process_sp) { 1533 const ArchSpec &arch(process_sp->GetTarget().GetArchitecture()); 1534 1535 return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0; 1536 } 1537 1538 return false; 1539 } 1540 1541 ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( 1542 Thread &thread, lldb_private::CompilerType &compiler_type) const { 1543 Value value; 1544 ValueObjectSP return_valobj_sp; 1545 1546 if (!compiler_type) 1547 return return_valobj_sp; 1548 1549 // value.SetContext (Value::eContextTypeClangType, 1550 // compiler_type.GetOpaqueQualType()); 1551 value.SetCompilerType(compiler_type); 1552 1553 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 1554 if (!reg_ctx) 1555 return return_valobj_sp; 1556 1557 bool is_signed; 1558 bool is_complex; 1559 uint32_t float_count; 1560 bool is_vfp_candidate = false; 1561 uint8_t vfp_count = 0; 1562 uint8_t vfp_byte_size = 0; 1563 1564 // Get the pointer to the first stack argument so we have a place to start 1565 // when reading data 1566 1567 const RegisterInfo *r0_reg_info = 1568 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); 1569 std::optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread); 1570 std::optional<uint64_t> byte_size = compiler_type.GetByteSize(&thread); 1571 if (!bit_width || !byte_size) 1572 return return_valobj_sp; 1573 1574 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { 1575 switch (*bit_width) { 1576 default: 1577 return return_valobj_sp; 1578 case 64: { 1579 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo( 1580 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); 1581 uint64_t raw_value; 1582 raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; 1583 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & 1584 UINT32_MAX)) 1585 << 32; 1586 if (is_signed) 1587 value.GetScalar() = (int64_t)raw_value; 1588 else 1589 value.GetScalar() = (uint64_t)raw_value; 1590 } break; 1591 case 32: 1592 if (is_signed) 1593 value.GetScalar() = (int32_t)( 1594 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX); 1595 else 1596 value.GetScalar() = (uint32_t)( 1597 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX); 1598 break; 1599 case 16: 1600 if (is_signed) 1601 value.GetScalar() = (int16_t)( 1602 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX); 1603 else 1604 value.GetScalar() = (uint16_t)( 1605 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX); 1606 break; 1607 case 8: 1608 if (is_signed) 1609 value.GetScalar() = (int8_t)( 1610 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX); 1611 else 1612 value.GetScalar() = (uint8_t)( 1613 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX); 1614 break; 1615 } 1616 } else if (compiler_type.IsPointerType()) { 1617 uint32_t ptr = 1618 thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) & 1619 UINT32_MAX; 1620 value.GetScalar() = ptr; 1621 } else if (compiler_type.IsVectorType()) { 1622 if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) { 1623 is_vfp_candidate = true; 1624 vfp_byte_size = 8; 1625 vfp_count = (*byte_size == 8 ? 1 : 2); 1626 } else if (*byte_size <= 16) { 1627 DataBufferHeap buffer(16, 0); 1628 uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes(); 1629 1630 for (uint32_t i = 0; 4 * i < *byte_size; ++i) { 1631 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( 1632 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); 1633 buffer_ptr[i] = 1634 reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX; 1635 } 1636 value.SetBytes(buffer.GetBytes(), *byte_size); 1637 } else { 1638 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value)) 1639 return return_valobj_sp; 1640 } 1641 } else if (compiler_type.IsFloatingPointType(float_count, is_complex)) { 1642 if (float_count == 1 && !is_complex) { 1643 switch (*bit_width) { 1644 default: 1645 return return_valobj_sp; 1646 case 64: { 1647 static_assert(sizeof(double) == sizeof(uint64_t)); 1648 1649 if (IsArmHardFloat(thread)) { 1650 RegisterValue reg_value; 1651 const RegisterInfo *d0_reg_info = 1652 reg_ctx->GetRegisterInfoByName("d0", 0); 1653 reg_ctx->ReadRegister(d0_reg_info, reg_value); 1654 value.GetScalar() = reg_value.GetAsDouble(); 1655 } else { 1656 uint64_t raw_value; 1657 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo( 1658 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); 1659 raw_value = 1660 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; 1661 raw_value |= 1662 ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) & 1663 UINT32_MAX)) 1664 << 32; 1665 value.GetScalar() = *reinterpret_cast<double *>(&raw_value); 1666 } 1667 break; 1668 } 1669 case 16: // Half precision returned after a conversion to single precision 1670 case 32: { 1671 static_assert(sizeof(float) == sizeof(uint32_t)); 1672 1673 if (IsArmHardFloat(thread)) { 1674 RegisterValue reg_value; 1675 const RegisterInfo *s0_reg_info = 1676 reg_ctx->GetRegisterInfoByName("s0", 0); 1677 reg_ctx->ReadRegister(s0_reg_info, reg_value); 1678 value.GetScalar() = reg_value.GetAsFloat(); 1679 } else { 1680 uint32_t raw_value; 1681 raw_value = 1682 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; 1683 value.GetScalar() = *reinterpret_cast<float *>(&raw_value); 1684 } 1685 break; 1686 } 1687 } 1688 } else if (is_complex && float_count == 2) { 1689 if (IsArmHardFloat(thread)) { 1690 is_vfp_candidate = true; 1691 vfp_byte_size = *byte_size / 2; 1692 vfp_count = 2; 1693 } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8, 1694 value)) 1695 return return_valobj_sp; 1696 } else 1697 // not handled yet 1698 return return_valobj_sp; 1699 } else if (compiler_type.IsAggregateType()) { 1700 if (IsArmHardFloat(thread)) { 1701 CompilerType base_type; 1702 const uint32_t homogeneous_count = 1703 compiler_type.IsHomogeneousAggregate(&base_type); 1704 1705 if (homogeneous_count > 0 && homogeneous_count <= 4) { 1706 std::optional<uint64_t> base_byte_size = base_type.GetByteSize(&thread); 1707 if (base_type.IsVectorType()) { 1708 if (base_byte_size && 1709 (*base_byte_size == 8 || *base_byte_size == 16)) { 1710 is_vfp_candidate = true; 1711 vfp_byte_size = 8; 1712 vfp_count = (*base_byte_size == 8 ? homogeneous_count 1713 : homogeneous_count * 2); 1714 } 1715 } else if (base_type.IsFloatingPointType(float_count, is_complex)) { 1716 if (float_count == 1 && !is_complex) { 1717 is_vfp_candidate = true; 1718 if (base_byte_size) 1719 vfp_byte_size = *base_byte_size; 1720 vfp_count = homogeneous_count; 1721 } 1722 } 1723 } else if (homogeneous_count == 0) { 1724 const uint32_t num_children = compiler_type.GetNumFields(); 1725 1726 if (num_children > 0 && num_children <= 2) { 1727 uint32_t index = 0; 1728 for (index = 0; index < num_children; index++) { 1729 std::string name; 1730 base_type = compiler_type.GetFieldAtIndex(index, name, nullptr, 1731 nullptr, nullptr); 1732 1733 if (base_type.IsFloatingPointType(float_count, is_complex)) { 1734 std::optional<uint64_t> base_byte_size = 1735 base_type.GetByteSize(&thread); 1736 if (float_count == 2 && is_complex) { 1737 if (index != 0 && base_byte_size && 1738 vfp_byte_size != *base_byte_size) 1739 break; 1740 else if (base_byte_size) 1741 vfp_byte_size = *base_byte_size; 1742 } else 1743 break; 1744 } else 1745 break; 1746 } 1747 1748 if (index == num_children) { 1749 is_vfp_candidate = true; 1750 vfp_byte_size = (vfp_byte_size >> 1); 1751 vfp_count = (num_children << 1); 1752 } 1753 } 1754 } 1755 } 1756 1757 if (*byte_size <= 4) { 1758 RegisterValue r0_reg_value; 1759 uint32_t raw_value = 1760 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; 1761 value.SetBytes(&raw_value, *byte_size); 1762 } else if (!is_vfp_candidate) { 1763 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value)) 1764 return return_valobj_sp; 1765 } 1766 } else { 1767 // not handled yet 1768 return return_valobj_sp; 1769 } 1770 1771 if (is_vfp_candidate) { 1772 ProcessSP process_sp(thread.GetProcess()); 1773 ByteOrder byte_order = process_sp->GetByteOrder(); 1774 1775 WritableDataBufferSP data_sp(new DataBufferHeap(*byte_size, 0)); 1776 uint32_t data_offset = 0; 1777 1778 for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) { 1779 uint32_t regnum = 0; 1780 1781 if (vfp_byte_size == 4) 1782 regnum = dwarf_s0 + reg_index; 1783 else if (vfp_byte_size == 8) 1784 regnum = dwarf_d0 + reg_index; 1785 else 1786 break; 1787 1788 const RegisterInfo *reg_info = 1789 reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum); 1790 if (reg_info == nullptr) 1791 break; 1792 1793 RegisterValue reg_value; 1794 if (!reg_ctx->ReadRegister(reg_info, reg_value)) 1795 break; 1796 1797 // Make sure we have enough room in "data_sp" 1798 if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) { 1799 Status error; 1800 const size_t bytes_copied = reg_value.GetAsMemoryData( 1801 *reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size, 1802 byte_order, error); 1803 if (bytes_copied != vfp_byte_size) 1804 break; 1805 1806 data_offset += bytes_copied; 1807 } 1808 } 1809 1810 if (data_offset == *byte_size) { 1811 DataExtractor data; 1812 data.SetByteOrder(byte_order); 1813 data.SetAddressByteSize(process_sp->GetAddressByteSize()); 1814 data.SetData(data_sp); 1815 1816 return ValueObjectConstResult::Create(&thread, compiler_type, 1817 ConstString(""), data); 1818 } else { // Some error occurred while getting values from registers 1819 return return_valobj_sp; 1820 } 1821 } 1822 1823 // If we get here, we have a valid Value, so make our ValueObject out of it: 1824 1825 return_valobj_sp = ValueObjectConstResult::Create( 1826 thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); 1827 return return_valobj_sp; 1828 } 1829 1830 Status ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp, 1831 lldb::ValueObjectSP &new_value_sp) { 1832 Status error; 1833 if (!new_value_sp) { 1834 error.SetErrorString("Empty value object for return value."); 1835 return error; 1836 } 1837 1838 CompilerType compiler_type = new_value_sp->GetCompilerType(); 1839 if (!compiler_type) { 1840 error.SetErrorString("Null clang type for return value."); 1841 return error; 1842 } 1843 1844 Thread *thread = frame_sp->GetThread().get(); 1845 1846 bool is_signed; 1847 uint32_t count; 1848 bool is_complex; 1849 1850 RegisterContext *reg_ctx = thread->GetRegisterContext().get(); 1851 1852 bool set_it_simple = false; 1853 if (compiler_type.IsIntegerOrEnumerationType(is_signed) || 1854 compiler_type.IsPointerType()) { 1855 DataExtractor data; 1856 Status data_error; 1857 size_t num_bytes = new_value_sp->GetData(data, data_error); 1858 if (data_error.Fail()) { 1859 error.SetErrorStringWithFormat( 1860 "Couldn't convert return value to raw data: %s", 1861 data_error.AsCString()); 1862 return error; 1863 } 1864 lldb::offset_t offset = 0; 1865 if (num_bytes <= 8) { 1866 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo( 1867 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); 1868 if (num_bytes <= 4) { 1869 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes); 1870 1871 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) 1872 set_it_simple = true; 1873 } else { 1874 uint32_t raw_value = data.GetMaxU32(&offset, 4); 1875 1876 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) { 1877 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo( 1878 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2); 1879 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset); 1880 1881 if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value)) 1882 set_it_simple = true; 1883 } 1884 } 1885 } else { 1886 error.SetErrorString("We don't support returning longer than 64 bit " 1887 "integer values at present."); 1888 } 1889 } else if (compiler_type.IsFloatingPointType(count, is_complex)) { 1890 if (is_complex) 1891 error.SetErrorString( 1892 "We don't support returning complex values at present"); 1893 else 1894 error.SetErrorString( 1895 "We don't support returning float values at present"); 1896 } 1897 1898 if (!set_it_simple) 1899 error.SetErrorString( 1900 "We only support setting simple integer return types at present."); 1901 1902 return error; 1903 } 1904 1905 bool ABISysV_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { 1906 unwind_plan.Clear(); 1907 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1908 1909 uint32_t lr_reg_num = dwarf_lr; 1910 uint32_t sp_reg_num = dwarf_sp; 1911 uint32_t pc_reg_num = dwarf_pc; 1912 1913 UnwindPlan::RowSP row(new UnwindPlan::Row); 1914 1915 // Our Call Frame Address is the stack pointer value 1916 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0); 1917 1918 // The previous PC is in the LR 1919 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true); 1920 unwind_plan.AppendRow(row); 1921 1922 // All other registers are the same. 1923 1924 unwind_plan.SetSourceName("arm at-func-entry default"); 1925 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1926 1927 return true; 1928 } 1929 1930 bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { 1931 unwind_plan.Clear(); 1932 unwind_plan.SetRegisterKind(eRegisterKindDWARF); 1933 1934 // TODO: Handle thumb 1935 uint32_t fp_reg_num = dwarf_r11; 1936 uint32_t pc_reg_num = dwarf_pc; 1937 1938 UnwindPlan::RowSP row(new UnwindPlan::Row); 1939 const int32_t ptr_size = 4; 1940 1941 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size); 1942 row->SetOffset(0); 1943 row->SetUnspecifiedRegistersAreUndefined(true); 1944 1945 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true); 1946 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true); 1947 1948 unwind_plan.AppendRow(row); 1949 unwind_plan.SetSourceName("arm default unwind plan"); 1950 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1951 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); 1952 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 1953 1954 return true; 1955 } 1956 1957 // cf. "ARMv6 Function Calling Conventions" 1958 1959 // ARMv7 on GNU/Linux general purpose reg rules: 1960 // r0-r3 not preserved (used for argument passing) 1961 // r4-r11 preserved (v1-v8) 1962 // r12 not presrved 1963 // r13 preserved (stack pointer) 1964 // r14 preserved (link register) 1965 // r15 preserved (pc) 1966 // cpsr not preserved (different rules for different bits) 1967 1968 // ARMv7 VFP register rules: 1969 // d0-d7 not preserved (aka s0-s15, q0-q3) 1970 // d8-d15 preserved (aka s16-s31, q4-q7) 1971 // d16-d31 not preserved (aka q8-q15) 1972 1973 bool ABISysV_arm::RegisterIsVolatile(const RegisterInfo *reg_info) { 1974 if (reg_info) { 1975 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp) 1976 const char *name = reg_info->name; 1977 if (name[0] == 'r') { 1978 switch (name[1]) { 1979 case '0': 1980 return name[2] == '\0'; // r0 1981 case '1': 1982 switch (name[2]) { 1983 case '\0': 1984 return true; // r1 1985 case '2': 1986 return name[3] == '\0'; // r12 1987 default: 1988 break; 1989 } 1990 break; 1991 1992 case '2': 1993 return name[2] == '\0'; // r2 1994 case '3': 1995 return name[2] == '\0'; // r3 1996 default: 1997 break; 1998 } 1999 } else if (name[0] == 'd') { 2000 switch (name[1]) { 2001 case '0': 2002 return name[2] == '\0'; // d0 is volatile 2003 2004 case '1': 2005 switch (name[2]) { 2006 case '\0': 2007 return true; // d1 is volatile 2008 case '6': 2009 case '7': 2010 case '8': 2011 case '9': 2012 return name[3] == '\0'; // d16 - d19 are volatile 2013 default: 2014 break; 2015 } 2016 break; 2017 2018 case '2': 2019 switch (name[2]) { 2020 case '\0': 2021 return true; // d2 is volatile 2022 case '0': 2023 case '1': 2024 case '2': 2025 case '3': 2026 case '4': 2027 case '5': 2028 case '6': 2029 case '7': 2030 case '8': 2031 case '9': 2032 return name[3] == '\0'; // d20 - d29 are volatile 2033 default: 2034 break; 2035 } 2036 break; 2037 2038 case '3': 2039 switch (name[2]) { 2040 case '\0': 2041 return true; // d3 is volatile 2042 case '0': 2043 case '1': 2044 return name[3] == '\0'; // d30 - d31 are volatile 2045 default: 2046 break; 2047 } 2048 break; 2049 case '4': 2050 case '5': 2051 case '6': 2052 case '7': 2053 return name[2] == '\0'; // d4 - d7 are volatile 2054 2055 default: 2056 break; 2057 } 2058 } else if (name[0] == 's') { 2059 switch (name[1]) { 2060 case '0': 2061 return name[2] == '\0'; // s0 is volatile 2062 2063 case '1': 2064 switch (name[2]) { 2065 case '\0': 2066 return true; // s1 is volatile 2067 case '0': 2068 case '1': 2069 case '2': 2070 case '3': 2071 case '4': 2072 case '5': 2073 return name[3] == '\0'; // s10 - s15 are volatile 2074 default: 2075 break; 2076 } 2077 break; 2078 2079 case '2': 2080 case '3': 2081 case '4': 2082 case '5': 2083 case '6': 2084 case '7': 2085 case '8': 2086 case '9': 2087 return name[2] == '\0'; // s2 - s9 are volatile 2088 2089 default: 2090 break; 2091 } 2092 } else if (name[0] == 'q') { 2093 switch (name[1]) { 2094 case '1': 2095 switch (name[2]) { 2096 case '\0': 2097 return true; // q1 is volatile 2098 case '0': 2099 case '1': 2100 case '2': 2101 case '3': 2102 case '4': 2103 case '5': 2104 return true; // q10-q15 are volatile 2105 default: 2106 return false; 2107 } 2108 break; 2109 2110 case '0': 2111 case '2': 2112 case '3': 2113 return name[2] == '\0'; // q0-q3 are volatile 2114 case '8': 2115 case '9': 2116 return name[2] == '\0'; // q8-q9 are volatile 2117 default: 2118 break; 2119 } 2120 } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') 2121 return true; 2122 } 2123 return false; 2124 } 2125 2126 void ABISysV_arm::Initialize() { 2127 PluginManager::RegisterPlugin(GetPluginNameStatic(), 2128 "SysV ABI for arm targets", CreateInstance); 2129 } 2130 2131 void ABISysV_arm::Terminate() { 2132 PluginManager::UnregisterPlugin(CreateInstance); 2133 } 2134