1 //===-- ABISysV_hexagon.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_hexagon.h" 10 11 #include "llvm/IR/DerivedTypes.h" 12 #include "llvm/TargetParser/Triple.h" 13 14 #include "lldb/Core/Module.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Core/Value.h" 17 #include "lldb/Core/ValueObjectConstResult.h" 18 #include "lldb/Core/ValueObjectMemory.h" 19 #include "lldb/Core/ValueObjectRegister.h" 20 #include "lldb/Symbol/UnwindPlan.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/RegisterContext.h" 23 #include "lldb/Target/StackFrame.h" 24 #include "lldb/Target/Target.h" 25 #include "lldb/Target/Thread.h" 26 #include "lldb/Utility/ConstString.h" 27 #include "lldb/Utility/DataExtractor.h" 28 #include "lldb/Utility/Log.h" 29 #include "lldb/Utility/RegisterValue.h" 30 #include "lldb/Utility/Status.h" 31 32 using namespace lldb; 33 using namespace lldb_private; 34 35 LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon) 36 37 static const RegisterInfo g_register_infos[] = { 38 // hexagon-core.xml 39 {"r00", 40 "", 41 4, 42 0, 43 eEncodingUint, 44 eFormatAddressInfo, 45 {0, 0, LLDB_INVALID_REGNUM, 0, 0}, 46 nullptr, 47 nullptr, 48 nullptr, 49 }, 50 {"r01", 51 "", 52 4, 53 0, 54 eEncodingUint, 55 eFormatAddressInfo, 56 {1, 1, LLDB_INVALID_REGNUM, 1, 1}, 57 nullptr, 58 nullptr, 59 nullptr, 60 }, 61 {"r02", 62 "", 63 4, 64 0, 65 eEncodingUint, 66 eFormatAddressInfo, 67 {2, 2, LLDB_INVALID_REGNUM, 2, 2}, 68 nullptr, 69 nullptr, 70 nullptr, 71 }, 72 {"r03", 73 "", 74 4, 75 0, 76 eEncodingUint, 77 eFormatAddressInfo, 78 {3, 3, LLDB_INVALID_REGNUM, 3, 3}, 79 nullptr, 80 nullptr, 81 nullptr, 82 }, 83 {"r04", 84 "", 85 4, 86 0, 87 eEncodingUint, 88 eFormatAddressInfo, 89 {4, 4, LLDB_INVALID_REGNUM, 4, 4}, 90 nullptr, 91 nullptr, 92 nullptr, 93 }, 94 {"r05", 95 "", 96 4, 97 0, 98 eEncodingUint, 99 eFormatAddressInfo, 100 {5, 5, LLDB_INVALID_REGNUM, 5, 5}, 101 nullptr, 102 nullptr, 103 nullptr, 104 }, 105 {"r06", 106 "", 107 4, 108 0, 109 eEncodingUint, 110 eFormatAddressInfo, 111 {6, 6, LLDB_INVALID_REGNUM, 6, 6}, 112 nullptr, 113 nullptr, 114 nullptr, 115 }, 116 {"r07", 117 "", 118 4, 119 0, 120 eEncodingUint, 121 eFormatAddressInfo, 122 {7, 7, LLDB_INVALID_REGNUM, 7, 7}, 123 nullptr, 124 nullptr, 125 nullptr, 126 }, 127 {"r08", 128 "", 129 4, 130 0, 131 eEncodingUint, 132 eFormatAddressInfo, 133 {8, 8, LLDB_INVALID_REGNUM, 8, 8}, 134 nullptr, 135 nullptr, 136 nullptr, 137 }, 138 {"r09", 139 "", 140 4, 141 0, 142 eEncodingUint, 143 eFormatAddressInfo, 144 {9, 9, LLDB_INVALID_REGNUM, 9, 9}, 145 nullptr, 146 nullptr, 147 nullptr, 148 }, 149 {"r10", 150 "", 151 4, 152 0, 153 eEncodingUint, 154 eFormatAddressInfo, 155 {10, 10, LLDB_INVALID_REGNUM, 10, 10}, 156 nullptr, 157 nullptr, 158 nullptr, 159 }, 160 {"r11", 161 "", 162 4, 163 0, 164 eEncodingUint, 165 eFormatAddressInfo, 166 {11, 11, LLDB_INVALID_REGNUM, 11, 11}, 167 nullptr, 168 nullptr, 169 nullptr, 170 }, 171 {"r12", 172 "", 173 4, 174 0, 175 eEncodingUint, 176 eFormatAddressInfo, 177 {12, 12, LLDB_INVALID_REGNUM, 12, 12}, 178 nullptr, 179 nullptr, 180 nullptr, 181 }, 182 {"r13", 183 "", 184 4, 185 0, 186 eEncodingUint, 187 eFormatAddressInfo, 188 {13, 13, LLDB_INVALID_REGNUM, 13, 13}, 189 nullptr, 190 nullptr, 191 nullptr, 192 }, 193 {"r14", 194 "", 195 4, 196 0, 197 eEncodingUint, 198 eFormatAddressInfo, 199 {14, 14, LLDB_INVALID_REGNUM, 14, 14}, 200 nullptr, 201 nullptr, 202 nullptr, 203 }, 204 {"r15", 205 "", 206 4, 207 0, 208 eEncodingUint, 209 eFormatAddressInfo, 210 {15, 15, LLDB_INVALID_REGNUM, 15, 15}, 211 nullptr, 212 nullptr, 213 nullptr, 214 }, 215 {"r16", 216 "", 217 4, 218 0, 219 eEncodingUint, 220 eFormatAddressInfo, 221 {16, 16, LLDB_INVALID_REGNUM, 16, 16}, 222 nullptr, 223 nullptr, 224 nullptr, 225 }, 226 {"r17", 227 "", 228 4, 229 0, 230 eEncodingUint, 231 eFormatAddressInfo, 232 {17, 17, LLDB_INVALID_REGNUM, 17, 17}, 233 nullptr, 234 nullptr, 235 nullptr, 236 }, 237 {"r18", 238 "", 239 4, 240 0, 241 eEncodingUint, 242 eFormatAddressInfo, 243 {18, 18, LLDB_INVALID_REGNUM, 18, 18}, 244 nullptr, 245 nullptr, 246 nullptr, 247 }, 248 {"r19", 249 "", 250 4, 251 0, 252 eEncodingUint, 253 eFormatAddressInfo, 254 {19, 19, LLDB_INVALID_REGNUM, 19, 19}, 255 nullptr, 256 nullptr, 257 nullptr, 258 }, 259 {"r20", 260 "", 261 4, 262 0, 263 eEncodingUint, 264 eFormatAddressInfo, 265 {20, 20, LLDB_INVALID_REGNUM, 20, 20}, 266 nullptr, 267 nullptr, 268 nullptr, 269 }, 270 {"r21", 271 "", 272 4, 273 0, 274 eEncodingUint, 275 eFormatAddressInfo, 276 {21, 21, LLDB_INVALID_REGNUM, 21, 21}, 277 nullptr, 278 nullptr, 279 nullptr, 280 }, 281 {"r22", 282 "", 283 4, 284 0, 285 eEncodingUint, 286 eFormatAddressInfo, 287 {22, 22, LLDB_INVALID_REGNUM, 22, 22}, 288 nullptr, 289 nullptr, 290 nullptr, 291 }, 292 {"r23", 293 "", 294 4, 295 0, 296 eEncodingUint, 297 eFormatAddressInfo, 298 {23, 23, LLDB_INVALID_REGNUM, 23, 23}, 299 nullptr, 300 nullptr, 301 nullptr, 302 }, 303 {"r24", 304 "", 305 4, 306 0, 307 eEncodingUint, 308 eFormatAddressInfo, 309 {24, 24, LLDB_INVALID_REGNUM, 24, 24}, 310 nullptr, 311 nullptr, 312 nullptr, 313 }, 314 {"r25", 315 "", 316 4, 317 0, 318 eEncodingUint, 319 eFormatAddressInfo, 320 {25, 25, LLDB_INVALID_REGNUM, 25, 25}, 321 nullptr, 322 nullptr, 323 nullptr, 324 }, 325 {"r26", 326 "", 327 4, 328 0, 329 eEncodingUint, 330 eFormatAddressInfo, 331 {26, 26, LLDB_INVALID_REGNUM, 26, 26}, 332 nullptr, 333 nullptr, 334 nullptr, 335 }, 336 {"r27", 337 "", 338 4, 339 0, 340 eEncodingUint, 341 eFormatAddressInfo, 342 {27, 27, LLDB_INVALID_REGNUM, 27, 27}, 343 nullptr, 344 nullptr, 345 nullptr, 346 }, 347 {"r28", 348 "", 349 4, 350 0, 351 eEncodingUint, 352 eFormatAddressInfo, 353 {28, 28, LLDB_INVALID_REGNUM, 28, 28}, 354 nullptr, 355 nullptr, 356 nullptr, 357 }, 358 {"sp", 359 "r29", 360 4, 361 0, 362 eEncodingUint, 363 eFormatAddressInfo, 364 {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29}, 365 nullptr, 366 nullptr, 367 nullptr, 368 }, 369 {"fp", 370 "r30", 371 4, 372 0, 373 eEncodingUint, 374 eFormatAddressInfo, 375 {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30}, 376 nullptr, 377 nullptr, 378 nullptr, 379 }, 380 {"lr", 381 "r31", 382 4, 383 0, 384 eEncodingUint, 385 eFormatAddressInfo, 386 {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31}, 387 nullptr, 388 nullptr, 389 nullptr, 390 }, 391 {"sa0", 392 "", 393 4, 394 0, 395 eEncodingUint, 396 eFormatAddressInfo, 397 {32, 32, LLDB_INVALID_REGNUM, 32, 32}, 398 nullptr, 399 nullptr, 400 nullptr, 401 }, 402 {"lc0", 403 "", 404 4, 405 0, 406 eEncodingUint, 407 eFormatAddressInfo, 408 {33, 33, LLDB_INVALID_REGNUM, 33, 33}, 409 nullptr, 410 nullptr, 411 nullptr, 412 }, 413 {"sa1", 414 "", 415 4, 416 0, 417 eEncodingUint, 418 eFormatAddressInfo, 419 {34, 34, LLDB_INVALID_REGNUM, 34, 34}, 420 nullptr, 421 nullptr, 422 nullptr, 423 }, 424 {"lc1", 425 "", 426 4, 427 0, 428 eEncodingUint, 429 eFormatAddressInfo, 430 {35, 35, LLDB_INVALID_REGNUM, 35, 35}, 431 nullptr, 432 nullptr, 433 nullptr, 434 }, 435 // --> hexagon-v4/5/55/56-sim.xml 436 {"p3_0", 437 "", 438 4, 439 0, 440 eEncodingUint, 441 eFormatAddressInfo, 442 {36, 36, LLDB_INVALID_REGNUM, 36, 36}, 443 nullptr, 444 nullptr, 445 nullptr, 446 447 }, 448 // PADDING { 449 {"p00", 450 "", 451 4, 452 0, 453 eEncodingInvalid, 454 eFormatInvalid, 455 {37, 37, LLDB_INVALID_REGNUM, 37, 37}, 456 nullptr, 457 nullptr, 458 nullptr, 459 }, 460 // } 461 {"m0", 462 "", 463 4, 464 0, 465 eEncodingUint, 466 eFormatAddressInfo, 467 {38, 38, LLDB_INVALID_REGNUM, 38, 38}, 468 nullptr, 469 nullptr, 470 nullptr, 471 }, 472 {"m1", 473 "", 474 4, 475 0, 476 eEncodingUint, 477 eFormatAddressInfo, 478 {39, 39, LLDB_INVALID_REGNUM, 39, 39}, 479 nullptr, 480 nullptr, 481 nullptr, 482 }, 483 {"usr", 484 "", 485 4, 486 0, 487 eEncodingUint, 488 eFormatAddressInfo, 489 {40, 40, LLDB_INVALID_REGNUM, 40, 40}, 490 nullptr, 491 nullptr, 492 nullptr, 493 }, 494 {"pc", 495 "", 496 4, 497 0, 498 eEncodingUint, 499 eFormatAddressInfo, 500 {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41}, 501 nullptr, 502 nullptr, 503 nullptr, 504 }, 505 {"ugp", 506 "", 507 4, 508 0, 509 eEncodingUint, 510 eFormatAddressInfo, 511 {42, 42, LLDB_INVALID_REGNUM, 42, 42}, 512 nullptr, 513 nullptr, 514 nullptr, 515 }, 516 {"gp", 517 "", 518 4, 519 0, 520 eEncodingUint, 521 eFormatAddressInfo, 522 {43, 43, LLDB_INVALID_REGNUM, 43, 43}, 523 nullptr, 524 nullptr, 525 nullptr, 526 }, 527 {"cs0", 528 "", 529 4, 530 0, 531 eEncodingUint, 532 eFormatAddressInfo, 533 {44, 44, LLDB_INVALID_REGNUM, 44, 44}, 534 nullptr, 535 nullptr, 536 nullptr, 537 }, 538 {"cs1", 539 "", 540 4, 541 0, 542 eEncodingUint, 543 eFormatAddressInfo, 544 {45, 45, LLDB_INVALID_REGNUM, 45, 45}, 545 nullptr, 546 nullptr, 547 nullptr, 548 }, 549 // PADDING { 550 {"p01", 551 "", 552 4, 553 0, 554 eEncodingInvalid, 555 eFormatInvalid, 556 {46, 46, LLDB_INVALID_REGNUM, 46, 46}, 557 nullptr, 558 nullptr, 559 nullptr, 560 }, 561 {"p02", 562 "", 563 4, 564 0, 565 eEncodingInvalid, 566 eFormatInvalid, 567 {47, 47, LLDB_INVALID_REGNUM, 47, 47}, 568 nullptr, 569 nullptr, 570 nullptr, 571 }, 572 {"p03", 573 "", 574 4, 575 0, 576 eEncodingInvalid, 577 eFormatInvalid, 578 {48, 48, LLDB_INVALID_REGNUM, 48, 48}, 579 nullptr, 580 nullptr, 581 nullptr, 582 }, 583 {"p04", 584 "", 585 4, 586 0, 587 eEncodingInvalid, 588 eFormatInvalid, 589 {49, 49, LLDB_INVALID_REGNUM, 49, 49}, 590 nullptr, 591 nullptr, 592 nullptr, 593 }, 594 {"p05", 595 "", 596 4, 597 0, 598 eEncodingInvalid, 599 eFormatInvalid, 600 {50, 50, LLDB_INVALID_REGNUM, 50, 50}, 601 nullptr, 602 nullptr, 603 nullptr, 604 }, 605 {"p06", 606 "", 607 4, 608 0, 609 eEncodingInvalid, 610 eFormatInvalid, 611 {51, 51, LLDB_INVALID_REGNUM, 51, 51}, 612 nullptr, 613 nullptr, 614 nullptr, 615 }, 616 {"p07", 617 "", 618 4, 619 0, 620 eEncodingInvalid, 621 eFormatInvalid, 622 {52, 52, LLDB_INVALID_REGNUM, 52, 52}, 623 nullptr, 624 nullptr, 625 nullptr, 626 }, 627 {"p08", 628 "", 629 4, 630 0, 631 eEncodingInvalid, 632 eFormatInvalid, 633 {53, 53, LLDB_INVALID_REGNUM, 53, 53}, 634 nullptr, 635 nullptr, 636 nullptr, 637 }, 638 {"p09", 639 "", 640 4, 641 0, 642 eEncodingInvalid, 643 eFormatInvalid, 644 {54, 54, LLDB_INVALID_REGNUM, 54, 54}, 645 nullptr, 646 nullptr, 647 nullptr, 648 }, 649 {"p10", 650 "", 651 4, 652 0, 653 eEncodingInvalid, 654 eFormatInvalid, 655 {55, 55, LLDB_INVALID_REGNUM, 55, 55}, 656 nullptr, 657 nullptr, 658 nullptr, 659 }, 660 {"p11", 661 "", 662 4, 663 0, 664 eEncodingInvalid, 665 eFormatInvalid, 666 {56, 56, LLDB_INVALID_REGNUM, 56, 56}, 667 nullptr, 668 nullptr, 669 nullptr, 670 }, 671 {"p12", 672 "", 673 4, 674 0, 675 eEncodingInvalid, 676 eFormatInvalid, 677 {57, 57, LLDB_INVALID_REGNUM, 57, 57}, 678 nullptr, 679 nullptr, 680 nullptr, 681 }, 682 {"p13", 683 "", 684 4, 685 0, 686 eEncodingInvalid, 687 eFormatInvalid, 688 {58, 58, LLDB_INVALID_REGNUM, 58, 58}, 689 nullptr, 690 nullptr, 691 nullptr, 692 }, 693 {"p14", 694 "", 695 4, 696 0, 697 eEncodingInvalid, 698 eFormatInvalid, 699 {59, 59, LLDB_INVALID_REGNUM, 59, 59}, 700 nullptr, 701 nullptr, 702 nullptr, 703 }, 704 {"p15", 705 "", 706 4, 707 0, 708 eEncodingInvalid, 709 eFormatInvalid, 710 {60, 60, LLDB_INVALID_REGNUM, 60, 60}, 711 nullptr, 712 nullptr, 713 nullptr, 714 }, 715 {"p16", 716 "", 717 4, 718 0, 719 eEncodingInvalid, 720 eFormatInvalid, 721 {61, 61, LLDB_INVALID_REGNUM, 61, 61}, 722 nullptr, 723 nullptr, 724 nullptr, 725 }, 726 {"p17", 727 "", 728 4, 729 0, 730 eEncodingInvalid, 731 eFormatInvalid, 732 {62, 62, LLDB_INVALID_REGNUM, 62, 62}, 733 nullptr, 734 nullptr, 735 nullptr, 736 }, 737 {"p18", 738 "", 739 4, 740 0, 741 eEncodingInvalid, 742 eFormatInvalid, 743 {63, 63, LLDB_INVALID_REGNUM, 63, 63}, 744 nullptr, 745 nullptr, 746 nullptr, 747 }, 748 // } 749 {"sgp0", 750 "", 751 4, 752 0, 753 eEncodingUint, 754 eFormatAddressInfo, 755 {64, 64, LLDB_INVALID_REGNUM, 64, 64}, 756 nullptr, 757 nullptr, 758 nullptr, 759 }, 760 // PADDING { 761 {"p19", 762 "", 763 4, 764 0, 765 eEncodingInvalid, 766 eFormatInvalid, 767 {65, 65, LLDB_INVALID_REGNUM, 65, 65}, 768 nullptr, 769 nullptr, 770 nullptr, 771 }, 772 // } 773 {"stid", 774 "", 775 4, 776 0, 777 eEncodingUint, 778 eFormatAddressInfo, 779 {66, 66, LLDB_INVALID_REGNUM, 66, 66}, 780 nullptr, 781 nullptr, 782 nullptr, 783 }, 784 {"elr", 785 "", 786 4, 787 0, 788 eEncodingUint, 789 eFormatAddressInfo, 790 {67, 67, LLDB_INVALID_REGNUM, 67, 67}, 791 nullptr, 792 nullptr, 793 nullptr, 794 }, 795 {"badva0", 796 "", 797 4, 798 0, 799 eEncodingUint, 800 eFormatAddressInfo, 801 {68, 68, LLDB_INVALID_REGNUM, 68, 68}, 802 nullptr, 803 nullptr, 804 nullptr, 805 }, 806 {"badva1", 807 "", 808 4, 809 0, 810 eEncodingUint, 811 eFormatAddressInfo, 812 {69, 69, LLDB_INVALID_REGNUM, 69, 69}, 813 nullptr, 814 nullptr, 815 nullptr, 816 }, 817 {"ssr", 818 "", 819 4, 820 0, 821 eEncodingUint, 822 eFormatAddressInfo, 823 {70, 70, LLDB_INVALID_REGNUM, 70, 70}, 824 nullptr, 825 nullptr, 826 nullptr, 827 }, 828 {"ccr", 829 "", 830 4, 831 0, 832 eEncodingUint, 833 eFormatAddressInfo, 834 {71, 71, LLDB_INVALID_REGNUM, 71, 71}, 835 nullptr, 836 nullptr, 837 nullptr, 838 }, 839 {"htid", 840 "", 841 4, 842 0, 843 eEncodingUint, 844 eFormatAddressInfo, 845 {72, 72, LLDB_INVALID_REGNUM, 72, 72}, 846 nullptr, 847 nullptr, 848 nullptr, 849 }, 850 // PADDING { 851 {"p20", 852 "", 853 4, 854 0, 855 eEncodingInvalid, 856 eFormatInvalid, 857 {73, 73, LLDB_INVALID_REGNUM, 73, 73}, 858 nullptr, 859 nullptr, 860 nullptr, 861 }, 862 // } 863 {"imask", 864 "", 865 4, 866 0, 867 eEncodingUint, 868 eFormatAddressInfo, 869 {74, 74, LLDB_INVALID_REGNUM, 74, 74}, 870 nullptr, 871 nullptr, 872 nullptr, 873 }, 874 // PADDING { 875 {"p21", 876 "", 877 4, 878 0, 879 eEncodingInvalid, 880 eFormatInvalid, 881 {75, 75, LLDB_INVALID_REGNUM, 75, 75}, 882 nullptr, 883 nullptr, 884 nullptr, 885 }, 886 {"p22", 887 "", 888 4, 889 0, 890 eEncodingInvalid, 891 eFormatInvalid, 892 {76, 76, LLDB_INVALID_REGNUM, 76, 76}, 893 nullptr, 894 nullptr, 895 nullptr, 896 }, 897 {"p23", 898 "", 899 4, 900 0, 901 eEncodingInvalid, 902 eFormatInvalid, 903 {77, 77, LLDB_INVALID_REGNUM, 77, 77}, 904 nullptr, 905 nullptr, 906 nullptr, 907 }, 908 {"p24", 909 "", 910 4, 911 0, 912 eEncodingInvalid, 913 eFormatInvalid, 914 {78, 78, LLDB_INVALID_REGNUM, 78, 78}, 915 nullptr, 916 nullptr, 917 nullptr, 918 }, 919 {"p25", 920 "", 921 4, 922 0, 923 eEncodingInvalid, 924 eFormatInvalid, 925 {79, 79, LLDB_INVALID_REGNUM, 79, 79}, 926 nullptr, 927 nullptr, 928 nullptr, 929 }, 930 // } 931 {"g0", 932 "", 933 4, 934 0, 935 eEncodingUint, 936 eFormatAddressInfo, 937 {80, 80, LLDB_INVALID_REGNUM, 80, 80}, 938 nullptr, 939 nullptr, 940 nullptr, 941 }, 942 {"g1", 943 "", 944 4, 945 0, 946 eEncodingUint, 947 eFormatAddressInfo, 948 {81, 81, LLDB_INVALID_REGNUM, 81, 81}, 949 nullptr, 950 nullptr, 951 nullptr, 952 }, 953 {"g2", 954 "", 955 4, 956 0, 957 eEncodingUint, 958 eFormatAddressInfo, 959 {82, 82, LLDB_INVALID_REGNUM, 82, 82}, 960 nullptr, 961 nullptr, 962 nullptr, 963 }, 964 {"g3", 965 "", 966 4, 967 0, 968 eEncodingUint, 969 eFormatAddressInfo, 970 {83, 83, LLDB_INVALID_REGNUM, 83, 83}, 971 nullptr, 972 nullptr, 973 nullptr, 974 }}; 975 976 static const uint32_t k_num_register_infos = 977 sizeof(g_register_infos) / sizeof(RegisterInfo); 978 979 const lldb_private::RegisterInfo * 980 ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) { 981 count = k_num_register_infos; 982 return g_register_infos; 983 } 984 985 /* 986 http://en.wikipedia.org/wiki/Red_zone_%28computing%29 987 988 In computing, a red zone is a fixed size area in memory beyond the stack 989 pointer that has not been 990 "allocated". This region of memory is not to be modified by 991 interrupt/exception/signal handlers. 992 This allows the space to be used for temporary data without the extra 993 overhead of modifying the 994 stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC 995 toolchain assumes a 996 128 byte red zone though it is not documented. 997 */ 998 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; } 999 1000 // Static Functions 1001 1002 ABISP 1003 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { 1004 if (arch.GetTriple().getArch() == llvm::Triple::hexagon) { 1005 return ABISP( 1006 new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch))); 1007 } 1008 return ABISP(); 1009 } 1010 1011 bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp, 1012 lldb::addr_t pc, lldb::addr_t ra, 1013 llvm::ArrayRef<addr_t> args) const { 1014 // we don't use the traditional trivial call specialized for jit 1015 return false; 1016 } 1017 1018 /* 1019 1020 // AD: 1021 // . safeguard the current stack 1022 // . how can we know that the called function will create its own frame 1023 properly? 1024 // . we could manually make a new stack first: 1025 // 2. push RA 1026 // 3. push FP 1027 // 4. FP = SP 1028 // 5. SP = SP ( since no locals in our temp frame ) 1029 1030 // AD 6/05/2014 1031 // . variable argument list parameters are not passed via registers, they are 1032 passed on 1033 // the stack. This presents us with a problem, since we need to know when 1034 the valist 1035 // starts. Currently I can find out if a function is varg, but not how many 1036 // real parameters it takes. Thus I don't know when to start spilling the 1037 vargs. For 1038 // the time being, to progress, I will assume that it takes on real parameter 1039 before 1040 // the vargs list starts. 1041 1042 // AD 06/05/2014 1043 // . how do we adhere to the stack alignment requirements 1044 1045 // AD 06/05/2014 1046 // . handle 64bit values and their register / stack requirements 1047 1048 */ 1049 #define HEX_ABI_DEBUG 0 1050 bool ABISysV_hexagon::PrepareTrivialCall( 1051 Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra, 1052 llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const { 1053 // default number of register passed arguments for varg functions 1054 const int nVArgRegParams = 1; 1055 Status error; 1056 1057 // grab the process so we have access to the memory for spilling 1058 lldb::ProcessSP proc = thread.GetProcess(); 1059 1060 // get the register context for modifying all of the registers 1061 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 1062 if (!reg_ctx) 1063 return false; 1064 1065 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( 1066 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 1067 if (pc_reg == LLDB_INVALID_REGNUM) 1068 return false; 1069 1070 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( 1071 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 1072 if (ra_reg == LLDB_INVALID_REGNUM) 1073 return false; 1074 1075 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( 1076 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 1077 if (sp_reg == LLDB_INVALID_REGNUM) 1078 return false; 1079 1080 // push host data onto target 1081 for (size_t i = 0; i < args.size(); i++) { 1082 const ABI::CallArgument &arg = args[i]; 1083 // skip over target values 1084 if (arg.type == ABI::CallArgument::TargetValue) 1085 continue; 1086 // round up to 8 byte multiple 1087 size_t argSize = (arg.size | 0x7) + 1; 1088 1089 // create space on the stack for this data 1090 sp -= argSize; 1091 1092 // write this argument onto the stack of the host process 1093 proc->WriteMemory(sp, arg.data_up.get(), arg.size, error); 1094 if (error.Fail()) 1095 return false; 1096 1097 // update the argument with the target pointer 1098 // XXX: This is a gross hack for getting around the const 1099 *const_cast<lldb::addr_t *>(&arg.value) = sp; 1100 } 1101 1102 #if HEX_ABI_DEBUG 1103 // print the original stack pointer 1104 printf("sp : %04" PRIx64 " \n", sp); 1105 #endif 1106 1107 // make sure number of parameters matches prototype 1108 assert(prototype.getFunctionNumParams() == args.size()); 1109 1110 // check if this is a variable argument function 1111 bool isVArg = prototype.isFunctionVarArg(); 1112 1113 // number of arguments passed by register 1114 int nRegArgs = nVArgRegParams; 1115 if (!isVArg) { 1116 // number of arguments is limited by [R0 : R5] space 1117 nRegArgs = args.size(); 1118 if (nRegArgs > 6) 1119 nRegArgs = 6; 1120 } 1121 1122 // pass arguments that are passed via registers 1123 for (int i = 0; i < nRegArgs; i++) { 1124 // get the parameter as a u32 1125 uint32_t param = (uint32_t)args[i].value; 1126 // write argument into register 1127 if (!reg_ctx->WriteRegisterFromUnsigned(i, param)) 1128 return false; 1129 } 1130 1131 // number of arguments to spill onto stack 1132 int nSpillArgs = args.size() - nRegArgs; 1133 // make space on the stack for arguments 1134 sp -= 4 * nSpillArgs; 1135 // align stack on an 8 byte boundary 1136 if (sp & 7) 1137 sp -= 4; 1138 1139 // arguments that are passed on the stack 1140 for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) { 1141 // get the parameter as a u32 1142 uint32_t param = (uint32_t)args[i].value; 1143 // write argument to stack 1144 proc->WriteMemory(sp + offs, (void *)¶m, sizeof(param), error); 1145 if (!error.Success()) 1146 return false; 1147 // 1148 offs += 4; 1149 } 1150 1151 // update registers with current function call state 1152 reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc); 1153 reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra); 1154 reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp); 1155 1156 #if HEX_ABI_DEBUG 1157 // quick and dirty stack dumper for debugging 1158 for (int i = -8; i < 8; i++) { 1159 uint32_t data = 0; 1160 lldb::addr_t addr = sp + i * 4; 1161 proc->ReadMemory(addr, (void *)&data, sizeof(data), error); 1162 printf("\n0x%04" PRIx64 " 0x%08x ", addr, data); 1163 if (i == 0) 1164 printf("<<-- sp"); 1165 } 1166 printf("\n"); 1167 #endif 1168 1169 return true; 1170 } 1171 1172 bool ABISysV_hexagon::GetArgumentValues(Thread &thread, 1173 ValueList &values) const { 1174 return false; 1175 } 1176 1177 Status 1178 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp, 1179 lldb::ValueObjectSP &new_value_sp) { 1180 Status error; 1181 return error; 1182 } 1183 1184 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple( 1185 Thread &thread, CompilerType &return_compiler_type) const { 1186 ValueObjectSP return_valobj_sp; 1187 return return_valobj_sp; 1188 } 1189 1190 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl( 1191 Thread &thread, CompilerType &return_compiler_type) const { 1192 ValueObjectSP return_valobj_sp; 1193 return return_valobj_sp; 1194 } 1195 1196 // called when we are on the first instruction of a new function for hexagon 1197 // the return address is in RA (R31) 1198 bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { 1199 unwind_plan.Clear(); 1200 unwind_plan.SetRegisterKind(eRegisterKindGeneric); 1201 unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA); 1202 1203 UnwindPlan::RowSP row(new UnwindPlan::Row); 1204 1205 // Our Call Frame Address is the stack pointer value 1206 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4); 1207 row->SetOffset(0); 1208 1209 // The previous PC is in the LR 1210 row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC, 1211 LLDB_REGNUM_GENERIC_RA, true); 1212 unwind_plan.AppendRow(row); 1213 1214 unwind_plan.SetSourceName("hexagon at-func-entry default"); 1215 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1216 return true; 1217 } 1218 1219 bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { 1220 unwind_plan.Clear(); 1221 unwind_plan.SetRegisterKind(eRegisterKindGeneric); 1222 1223 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP; 1224 uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP; 1225 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC; 1226 1227 UnwindPlan::RowSP row(new UnwindPlan::Row); 1228 1229 row->SetUnspecifiedRegistersAreUndefined(true); 1230 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8); 1231 1232 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true); 1233 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true); 1234 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); 1235 1236 unwind_plan.AppendRow(row); 1237 unwind_plan.SetSourceName("hexagon default unwind plan"); 1238 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); 1239 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); 1240 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); 1241 return true; 1242 } 1243 1244 /* 1245 Register Usage Saved By 1246 1247 R0 - R5 parameters(a) - 1248 R6 - R15 Scratch(b) Caller 1249 R16 - R27 Scratch Callee 1250 R28 Scratch(b) Caller 1251 R29 - R31 Stack Frames Callee(c) 1252 P3:0 Processor State Caller 1253 1254 a = the caller can change parameter values 1255 b = R14 - R15 and R28 are used by the procedure linkage table 1256 c = R29 - R31 are saved and restored by allocframe() and deallocframe() 1257 */ 1258 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) { 1259 return !RegisterIsCalleeSaved(reg_info); 1260 } 1261 1262 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { 1263 int reg = ((reg_info->byte_offset) / 4); 1264 1265 bool save = (reg >= 16) && (reg <= 27); 1266 save |= (reg >= 29) && (reg <= 32); 1267 1268 return save; 1269 } 1270 1271 void ABISysV_hexagon::Initialize() { 1272 PluginManager::RegisterPlugin(GetPluginNameStatic(), 1273 "System V ABI for hexagon targets", 1274 CreateInstance); 1275 } 1276 1277 void ABISysV_hexagon::Terminate() { 1278 PluginManager::UnregisterPlugin(CreateInstance); 1279 } 1280 1281 // get value object specialized to work with llvm IR types 1282 lldb::ValueObjectSP 1283 ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread, 1284 llvm::Type &retType) const { 1285 Value value; 1286 ValueObjectSP vObjSP; 1287 1288 // get the current register context 1289 RegisterContext *reg_ctx = thread.GetRegisterContext().get(); 1290 if (!reg_ctx) 1291 return vObjSP; 1292 1293 // for now just pop R0 to find the return value 1294 const lldb_private::RegisterInfo *r0_info = 1295 reg_ctx->GetRegisterInfoAtIndex(0); 1296 if (r0_info == nullptr) 1297 return vObjSP; 1298 1299 // void return type 1300 if (retType.isVoidTy()) { 1301 value.GetScalar() = 0; 1302 } 1303 // integer / pointer return type 1304 else if (retType.isIntegerTy() || retType.isPointerTy()) { 1305 // read r0 register value 1306 lldb_private::RegisterValue r0_value; 1307 if (!reg_ctx->ReadRegister(r0_info, r0_value)) 1308 return vObjSP; 1309 1310 // push r0 into value 1311 uint32_t r0_u32 = r0_value.GetAsUInt32(); 1312 1313 // account for integer size 1314 if (retType.isIntegerTy() && retType.isSized()) { 1315 uint64_t size = retType.getScalarSizeInBits(); 1316 uint64_t mask = (1ull << size) - 1; 1317 // mask out higher order bits then the type we expect 1318 r0_u32 &= mask; 1319 } 1320 1321 value.GetScalar() = r0_u32; 1322 } 1323 // unsupported return type 1324 else 1325 return vObjSP; 1326 1327 // pack the value into a ValueObjectSP 1328 vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(), 1329 value, ConstString("")); 1330 return vObjSP; 1331 } 1332