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