1 //===-- ABISysV_hexagon.cpp -----------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ABISysV_hexagon.h"
11 #include "llvm/IR/DerivedTypes.h"
12 #include "llvm/TargetParser/Triple.h"
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"
33 using namespace lldb_private
;
35 LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon
, ABIHexagon
)
37 static const RegisterInfo g_register_infos
[] = {
45 {0, 0, LLDB_INVALID_REGNUM
, 0, 0},
56 {1, 1, LLDB_INVALID_REGNUM
, 1, 1},
67 {2, 2, LLDB_INVALID_REGNUM
, 2, 2},
78 {3, 3, LLDB_INVALID_REGNUM
, 3, 3},
89 {4, 4, LLDB_INVALID_REGNUM
, 4, 4},
100 {5, 5, LLDB_INVALID_REGNUM
, 5, 5},
111 {6, 6, LLDB_INVALID_REGNUM
, 6, 6},
122 {7, 7, LLDB_INVALID_REGNUM
, 7, 7},
133 {8, 8, LLDB_INVALID_REGNUM
, 8, 8},
144 {9, 9, LLDB_INVALID_REGNUM
, 9, 9},
155 {10, 10, LLDB_INVALID_REGNUM
, 10, 10},
166 {11, 11, LLDB_INVALID_REGNUM
, 11, 11},
177 {12, 12, LLDB_INVALID_REGNUM
, 12, 12},
188 {13, 13, LLDB_INVALID_REGNUM
, 13, 13},
199 {14, 14, LLDB_INVALID_REGNUM
, 14, 14},
210 {15, 15, LLDB_INVALID_REGNUM
, 15, 15},
221 {16, 16, LLDB_INVALID_REGNUM
, 16, 16},
232 {17, 17, LLDB_INVALID_REGNUM
, 17, 17},
243 {18, 18, LLDB_INVALID_REGNUM
, 18, 18},
254 {19, 19, LLDB_INVALID_REGNUM
, 19, 19},
265 {20, 20, LLDB_INVALID_REGNUM
, 20, 20},
276 {21, 21, LLDB_INVALID_REGNUM
, 21, 21},
287 {22, 22, LLDB_INVALID_REGNUM
, 22, 22},
298 {23, 23, LLDB_INVALID_REGNUM
, 23, 23},
309 {24, 24, LLDB_INVALID_REGNUM
, 24, 24},
320 {25, 25, LLDB_INVALID_REGNUM
, 25, 25},
331 {26, 26, LLDB_INVALID_REGNUM
, 26, 26},
342 {27, 27, LLDB_INVALID_REGNUM
, 27, 27},
353 {28, 28, LLDB_INVALID_REGNUM
, 28, 28},
364 {29, 29, LLDB_REGNUM_GENERIC_SP
, 29, 29},
375 {30, 30, LLDB_REGNUM_GENERIC_FP
, 30, 30},
386 {31, 31, LLDB_REGNUM_GENERIC_RA
, 31, 31},
397 {32, 32, LLDB_INVALID_REGNUM
, 32, 32},
408 {33, 33, LLDB_INVALID_REGNUM
, 33, 33},
419 {34, 34, LLDB_INVALID_REGNUM
, 34, 34},
430 {35, 35, LLDB_INVALID_REGNUM
, 35, 35},
435 // --> hexagon-v4/5/55/56-sim.xml
442 {36, 36, LLDB_INVALID_REGNUM
, 36, 36},
455 {37, 37, LLDB_INVALID_REGNUM
, 37, 37},
467 {38, 38, LLDB_INVALID_REGNUM
, 38, 38},
478 {39, 39, LLDB_INVALID_REGNUM
, 39, 39},
489 {40, 40, LLDB_INVALID_REGNUM
, 40, 40},
500 {41, 41, LLDB_REGNUM_GENERIC_PC
, 41, 41},
511 {42, 42, LLDB_INVALID_REGNUM
, 42, 42},
522 {43, 43, LLDB_INVALID_REGNUM
, 43, 43},
533 {44, 44, LLDB_INVALID_REGNUM
, 44, 44},
544 {45, 45, LLDB_INVALID_REGNUM
, 45, 45},
556 {46, 46, LLDB_INVALID_REGNUM
, 46, 46},
567 {47, 47, LLDB_INVALID_REGNUM
, 47, 47},
578 {48, 48, LLDB_INVALID_REGNUM
, 48, 48},
589 {49, 49, LLDB_INVALID_REGNUM
, 49, 49},
600 {50, 50, LLDB_INVALID_REGNUM
, 50, 50},
611 {51, 51, LLDB_INVALID_REGNUM
, 51, 51},
622 {52, 52, LLDB_INVALID_REGNUM
, 52, 52},
633 {53, 53, LLDB_INVALID_REGNUM
, 53, 53},
644 {54, 54, LLDB_INVALID_REGNUM
, 54, 54},
655 {55, 55, LLDB_INVALID_REGNUM
, 55, 55},
666 {56, 56, LLDB_INVALID_REGNUM
, 56, 56},
677 {57, 57, LLDB_INVALID_REGNUM
, 57, 57},
688 {58, 58, LLDB_INVALID_REGNUM
, 58, 58},
699 {59, 59, LLDB_INVALID_REGNUM
, 59, 59},
710 {60, 60, LLDB_INVALID_REGNUM
, 60, 60},
721 {61, 61, LLDB_INVALID_REGNUM
, 61, 61},
732 {62, 62, LLDB_INVALID_REGNUM
, 62, 62},
743 {63, 63, LLDB_INVALID_REGNUM
, 63, 63},
755 {64, 64, LLDB_INVALID_REGNUM
, 64, 64},
767 {65, 65, LLDB_INVALID_REGNUM
, 65, 65},
779 {66, 66, LLDB_INVALID_REGNUM
, 66, 66},
790 {67, 67, LLDB_INVALID_REGNUM
, 67, 67},
801 {68, 68, LLDB_INVALID_REGNUM
, 68, 68},
812 {69, 69, LLDB_INVALID_REGNUM
, 69, 69},
823 {70, 70, LLDB_INVALID_REGNUM
, 70, 70},
834 {71, 71, LLDB_INVALID_REGNUM
, 71, 71},
845 {72, 72, LLDB_INVALID_REGNUM
, 72, 72},
857 {73, 73, LLDB_INVALID_REGNUM
, 73, 73},
869 {74, 74, LLDB_INVALID_REGNUM
, 74, 74},
881 {75, 75, LLDB_INVALID_REGNUM
, 75, 75},
892 {76, 76, LLDB_INVALID_REGNUM
, 76, 76},
903 {77, 77, LLDB_INVALID_REGNUM
, 77, 77},
914 {78, 78, LLDB_INVALID_REGNUM
, 78, 78},
925 {79, 79, LLDB_INVALID_REGNUM
, 79, 79},
937 {80, 80, LLDB_INVALID_REGNUM
, 80, 80},
948 {81, 81, LLDB_INVALID_REGNUM
, 81, 81},
959 {82, 82, LLDB_INVALID_REGNUM
, 82, 82},
970 {83, 83, LLDB_INVALID_REGNUM
, 83, 83},
976 static const uint32_t k_num_register_infos
=
977 sizeof(g_register_infos
) / sizeof(RegisterInfo
);
979 const lldb_private::RegisterInfo
*
980 ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count
) {
981 count
= k_num_register_infos
;
982 return g_register_infos
;
986 http://en.wikipedia.org/wiki/Red_zone_%28computing%29
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
996 128 byte red zone though it is not documented.
998 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
1003 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp
, const ArchSpec
&arch
) {
1004 if (arch
.GetTriple().getArch() == llvm::Triple::hexagon
) {
1006 new ABISysV_hexagon(std::move(process_sp
), MakeMCRegisterInfo(arch
)));
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
1021 // . safeguard the current stack
1022 // . how can we know that the called function will create its own frame
1024 // . we could manually make a new stack first:
1028 // 5. SP = SP ( since no locals in our temp frame )
1031 // . variable argument list parameters are not passed via registers, they are
1033 // the stack. This presents us with a problem, since we need to know when
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
1038 // the time being, to progress, I will assume that it takes on real parameter
1040 // the vargs list starts.
1043 // . how do we adhere to the stack alignment requirements
1046 // . handle 64bit values and their register / stack requirements
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;
1057 // grab the process so we have access to the memory for spilling
1058 lldb::ProcessSP proc
= thread
.GetProcess();
1060 // get the register context for modifying all of the registers
1061 RegisterContext
*reg_ctx
= thread
.GetRegisterContext().get();
1065 uint32_t pc_reg
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1066 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_PC
);
1067 if (pc_reg
== LLDB_INVALID_REGNUM
)
1070 uint32_t ra_reg
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1071 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_RA
);
1072 if (ra_reg
== LLDB_INVALID_REGNUM
)
1075 uint32_t sp_reg
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1076 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_SP
);
1077 if (sp_reg
== LLDB_INVALID_REGNUM
)
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
)
1086 // round up to 8 byte multiple
1087 size_t argSize
= (arg
.size
| 0x7) + 1;
1089 // create space on the stack for this data
1092 // write this argument onto the stack of the host process
1093 proc
->WriteMemory(sp
, arg
.data_up
.get(), arg
.size
, error
);
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
;
1103 // print the original stack pointer
1104 printf("sp : %04" PRIx64
" \n", sp
);
1107 // make sure number of parameters matches prototype
1108 assert(prototype
.getFunctionNumParams() == args
.size());
1110 // check if this is a variable argument function
1111 bool isVArg
= prototype
.isFunctionVarArg();
1113 // number of arguments passed by register
1114 int nRegArgs
= nVArgRegParams
;
1116 // number of arguments is limited by [R0 : R5] space
1117 nRegArgs
= args
.size();
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
))
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
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())
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
);
1157 // quick and dirty stack dumper for debugging
1158 for (int i
= -8; i
< 8; i
++) {
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
);
1172 bool ABISysV_hexagon::GetArgumentValues(Thread
&thread
,
1173 ValueList
&values
) const {
1178 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP
&frame_sp
,
1179 lldb::ValueObjectSP
&new_value_sp
) {
1184 ValueObjectSP
ABISysV_hexagon::GetReturnValueObjectSimple(
1185 Thread
&thread
, CompilerType
&return_compiler_type
) const {
1186 ValueObjectSP return_valobj_sp
;
1187 return return_valobj_sp
;
1190 ValueObjectSP
ABISysV_hexagon::GetReturnValueObjectImpl(
1191 Thread
&thread
, CompilerType
&return_compiler_type
) const {
1192 ValueObjectSP return_valobj_sp
;
1193 return return_valobj_sp
;
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
);
1203 UnwindPlan::RowSP
row(new UnwindPlan::Row
);
1205 // Our Call Frame Address is the stack pointer value
1206 row
->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP
, 4);
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
);
1214 unwind_plan
.SetSourceName("hexagon at-func-entry default");
1215 unwind_plan
.SetSourcedFromCompiler(eLazyBoolNo
);
1219 bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan
&unwind_plan
) {
1220 unwind_plan
.Clear();
1221 unwind_plan
.SetRegisterKind(eRegisterKindGeneric
);
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
;
1227 UnwindPlan::RowSP
row(new UnwindPlan::Row
);
1229 row
->SetUnspecifiedRegistersAreUndefined(true);
1230 row
->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP
, 8);
1232 row
->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num
, -8, true);
1233 row
->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num
, -4, true);
1234 row
->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num
, 0, true);
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
);
1245 Register Usage Saved By
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
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()
1258 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo
*reg_info
) {
1259 return !RegisterIsCalleeSaved(reg_info
);
1262 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo
*reg_info
) {
1263 int reg
= ((reg_info
->byte_offset
) / 4);
1265 bool save
= (reg
>= 16) && (reg
<= 27);
1266 save
|= (reg
>= 29) && (reg
<= 32);
1271 void ABISysV_hexagon::Initialize() {
1272 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1273 "System V ABI for hexagon targets",
1277 void ABISysV_hexagon::Terminate() {
1278 PluginManager::UnregisterPlugin(CreateInstance
);
1281 // get value object specialized to work with llvm IR types
1283 ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread
&thread
,
1284 llvm::Type
&retType
) const {
1286 ValueObjectSP vObjSP
;
1288 // get the current register context
1289 RegisterContext
*reg_ctx
= thread
.GetRegisterContext().get();
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)
1300 if (retType
.isVoidTy()) {
1301 value
.GetScalar() = 0;
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
))
1310 // push r0 into value
1311 uint32_t r0_u32
= r0_value
.GetAsUInt32();
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
1321 value
.GetScalar() = r0_u32
;
1323 // unsupported return type
1327 // pack the value into a ValueObjectSP
1328 vObjSP
= ValueObjectConstResult::Create(thread
.GetStackFrameAtIndex(0).get(),
1329 value
, ConstString(""));