Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp
39653 views
//===-- ABISysV_hexagon.cpp -----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "ABISysV_hexagon.h"910#include "llvm/IR/DerivedTypes.h"11#include "llvm/TargetParser/Triple.h"1213#include "lldb/Core/Module.h"14#include "lldb/Core/PluginManager.h"15#include "lldb/Core/Value.h"16#include "lldb/Core/ValueObjectConstResult.h"17#include "lldb/Core/ValueObjectMemory.h"18#include "lldb/Core/ValueObjectRegister.h"19#include "lldb/Symbol/UnwindPlan.h"20#include "lldb/Target/Process.h"21#include "lldb/Target/RegisterContext.h"22#include "lldb/Target/StackFrame.h"23#include "lldb/Target/Target.h"24#include "lldb/Target/Thread.h"25#include "lldb/Utility/ConstString.h"26#include "lldb/Utility/DataExtractor.h"27#include "lldb/Utility/Log.h"28#include "lldb/Utility/RegisterValue.h"29#include "lldb/Utility/Status.h"3031using namespace lldb;32using namespace lldb_private;3334LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon)3536static const RegisterInfo g_register_infos[] = {37// hexagon-core.xml38{"r00",39"",404,410,42eEncodingUint,43eFormatAddressInfo,44{0, 0, LLDB_INVALID_REGNUM, 0, 0},45nullptr,46nullptr,47nullptr,48},49{"r01",50"",514,520,53eEncodingUint,54eFormatAddressInfo,55{1, 1, LLDB_INVALID_REGNUM, 1, 1},56nullptr,57nullptr,58nullptr,59},60{"r02",61"",624,630,64eEncodingUint,65eFormatAddressInfo,66{2, 2, LLDB_INVALID_REGNUM, 2, 2},67nullptr,68nullptr,69nullptr,70},71{"r03",72"",734,740,75eEncodingUint,76eFormatAddressInfo,77{3, 3, LLDB_INVALID_REGNUM, 3, 3},78nullptr,79nullptr,80nullptr,81},82{"r04",83"",844,850,86eEncodingUint,87eFormatAddressInfo,88{4, 4, LLDB_INVALID_REGNUM, 4, 4},89nullptr,90nullptr,91nullptr,92},93{"r05",94"",954,960,97eEncodingUint,98eFormatAddressInfo,99{5, 5, LLDB_INVALID_REGNUM, 5, 5},100nullptr,101nullptr,102nullptr,103},104{"r06",105"",1064,1070,108eEncodingUint,109eFormatAddressInfo,110{6, 6, LLDB_INVALID_REGNUM, 6, 6},111nullptr,112nullptr,113nullptr,114},115{"r07",116"",1174,1180,119eEncodingUint,120eFormatAddressInfo,121{7, 7, LLDB_INVALID_REGNUM, 7, 7},122nullptr,123nullptr,124nullptr,125},126{"r08",127"",1284,1290,130eEncodingUint,131eFormatAddressInfo,132{8, 8, LLDB_INVALID_REGNUM, 8, 8},133nullptr,134nullptr,135nullptr,136},137{"r09",138"",1394,1400,141eEncodingUint,142eFormatAddressInfo,143{9, 9, LLDB_INVALID_REGNUM, 9, 9},144nullptr,145nullptr,146nullptr,147},148{"r10",149"",1504,1510,152eEncodingUint,153eFormatAddressInfo,154{10, 10, LLDB_INVALID_REGNUM, 10, 10},155nullptr,156nullptr,157nullptr,158},159{"r11",160"",1614,1620,163eEncodingUint,164eFormatAddressInfo,165{11, 11, LLDB_INVALID_REGNUM, 11, 11},166nullptr,167nullptr,168nullptr,169},170{"r12",171"",1724,1730,174eEncodingUint,175eFormatAddressInfo,176{12, 12, LLDB_INVALID_REGNUM, 12, 12},177nullptr,178nullptr,179nullptr,180},181{"r13",182"",1834,1840,185eEncodingUint,186eFormatAddressInfo,187{13, 13, LLDB_INVALID_REGNUM, 13, 13},188nullptr,189nullptr,190nullptr,191},192{"r14",193"",1944,1950,196eEncodingUint,197eFormatAddressInfo,198{14, 14, LLDB_INVALID_REGNUM, 14, 14},199nullptr,200nullptr,201nullptr,202},203{"r15",204"",2054,2060,207eEncodingUint,208eFormatAddressInfo,209{15, 15, LLDB_INVALID_REGNUM, 15, 15},210nullptr,211nullptr,212nullptr,213},214{"r16",215"",2164,2170,218eEncodingUint,219eFormatAddressInfo,220{16, 16, LLDB_INVALID_REGNUM, 16, 16},221nullptr,222nullptr,223nullptr,224},225{"r17",226"",2274,2280,229eEncodingUint,230eFormatAddressInfo,231{17, 17, LLDB_INVALID_REGNUM, 17, 17},232nullptr,233nullptr,234nullptr,235},236{"r18",237"",2384,2390,240eEncodingUint,241eFormatAddressInfo,242{18, 18, LLDB_INVALID_REGNUM, 18, 18},243nullptr,244nullptr,245nullptr,246},247{"r19",248"",2494,2500,251eEncodingUint,252eFormatAddressInfo,253{19, 19, LLDB_INVALID_REGNUM, 19, 19},254nullptr,255nullptr,256nullptr,257},258{"r20",259"",2604,2610,262eEncodingUint,263eFormatAddressInfo,264{20, 20, LLDB_INVALID_REGNUM, 20, 20},265nullptr,266nullptr,267nullptr,268},269{"r21",270"",2714,2720,273eEncodingUint,274eFormatAddressInfo,275{21, 21, LLDB_INVALID_REGNUM, 21, 21},276nullptr,277nullptr,278nullptr,279},280{"r22",281"",2824,2830,284eEncodingUint,285eFormatAddressInfo,286{22, 22, LLDB_INVALID_REGNUM, 22, 22},287nullptr,288nullptr,289nullptr,290},291{"r23",292"",2934,2940,295eEncodingUint,296eFormatAddressInfo,297{23, 23, LLDB_INVALID_REGNUM, 23, 23},298nullptr,299nullptr,300nullptr,301},302{"r24",303"",3044,3050,306eEncodingUint,307eFormatAddressInfo,308{24, 24, LLDB_INVALID_REGNUM, 24, 24},309nullptr,310nullptr,311nullptr,312},313{"r25",314"",3154,3160,317eEncodingUint,318eFormatAddressInfo,319{25, 25, LLDB_INVALID_REGNUM, 25, 25},320nullptr,321nullptr,322nullptr,323},324{"r26",325"",3264,3270,328eEncodingUint,329eFormatAddressInfo,330{26, 26, LLDB_INVALID_REGNUM, 26, 26},331nullptr,332nullptr,333nullptr,334},335{"r27",336"",3374,3380,339eEncodingUint,340eFormatAddressInfo,341{27, 27, LLDB_INVALID_REGNUM, 27, 27},342nullptr,343nullptr,344nullptr,345},346{"r28",347"",3484,3490,350eEncodingUint,351eFormatAddressInfo,352{28, 28, LLDB_INVALID_REGNUM, 28, 28},353nullptr,354nullptr,355nullptr,356},357{"sp",358"r29",3594,3600,361eEncodingUint,362eFormatAddressInfo,363{29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29},364nullptr,365nullptr,366nullptr,367},368{"fp",369"r30",3704,3710,372eEncodingUint,373eFormatAddressInfo,374{30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30},375nullptr,376nullptr,377nullptr,378},379{"lr",380"r31",3814,3820,383eEncodingUint,384eFormatAddressInfo,385{31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31},386nullptr,387nullptr,388nullptr,389},390{"sa0",391"",3924,3930,394eEncodingUint,395eFormatAddressInfo,396{32, 32, LLDB_INVALID_REGNUM, 32, 32},397nullptr,398nullptr,399nullptr,400},401{"lc0",402"",4034,4040,405eEncodingUint,406eFormatAddressInfo,407{33, 33, LLDB_INVALID_REGNUM, 33, 33},408nullptr,409nullptr,410nullptr,411},412{"sa1",413"",4144,4150,416eEncodingUint,417eFormatAddressInfo,418{34, 34, LLDB_INVALID_REGNUM, 34, 34},419nullptr,420nullptr,421nullptr,422},423{"lc1",424"",4254,4260,427eEncodingUint,428eFormatAddressInfo,429{35, 35, LLDB_INVALID_REGNUM, 35, 35},430nullptr,431nullptr,432nullptr,433},434// --> hexagon-v4/5/55/56-sim.xml435{"p3_0",436"",4374,4380,439eEncodingUint,440eFormatAddressInfo,441{36, 36, LLDB_INVALID_REGNUM, 36, 36},442nullptr,443nullptr,444nullptr,445446},447// PADDING {448{"p00",449"",4504,4510,452eEncodingInvalid,453eFormatInvalid,454{37, 37, LLDB_INVALID_REGNUM, 37, 37},455nullptr,456nullptr,457nullptr,458},459// }460{"m0",461"",4624,4630,464eEncodingUint,465eFormatAddressInfo,466{38, 38, LLDB_INVALID_REGNUM, 38, 38},467nullptr,468nullptr,469nullptr,470},471{"m1",472"",4734,4740,475eEncodingUint,476eFormatAddressInfo,477{39, 39, LLDB_INVALID_REGNUM, 39, 39},478nullptr,479nullptr,480nullptr,481},482{"usr",483"",4844,4850,486eEncodingUint,487eFormatAddressInfo,488{40, 40, LLDB_INVALID_REGNUM, 40, 40},489nullptr,490nullptr,491nullptr,492},493{"pc",494"",4954,4960,497eEncodingUint,498eFormatAddressInfo,499{41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},500nullptr,501nullptr,502nullptr,503},504{"ugp",505"",5064,5070,508eEncodingUint,509eFormatAddressInfo,510{42, 42, LLDB_INVALID_REGNUM, 42, 42},511nullptr,512nullptr,513nullptr,514},515{"gp",516"",5174,5180,519eEncodingUint,520eFormatAddressInfo,521{43, 43, LLDB_INVALID_REGNUM, 43, 43},522nullptr,523nullptr,524nullptr,525},526{"cs0",527"",5284,5290,530eEncodingUint,531eFormatAddressInfo,532{44, 44, LLDB_INVALID_REGNUM, 44, 44},533nullptr,534nullptr,535nullptr,536},537{"cs1",538"",5394,5400,541eEncodingUint,542eFormatAddressInfo,543{45, 45, LLDB_INVALID_REGNUM, 45, 45},544nullptr,545nullptr,546nullptr,547},548// PADDING {549{"p01",550"",5514,5520,553eEncodingInvalid,554eFormatInvalid,555{46, 46, LLDB_INVALID_REGNUM, 46, 46},556nullptr,557nullptr,558nullptr,559},560{"p02",561"",5624,5630,564eEncodingInvalid,565eFormatInvalid,566{47, 47, LLDB_INVALID_REGNUM, 47, 47},567nullptr,568nullptr,569nullptr,570},571{"p03",572"",5734,5740,575eEncodingInvalid,576eFormatInvalid,577{48, 48, LLDB_INVALID_REGNUM, 48, 48},578nullptr,579nullptr,580nullptr,581},582{"p04",583"",5844,5850,586eEncodingInvalid,587eFormatInvalid,588{49, 49, LLDB_INVALID_REGNUM, 49, 49},589nullptr,590nullptr,591nullptr,592},593{"p05",594"",5954,5960,597eEncodingInvalid,598eFormatInvalid,599{50, 50, LLDB_INVALID_REGNUM, 50, 50},600nullptr,601nullptr,602nullptr,603},604{"p06",605"",6064,6070,608eEncodingInvalid,609eFormatInvalid,610{51, 51, LLDB_INVALID_REGNUM, 51, 51},611nullptr,612nullptr,613nullptr,614},615{"p07",616"",6174,6180,619eEncodingInvalid,620eFormatInvalid,621{52, 52, LLDB_INVALID_REGNUM, 52, 52},622nullptr,623nullptr,624nullptr,625},626{"p08",627"",6284,6290,630eEncodingInvalid,631eFormatInvalid,632{53, 53, LLDB_INVALID_REGNUM, 53, 53},633nullptr,634nullptr,635nullptr,636},637{"p09",638"",6394,6400,641eEncodingInvalid,642eFormatInvalid,643{54, 54, LLDB_INVALID_REGNUM, 54, 54},644nullptr,645nullptr,646nullptr,647},648{"p10",649"",6504,6510,652eEncodingInvalid,653eFormatInvalid,654{55, 55, LLDB_INVALID_REGNUM, 55, 55},655nullptr,656nullptr,657nullptr,658},659{"p11",660"",6614,6620,663eEncodingInvalid,664eFormatInvalid,665{56, 56, LLDB_INVALID_REGNUM, 56, 56},666nullptr,667nullptr,668nullptr,669},670{"p12",671"",6724,6730,674eEncodingInvalid,675eFormatInvalid,676{57, 57, LLDB_INVALID_REGNUM, 57, 57},677nullptr,678nullptr,679nullptr,680},681{"p13",682"",6834,6840,685eEncodingInvalid,686eFormatInvalid,687{58, 58, LLDB_INVALID_REGNUM, 58, 58},688nullptr,689nullptr,690nullptr,691},692{"p14",693"",6944,6950,696eEncodingInvalid,697eFormatInvalid,698{59, 59, LLDB_INVALID_REGNUM, 59, 59},699nullptr,700nullptr,701nullptr,702},703{"p15",704"",7054,7060,707eEncodingInvalid,708eFormatInvalid,709{60, 60, LLDB_INVALID_REGNUM, 60, 60},710nullptr,711nullptr,712nullptr,713},714{"p16",715"",7164,7170,718eEncodingInvalid,719eFormatInvalid,720{61, 61, LLDB_INVALID_REGNUM, 61, 61},721nullptr,722nullptr,723nullptr,724},725{"p17",726"",7274,7280,729eEncodingInvalid,730eFormatInvalid,731{62, 62, LLDB_INVALID_REGNUM, 62, 62},732nullptr,733nullptr,734nullptr,735},736{"p18",737"",7384,7390,740eEncodingInvalid,741eFormatInvalid,742{63, 63, LLDB_INVALID_REGNUM, 63, 63},743nullptr,744nullptr,745nullptr,746},747// }748{"sgp0",749"",7504,7510,752eEncodingUint,753eFormatAddressInfo,754{64, 64, LLDB_INVALID_REGNUM, 64, 64},755nullptr,756nullptr,757nullptr,758},759// PADDING {760{"p19",761"",7624,7630,764eEncodingInvalid,765eFormatInvalid,766{65, 65, LLDB_INVALID_REGNUM, 65, 65},767nullptr,768nullptr,769nullptr,770},771// }772{"stid",773"",7744,7750,776eEncodingUint,777eFormatAddressInfo,778{66, 66, LLDB_INVALID_REGNUM, 66, 66},779nullptr,780nullptr,781nullptr,782},783{"elr",784"",7854,7860,787eEncodingUint,788eFormatAddressInfo,789{67, 67, LLDB_INVALID_REGNUM, 67, 67},790nullptr,791nullptr,792nullptr,793},794{"badva0",795"",7964,7970,798eEncodingUint,799eFormatAddressInfo,800{68, 68, LLDB_INVALID_REGNUM, 68, 68},801nullptr,802nullptr,803nullptr,804},805{"badva1",806"",8074,8080,809eEncodingUint,810eFormatAddressInfo,811{69, 69, LLDB_INVALID_REGNUM, 69, 69},812nullptr,813nullptr,814nullptr,815},816{"ssr",817"",8184,8190,820eEncodingUint,821eFormatAddressInfo,822{70, 70, LLDB_INVALID_REGNUM, 70, 70},823nullptr,824nullptr,825nullptr,826},827{"ccr",828"",8294,8300,831eEncodingUint,832eFormatAddressInfo,833{71, 71, LLDB_INVALID_REGNUM, 71, 71},834nullptr,835nullptr,836nullptr,837},838{"htid",839"",8404,8410,842eEncodingUint,843eFormatAddressInfo,844{72, 72, LLDB_INVALID_REGNUM, 72, 72},845nullptr,846nullptr,847nullptr,848},849// PADDING {850{"p20",851"",8524,8530,854eEncodingInvalid,855eFormatInvalid,856{73, 73, LLDB_INVALID_REGNUM, 73, 73},857nullptr,858nullptr,859nullptr,860},861// }862{"imask",863"",8644,8650,866eEncodingUint,867eFormatAddressInfo,868{74, 74, LLDB_INVALID_REGNUM, 74, 74},869nullptr,870nullptr,871nullptr,872},873// PADDING {874{"p21",875"",8764,8770,878eEncodingInvalid,879eFormatInvalid,880{75, 75, LLDB_INVALID_REGNUM, 75, 75},881nullptr,882nullptr,883nullptr,884},885{"p22",886"",8874,8880,889eEncodingInvalid,890eFormatInvalid,891{76, 76, LLDB_INVALID_REGNUM, 76, 76},892nullptr,893nullptr,894nullptr,895},896{"p23",897"",8984,8990,900eEncodingInvalid,901eFormatInvalid,902{77, 77, LLDB_INVALID_REGNUM, 77, 77},903nullptr,904nullptr,905nullptr,906},907{"p24",908"",9094,9100,911eEncodingInvalid,912eFormatInvalid,913{78, 78, LLDB_INVALID_REGNUM, 78, 78},914nullptr,915nullptr,916nullptr,917},918{"p25",919"",9204,9210,922eEncodingInvalid,923eFormatInvalid,924{79, 79, LLDB_INVALID_REGNUM, 79, 79},925nullptr,926nullptr,927nullptr,928},929// }930{"g0",931"",9324,9330,934eEncodingUint,935eFormatAddressInfo,936{80, 80, LLDB_INVALID_REGNUM, 80, 80},937nullptr,938nullptr,939nullptr,940},941{"g1",942"",9434,9440,945eEncodingUint,946eFormatAddressInfo,947{81, 81, LLDB_INVALID_REGNUM, 81, 81},948nullptr,949nullptr,950nullptr,951},952{"g2",953"",9544,9550,956eEncodingUint,957eFormatAddressInfo,958{82, 82, LLDB_INVALID_REGNUM, 82, 82},959nullptr,960nullptr,961nullptr,962},963{"g3",964"",9654,9660,967eEncodingUint,968eFormatAddressInfo,969{83, 83, LLDB_INVALID_REGNUM, 83, 83},970nullptr,971nullptr,972nullptr,973}};974975static const uint32_t k_num_register_infos =976sizeof(g_register_infos) / sizeof(RegisterInfo);977978const lldb_private::RegisterInfo *979ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) {980count = k_num_register_infos;981return g_register_infos;982}983984/*985http://en.wikipedia.org/wiki/Red_zone_%28computing%29986987In computing, a red zone is a fixed size area in memory beyond the stack988pointer that has not been989"allocated". This region of memory is not to be modified by990interrupt/exception/signal handlers.991This allows the space to be used for temporary data without the extra992overhead of modifying the993stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC994toolchain assumes a995128 byte red zone though it is not documented.996*/997size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }998999// Static Functions10001001ABISP1002ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {1003if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {1004return ABISP(1005new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch)));1006}1007return ABISP();1008}10091010bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,1011lldb::addr_t pc, lldb::addr_t ra,1012llvm::ArrayRef<addr_t> args) const {1013// we don't use the traditional trivial call specialized for jit1014return false;1015}10161017/*10181019// AD:1020// . safeguard the current stack1021// . how can we know that the called function will create its own frame1022properly?1023// . we could manually make a new stack first:1024// 2. push RA1025// 3. push FP1026// 4. FP = SP1027// 5. SP = SP ( since no locals in our temp frame )10281029// AD 6/05/20141030// . variable argument list parameters are not passed via registers, they are1031passed on1032// the stack. This presents us with a problem, since we need to know when1033the valist1034// starts. Currently I can find out if a function is varg, but not how many1035// real parameters it takes. Thus I don't know when to start spilling the1036vargs. For1037// the time being, to progress, I will assume that it takes on real parameter1038before1039// the vargs list starts.10401041// AD 06/05/20141042// . how do we adhere to the stack alignment requirements10431044// AD 06/05/20141045// . handle 64bit values and their register / stack requirements10461047*/1048#define HEX_ABI_DEBUG 01049bool ABISysV_hexagon::PrepareTrivialCall(1050Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,1051llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {1052// default number of register passed arguments for varg functions1053const int nVArgRegParams = 1;1054Status error;10551056// grab the process so we have access to the memory for spilling1057lldb::ProcessSP proc = thread.GetProcess();10581059// get the register context for modifying all of the registers1060RegisterContext *reg_ctx = thread.GetRegisterContext().get();1061if (!reg_ctx)1062return false;10631064uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(1065eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);1066if (pc_reg == LLDB_INVALID_REGNUM)1067return false;10681069uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(1070eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);1071if (ra_reg == LLDB_INVALID_REGNUM)1072return false;10731074uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(1075eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);1076if (sp_reg == LLDB_INVALID_REGNUM)1077return false;10781079// push host data onto target1080for (size_t i = 0; i < args.size(); i++) {1081const ABI::CallArgument &arg = args[i];1082// skip over target values1083if (arg.type == ABI::CallArgument::TargetValue)1084continue;1085// round up to 8 byte multiple1086size_t argSize = (arg.size | 0x7) + 1;10871088// create space on the stack for this data1089sp -= argSize;10901091// write this argument onto the stack of the host process1092proc->WriteMemory(sp, arg.data_up.get(), arg.size, error);1093if (error.Fail())1094return false;10951096// update the argument with the target pointer1097// XXX: This is a gross hack for getting around the const1098*const_cast<lldb::addr_t *>(&arg.value) = sp;1099}11001101#if HEX_ABI_DEBUG1102// print the original stack pointer1103printf("sp : %04" PRIx64 " \n", sp);1104#endif11051106// make sure number of parameters matches prototype1107assert(prototype.getFunctionNumParams() == args.size());11081109// check if this is a variable argument function1110bool isVArg = prototype.isFunctionVarArg();11111112// number of arguments passed by register1113int nRegArgs = nVArgRegParams;1114if (!isVArg) {1115// number of arguments is limited by [R0 : R5] space1116nRegArgs = args.size();1117if (nRegArgs > 6)1118nRegArgs = 6;1119}11201121// pass arguments that are passed via registers1122for (int i = 0; i < nRegArgs; i++) {1123// get the parameter as a u321124uint32_t param = (uint32_t)args[i].value;1125// write argument into register1126if (!reg_ctx->WriteRegisterFromUnsigned(i, param))1127return false;1128}11291130// number of arguments to spill onto stack1131int nSpillArgs = args.size() - nRegArgs;1132// make space on the stack for arguments1133sp -= 4 * nSpillArgs;1134// align stack on an 8 byte boundary1135if (sp & 7)1136sp -= 4;11371138// arguments that are passed on the stack1139for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {1140// get the parameter as a u321141uint32_t param = (uint32_t)args[i].value;1142// write argument to stack1143proc->WriteMemory(sp + offs, (void *)¶m, sizeof(param), error);1144if (!error.Success())1145return false;1146//1147offs += 4;1148}11491150// update registers with current function call state1151reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);1152reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);1153reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);11541155#if HEX_ABI_DEBUG1156// quick and dirty stack dumper for debugging1157for (int i = -8; i < 8; i++) {1158uint32_t data = 0;1159lldb::addr_t addr = sp + i * 4;1160proc->ReadMemory(addr, (void *)&data, sizeof(data), error);1161printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);1162if (i == 0)1163printf("<<-- sp");1164}1165printf("\n");1166#endif11671168return true;1169}11701171bool ABISysV_hexagon::GetArgumentValues(Thread &thread,1172ValueList &values) const {1173return false;1174}11751176Status1177ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,1178lldb::ValueObjectSP &new_value_sp) {1179Status error;1180return error;1181}11821183ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(1184Thread &thread, CompilerType &return_compiler_type) const {1185ValueObjectSP return_valobj_sp;1186return return_valobj_sp;1187}11881189ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(1190Thread &thread, CompilerType &return_compiler_type) const {1191ValueObjectSP return_valobj_sp;1192return return_valobj_sp;1193}11941195// called when we are on the first instruction of a new function for hexagon1196// the return address is in RA (R31)1197bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {1198unwind_plan.Clear();1199unwind_plan.SetRegisterKind(eRegisterKindGeneric);1200unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);12011202UnwindPlan::RowSP row(new UnwindPlan::Row);12031204// Our Call Frame Address is the stack pointer value1205row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);1206row->SetOffset(0);12071208// The previous PC is in the LR1209row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,1210LLDB_REGNUM_GENERIC_RA, true);1211unwind_plan.AppendRow(row);12121213unwind_plan.SetSourceName("hexagon at-func-entry default");1214unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);1215return true;1216}12171218bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {1219unwind_plan.Clear();1220unwind_plan.SetRegisterKind(eRegisterKindGeneric);12211222uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;1223uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;1224uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;12251226UnwindPlan::RowSP row(new UnwindPlan::Row);12271228row->SetUnspecifiedRegistersAreUndefined(true);1229row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);12301231row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);1232row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);1233row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);12341235unwind_plan.AppendRow(row);1236unwind_plan.SetSourceName("hexagon default unwind plan");1237unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);1238unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);1239unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);1240return true;1241}12421243/*1244Register Usage Saved By12451246R0 - R5 parameters(a) -1247R6 - R15 Scratch(b) Caller1248R16 - R27 Scratch Callee1249R28 Scratch(b) Caller1250R29 - R31 Stack Frames Callee(c)1251P3:0 Processor State Caller12521253a = the caller can change parameter values1254b = R14 - R15 and R28 are used by the procedure linkage table1255c = R29 - R31 are saved and restored by allocframe() and deallocframe()1256*/1257bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {1258return !RegisterIsCalleeSaved(reg_info);1259}12601261bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {1262int reg = ((reg_info->byte_offset) / 4);12631264bool save = (reg >= 16) && (reg <= 27);1265save |= (reg >= 29) && (reg <= 32);12661267return save;1268}12691270void ABISysV_hexagon::Initialize() {1271PluginManager::RegisterPlugin(GetPluginNameStatic(),1272"System V ABI for hexagon targets",1273CreateInstance);1274}12751276void ABISysV_hexagon::Terminate() {1277PluginManager::UnregisterPlugin(CreateInstance);1278}12791280// get value object specialized to work with llvm IR types1281lldb::ValueObjectSP1282ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,1283llvm::Type &retType) const {1284Value value;1285ValueObjectSP vObjSP;12861287// get the current register context1288RegisterContext *reg_ctx = thread.GetRegisterContext().get();1289if (!reg_ctx)1290return vObjSP;12911292// for now just pop R0 to find the return value1293const lldb_private::RegisterInfo *r0_info =1294reg_ctx->GetRegisterInfoAtIndex(0);1295if (r0_info == nullptr)1296return vObjSP;12971298// void return type1299if (retType.isVoidTy()) {1300value.GetScalar() = 0;1301}1302// integer / pointer return type1303else if (retType.isIntegerTy() || retType.isPointerTy()) {1304// read r0 register value1305lldb_private::RegisterValue r0_value;1306if (!reg_ctx->ReadRegister(r0_info, r0_value))1307return vObjSP;13081309// push r0 into value1310uint32_t r0_u32 = r0_value.GetAsUInt32();13111312// account for integer size1313if (retType.isIntegerTy() && retType.isSized()) {1314uint64_t size = retType.getScalarSizeInBits();1315uint64_t mask = (1ull << size) - 1;1316// mask out higher order bits then the type we expect1317r0_u32 &= mask;1318}13191320value.GetScalar() = r0_u32;1321}1322// unsupported return type1323else1324return vObjSP;13251326// pack the value into a ValueObjectSP1327vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),1328value, ConstString(""));1329return vObjSP;1330}133113321333