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