1327 lines · cpp
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-exception6//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/Symbol/UnwindPlan.h"18#include "lldb/Target/Process.h"19#include "lldb/Target/RegisterContext.h"20#include "lldb/Target/StackFrame.h"21#include "lldb/Target/Target.h"22#include "lldb/Target/Thread.h"23#include "lldb/Utility/ConstString.h"24#include "lldb/Utility/DataExtractor.h"25#include "lldb/Utility/Log.h"26#include "lldb/Utility/RegisterValue.h"27#include "lldb/Utility/Status.h"28#include "lldb/ValueObject/ValueObjectConstResult.h"29#include "lldb/ValueObject/ValueObjectMemory.h"30#include "lldb/ValueObject/ValueObjectRegister.h"31 32using namespace lldb;33using namespace lldb_private;34 35LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon)36 37static const RegisterInfo g_register_infos[] = {38 // hexagon-core.xml39 {"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.xml436 {"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 976static const uint32_t k_num_register_infos =977 sizeof(g_register_infos) / sizeof(RegisterInfo);978 979const lldb_private::RegisterInfo *980ABISysV_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%29987 988 In computing, a red zone is a fixed size area in memory beyond the stack989 pointer that has not been990 "allocated". This region of memory is not to be modified by991 interrupt/exception/signal handlers.992 This allows the space to be used for temporary data without the extra993 overhead of modifying the994 stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC995 toolchain assumes a996 128 byte red zone though it is not documented.997*/998size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }999 1000// Static Functions1001 1002ABISP1003ABISysV_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 1011bool 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 jit1015 return false;1016}1017 1018/*1019 1020// AD:1021// . safeguard the current stack1022// . how can we know that the called function will create its own frame1023properly?1024// . we could manually make a new stack first:1025// 2. push RA1026// 3. push FP1027// 4. FP = SP1028// 5. SP = SP ( since no locals in our temp frame )1029 1030// AD 6/05/20141031// . variable argument list parameters are not passed via registers, they are1032passed on1033// the stack. This presents us with a problem, since we need to know when1034the valist1035// starts. Currently I can find out if a function is varg, but not how many1036// real parameters it takes. Thus I don't know when to start spilling the1037vargs. For1038// the time being, to progress, I will assume that it takes on real parameter1039before1040// the vargs list starts.1041 1042// AD 06/05/20141043// . how do we adhere to the stack alignment requirements1044 1045// AD 06/05/20141046// . handle 64bit values and their register / stack requirements1047 1048*/1049#define HEX_ABI_DEBUG 01050bool 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 functions1054 const int nVArgRegParams = 1;1055 Status error;1056 1057 // grab the process so we have access to the memory for spilling1058 lldb::ProcessSP proc = thread.GetProcess();1059 1060 // get the register context for modifying all of the registers1061 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 target1081 for (size_t i = 0; i < args.size(); i++) {1082 const ABI::CallArgument &arg = args[i];1083 // skip over target values1084 if (arg.type == ABI::CallArgument::TargetValue)1085 continue;1086 // round up to 8 byte multiple1087 size_t argSize = (arg.size | 0x7) + 1;1088 1089 // create space on the stack for this data1090 sp -= argSize;1091 1092 // write this argument onto the stack of the host process1093 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 pointer1098 // XXX: This is a gross hack for getting around the const1099 *const_cast<lldb::addr_t *>(&arg.value) = sp;1100 }1101 1102#if HEX_ABI_DEBUG1103 // print the original stack pointer1104 printf("sp : %04" PRIx64 " \n", sp);1105#endif1106 1107 // make sure number of parameters matches prototype1108 assert(prototype.getFunctionNumParams() == args.size());1109 1110 // check if this is a variable argument function1111 bool isVArg = prototype.isFunctionVarArg();1112 1113 // number of arguments passed by register1114 int nRegArgs = nVArgRegParams;1115 if (!isVArg) {1116 // number of arguments is limited by [R0 : R5] space1117 nRegArgs = args.size();1118 if (nRegArgs > 6)1119 nRegArgs = 6;1120 }1121 1122 // pass arguments that are passed via registers1123 for (int i = 0; i < nRegArgs; i++) {1124 // get the parameter as a u321125 uint32_t param = (uint32_t)args[i].value;1126 // write argument into register1127 if (!reg_ctx->WriteRegisterFromUnsigned(i, param))1128 return false;1129 }1130 1131 // number of arguments to spill onto stack1132 int nSpillArgs = args.size() - nRegArgs;1133 // make space on the stack for arguments1134 sp -= 4 * nSpillArgs;1135 // align stack on an 8 byte boundary1136 if (sp & 7)1137 sp -= 4;1138 1139 // arguments that are passed on the stack1140 for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {1141 // get the parameter as a u321142 uint32_t param = (uint32_t)args[i].value;1143 // write argument to stack1144 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 state1152 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_DEBUG1157 // quick and dirty stack dumper for debugging1158 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#endif1168 1169 return true;1170}1171 1172bool ABISysV_hexagon::GetArgumentValues(Thread &thread,1173 ValueList &values) const {1174 return false;1175}1176 1177Status1178ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,1179 lldb::ValueObjectSP &new_value_sp) {1180 Status error;1181 return error;1182}1183 1184ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(1185 Thread &thread, CompilerType &return_compiler_type) const {1186 ValueObjectSP return_valobj_sp;1187 return return_valobj_sp;1188}1189 1190ValueObjectSP 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 hexagon1197// the return address is in RA (R31)1198UnwindPlanSP ABISysV_hexagon::CreateFunctionEntryUnwindPlan() {1199 UnwindPlan::Row row;1200 1201 // Our Call Frame Address is the stack pointer value1202 row.GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);1203 1204 // The previous PC is in the LR1205 row.SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,1206 LLDB_REGNUM_GENERIC_RA, true);1207 1208 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindGeneric);1209 plan_sp->AppendRow(std::move(row));1210 plan_sp->SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);1211 plan_sp->SetSourceName("hexagon at-func-entry default");1212 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);1213 return plan_sp;1214}1215 1216UnwindPlanSP ABISysV_hexagon::CreateDefaultUnwindPlan() {1217 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;1218 uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;1219 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;1220 1221 UnwindPlan::Row row;1222 1223 row.SetUnspecifiedRegistersAreUndefined(true);1224 row.GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);1225 1226 row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);1227 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);1228 row.SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);1229 1230 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindGeneric);1231 plan_sp->AppendRow(std::move(row));1232 plan_sp->SetSourceName("hexagon default unwind plan");1233 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);1234 plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);1235 plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);1236 return plan_sp;1237}1238 1239/*1240 Register Usage Saved By1241 1242 R0 - R5 parameters(a) -1243 R6 - R15 Scratch(b) Caller1244 R16 - R27 Scratch Callee1245 R28 Scratch(b) Caller1246 R29 - R31 Stack Frames Callee(c)1247 P3:0 Processor State Caller1248 1249 a = the caller can change parameter values1250 b = R14 - R15 and R28 are used by the procedure linkage table1251 c = R29 - R31 are saved and restored by allocframe() and deallocframe()1252*/1253bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {1254 return !RegisterIsCalleeSaved(reg_info);1255}1256 1257bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {1258 int reg = ((reg_info->byte_offset) / 4);1259 1260 bool save = (reg >= 16) && (reg <= 27);1261 save |= (reg >= 29) && (reg <= 32);1262 1263 return save;1264}1265 1266void ABISysV_hexagon::Initialize() {1267 PluginManager::RegisterPlugin(GetPluginNameStatic(),1268 "System V ABI for hexagon targets",1269 CreateInstance);1270}1271 1272void ABISysV_hexagon::Terminate() {1273 PluginManager::UnregisterPlugin(CreateInstance);1274}1275 1276// get value object specialized to work with llvm IR types1277lldb::ValueObjectSP1278ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,1279 llvm::Type &retType) const {1280 Value value;1281 ValueObjectSP vObjSP;1282 1283 // get the current register context1284 RegisterContext *reg_ctx = thread.GetRegisterContext().get();1285 if (!reg_ctx)1286 return vObjSP;1287 1288 // for now just pop R0 to find the return value1289 const lldb_private::RegisterInfo *r0_info =1290 reg_ctx->GetRegisterInfoAtIndex(0);1291 if (r0_info == nullptr)1292 return vObjSP;1293 1294 // void return type1295 if (retType.isVoidTy()) {1296 value.GetScalar() = 0;1297 }1298 // integer / pointer return type1299 else if (retType.isIntegerTy() || retType.isPointerTy()) {1300 // read r0 register value1301 lldb_private::RegisterValue r0_value;1302 if (!reg_ctx->ReadRegister(r0_info, r0_value))1303 return vObjSP;1304 1305 // push r0 into value1306 uint32_t r0_u32 = r0_value.GetAsUInt32();1307 1308 // account for integer size1309 if (retType.isIntegerTy() && retType.isSized()) {1310 uint64_t size = retType.getScalarSizeInBits();1311 uint64_t mask = (1ull << size) - 1;1312 // mask out higher order bits then the type we expect1313 r0_u32 &= mask;1314 }1315 1316 value.GetScalar() = r0_u32;1317 }1318 // unsupported return type1319 else1320 return vObjSP;1321 1322 // pack the value into a ValueObjectSP1323 vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),1324 value, ConstString(""));1325 return vObjSP;1326}1327