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