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