1 //===-- ABISysV_hexagon.cpp -------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "ABISysV_hexagon.h"
12 #include "llvm/ADT/Triple.h"
13 #include "llvm/IR/DerivedTypes.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/PluginManager.h"
17 #include "lldb/Core/Value.h"
18 #include "lldb/Core/ValueObjectConstResult.h"
19 #include "lldb/Core/ValueObjectMemory.h"
20 #include "lldb/Core/ValueObjectRegister.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "lldb/Target/StackFrame.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/ConstString.h"
28 #include "lldb/Utility/DataExtractor.h"
29 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/RegisterValue.h"
31 #include "lldb/Utility/Status.h"
34 using namespace lldb_private;
36 static RegisterInfo g_register_infos[] = {
44 {0, 0, LLDB_INVALID_REGNUM, 0, 0},
55 {1, 1, LLDB_INVALID_REGNUM, 1, 1},
66 {2, 2, LLDB_INVALID_REGNUM, 2, 2},
77 {3, 3, LLDB_INVALID_REGNUM, 3, 3},
88 {4, 4, LLDB_INVALID_REGNUM, 4, 4},
99 {5, 5, LLDB_INVALID_REGNUM, 5, 5},
110 {6, 6, LLDB_INVALID_REGNUM, 6, 6},
121 {7, 7, LLDB_INVALID_REGNUM, 7, 7},
132 {8, 8, LLDB_INVALID_REGNUM, 8, 8},
143 {9, 9, LLDB_INVALID_REGNUM, 9, 9},
154 {10, 10, LLDB_INVALID_REGNUM, 10, 10},
165 {11, 11, LLDB_INVALID_REGNUM, 11, 11},
176 {12, 12, LLDB_INVALID_REGNUM, 12, 12},
187 {13, 13, LLDB_INVALID_REGNUM, 13, 13},
198 {14, 14, LLDB_INVALID_REGNUM, 14, 14},
209 {15, 15, LLDB_INVALID_REGNUM, 15, 15},
220 {16, 16, LLDB_INVALID_REGNUM, 16, 16},
231 {17, 17, LLDB_INVALID_REGNUM, 17, 17},
242 {18, 18, LLDB_INVALID_REGNUM, 18, 18},
253 {19, 19, LLDB_INVALID_REGNUM, 19, 19},
264 {20, 20, LLDB_INVALID_REGNUM, 20, 20},
275 {21, 21, LLDB_INVALID_REGNUM, 21, 21},
286 {22, 22, LLDB_INVALID_REGNUM, 22, 22},
297 {23, 23, LLDB_INVALID_REGNUM, 23, 23},
308 {24, 24, LLDB_INVALID_REGNUM, 24, 24},
319 {25, 25, LLDB_INVALID_REGNUM, 25, 25},
330 {26, 26, LLDB_INVALID_REGNUM, 26, 26},
341 {27, 27, LLDB_INVALID_REGNUM, 27, 27},
352 {28, 28, LLDB_INVALID_REGNUM, 28, 28},
363 {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29},
374 {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30},
385 {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31},
396 {32, 32, LLDB_INVALID_REGNUM, 32, 32},
407 {33, 33, LLDB_INVALID_REGNUM, 33, 33},
418 {34, 34, LLDB_INVALID_REGNUM, 34, 34},
429 {35, 35, LLDB_INVALID_REGNUM, 35, 35},
434 // --> hexagon-v4/5/55/56-sim.xml
441 {36, 36, LLDB_INVALID_REGNUM, 36, 36},
453 {37, 37, LLDB_INVALID_REGNUM, 37, 37},
465 {38, 38, LLDB_INVALID_REGNUM, 38, 38},
476 {39, 39, LLDB_INVALID_REGNUM, 39, 39},
487 {40, 40, LLDB_INVALID_REGNUM, 40, 40},
498 {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41},
509 {42, 42, LLDB_INVALID_REGNUM, 42, 42},
520 {43, 43, LLDB_INVALID_REGNUM, 43, 43},
531 {44, 44, LLDB_INVALID_REGNUM, 44, 44},
542 {45, 45, LLDB_INVALID_REGNUM, 45, 45},
554 {46, 46, LLDB_INVALID_REGNUM, 46, 46},
565 {47, 47, LLDB_INVALID_REGNUM, 47, 47},
576 {48, 48, LLDB_INVALID_REGNUM, 48, 48},
587 {49, 49, LLDB_INVALID_REGNUM, 49, 49},
598 {50, 50, LLDB_INVALID_REGNUM, 50, 50},
609 {51, 51, LLDB_INVALID_REGNUM, 51, 51},
620 {52, 52, LLDB_INVALID_REGNUM, 52, 52},
631 {53, 53, LLDB_INVALID_REGNUM, 53, 53},
642 {54, 54, LLDB_INVALID_REGNUM, 54, 54},
653 {55, 55, LLDB_INVALID_REGNUM, 55, 55},
664 {56, 56, LLDB_INVALID_REGNUM, 56, 56},
675 {57, 57, LLDB_INVALID_REGNUM, 57, 57},
686 {58, 58, LLDB_INVALID_REGNUM, 58, 58},
697 {59, 59, LLDB_INVALID_REGNUM, 59, 59},
708 {60, 60, LLDB_INVALID_REGNUM, 60, 60},
719 {61, 61, LLDB_INVALID_REGNUM, 61, 61},
730 {62, 62, LLDB_INVALID_REGNUM, 62, 62},
741 {63, 63, LLDB_INVALID_REGNUM, 63, 63},
753 {64, 64, LLDB_INVALID_REGNUM, 64, 64},
765 {65, 65, LLDB_INVALID_REGNUM, 65, 65},
777 {66, 66, LLDB_INVALID_REGNUM, 66, 66},
788 {67, 67, LLDB_INVALID_REGNUM, 67, 67},
799 {68, 68, LLDB_INVALID_REGNUM, 68, 68},
810 {69, 69, LLDB_INVALID_REGNUM, 69, 69},
821 {70, 70, LLDB_INVALID_REGNUM, 70, 70},
832 {71, 71, LLDB_INVALID_REGNUM, 71, 71},
843 {72, 72, LLDB_INVALID_REGNUM, 72, 72},
855 {73, 73, LLDB_INVALID_REGNUM, 73, 73},
867 {74, 74, LLDB_INVALID_REGNUM, 74, 74},
879 {75, 75, LLDB_INVALID_REGNUM, 75, 75},
890 {76, 76, LLDB_INVALID_REGNUM, 76, 76},
901 {77, 77, LLDB_INVALID_REGNUM, 77, 77},
912 {78, 78, LLDB_INVALID_REGNUM, 78, 78},
923 {79, 79, LLDB_INVALID_REGNUM, 79, 79},
935 {80, 80, LLDB_INVALID_REGNUM, 80, 80},
946 {81, 81, LLDB_INVALID_REGNUM, 81, 81},
957 {82, 82, LLDB_INVALID_REGNUM, 82, 82},
968 {83, 83, LLDB_INVALID_REGNUM, 83, 83},
974 static const uint32_t k_num_register_infos =
975 sizeof(g_register_infos) / sizeof(RegisterInfo);
976 static bool g_register_info_names_constified = false;
978 const lldb_private::RegisterInfo *
979 ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) {
980 // Make the C-string names and alt_names for the register infos into const
981 // C-string values by having the ConstString unique the names in the global
982 // constant C-string pool.
983 if (!g_register_info_names_constified) {
984 g_register_info_names_constified = true;
985 for (uint32_t i = 0; i < k_num_register_infos; ++i) {
986 if (g_register_infos[i].name)
987 g_register_infos[i].name =
988 ConstString(g_register_infos[i].name).GetCString();
989 if (g_register_infos[i].alt_name)
990 g_register_infos[i].alt_name =
991 ConstString(g_register_infos[i].alt_name).GetCString();
994 count = k_num_register_infos;
995 return g_register_infos;
999 http://en.wikipedia.org/wiki/Red_zone_%28computing%29
1001 In computing, a red zone is a fixed size area in memory beyond the stack
1002 pointer that has not been
1003 "allocated". This region of memory is not to be modified by
1004 interrupt/exception/signal handlers.
1005 This allows the space to be used for temporary data without the extra
1006 overhead of modifying the
1007 stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC
1009 128 byte red zone though it is not documented.
1011 size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; }
1013 //------------------------------------------------------------------
1015 //------------------------------------------------------------------
1018 ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1019 if (arch.GetTriple().getArch() == llvm::Triple::hexagon) {
1020 return ABISP(new ABISysV_hexagon(process_sp));
1025 bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp,
1026 lldb::addr_t pc, lldb::addr_t ra,
1027 llvm::ArrayRef<addr_t> args) const {
1028 // we don't use the traditional trivial call specialized for jit
1035 // . safeguard the current stack
1036 // . how can we know that the called function will create its own frame
1038 // . we could manually make a new stack first:
1042 // 5. SP = SP ( since no locals in our temp frame )
1045 // . variable argument list parameters are not passed via registers, they are
1047 // the stack. This presents us with a problem, since we need to know when
1049 // starts. Currently I can find out if a function is varg, but not how many
1050 // real parameters it takes. Thus I don't know when to start spilling the
1052 // the time being, to progress, I will assume that it takes on real parameter
1054 // the vargs list starts.
1057 // . how do we adhere to the stack alignment requirements
1060 // . handle 64bit values and their register / stack requirements
1063 #define HEX_ABI_DEBUG 0
1064 bool ABISysV_hexagon::PrepareTrivialCall(
1065 Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra,
1066 llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const {
1067 // default number of register passed arguments for varg functions
1068 const int nVArgRegParams = 1;
1071 // grab the process so we have access to the memory for spilling
1072 lldb::ProcessSP proc = thread.GetProcess();
1074 // get the register context for modifying all of the registers
1075 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1079 uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1080 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1081 if (pc_reg == LLDB_INVALID_REGNUM)
1084 uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1085 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1086 if (ra_reg == LLDB_INVALID_REGNUM)
1089 uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber(
1090 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1091 if (sp_reg == LLDB_INVALID_REGNUM)
1094 // push host data onto target
1095 for (size_t i = 0; i < args.size(); i++) {
1096 const ABI::CallArgument &arg = args[i];
1097 // skip over target values
1098 if (arg.type == ABI::CallArgument::TargetValue)
1100 // round up to 8 byte multiple
1101 size_t argSize = (arg.size | 0x7) + 1;
1103 // create space on the stack for this data
1106 // write this argument onto the stack of the host process
1107 proc->WriteMemory(sp, arg.data_ap.get(), arg.size, error);
1111 // update the argument with the target pointer
1112 // XXX: This is a gross hack for getting around the const
1113 *const_cast<lldb::addr_t *>(&arg.value) = sp;
1117 // print the original stack pointer
1118 printf("sp : %04" PRIx64 " \n", sp);
1121 // make sure number of parameters matches prototype
1122 assert(prototype.getFunctionNumParams() == args.size());
1124 // check if this is a variable argument function
1125 bool isVArg = prototype.isFunctionVarArg();
1127 // number of arguments passed by register
1128 int nRegArgs = nVArgRegParams;
1130 // number of arguments is limited by [R0 : R5] space
1131 nRegArgs = args.size();
1136 // pass arguments that are passed via registers
1137 for (int i = 0; i < nRegArgs; i++) {
1138 // get the parameter as a u32
1139 uint32_t param = (uint32_t)args[i].value;
1140 // write argument into register
1141 if (!reg_ctx->WriteRegisterFromUnsigned(i, param))
1145 // number of arguments to spill onto stack
1146 int nSpillArgs = args.size() - nRegArgs;
1147 // make space on the stack for arguments
1148 sp -= 4 * nSpillArgs;
1149 // align stack on an 8 byte boundary
1153 // arguments that are passed on the stack
1154 for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) {
1155 // get the parameter as a u32
1156 uint32_t param = (uint32_t)args[i].value;
1157 // write argument to stack
1158 proc->WriteMemory(sp + offs, (void *)¶m, sizeof(param), error);
1159 if (!error.Success())
1165 // update registers with current function call state
1166 reg_ctx->WriteRegisterFromUnsigned(pc_reg, pc);
1167 reg_ctx->WriteRegisterFromUnsigned(ra_reg, ra);
1168 reg_ctx->WriteRegisterFromUnsigned(sp_reg, sp);
1171 // quick and dirty stack dumper for debugging
1172 for (int i = -8; i < 8; i++) {
1174 lldb::addr_t addr = sp + i * 4;
1175 proc->ReadMemory(addr, (void *)&data, sizeof(data), error);
1176 printf("\n0x%04" PRIx64 " 0x%08x ", addr, data);
1186 bool ABISysV_hexagon::GetArgumentValues(Thread &thread,
1187 ValueList &values) const {
1192 ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1193 lldb::ValueObjectSP &new_value_sp) {
1198 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple(
1199 Thread &thread, CompilerType &return_compiler_type) const {
1200 ValueObjectSP return_valobj_sp;
1201 return return_valobj_sp;
1204 ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl(
1205 Thread &thread, CompilerType &return_compiler_type) const {
1206 ValueObjectSP return_valobj_sp;
1207 return return_valobj_sp;
1210 // called when we are on the first instruction of a new function for hexagon
1211 // the return address is in RA (R31)
1212 bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1213 unwind_plan.Clear();
1214 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1215 unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA);
1217 UnwindPlan::RowSP row(new UnwindPlan::Row);
1219 // Our Call Frame Address is the stack pointer value
1220 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, 4);
1223 // The previous PC is in the LR
1224 row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC,
1225 LLDB_REGNUM_GENERIC_RA, true);
1226 unwind_plan.AppendRow(row);
1228 unwind_plan.SetSourceName("hexagon at-func-entry default");
1229 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1233 bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1234 unwind_plan.Clear();
1235 unwind_plan.SetRegisterKind(eRegisterKindGeneric);
1237 uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP;
1238 uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP;
1239 uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC;
1241 UnwindPlan::RowSP row(new UnwindPlan::Row);
1243 row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, 8);
1245 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, -8, true);
1246 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -4, true);
1247 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1249 unwind_plan.AppendRow(row);
1250 unwind_plan.SetSourceName("hexagon default unwind plan");
1251 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1252 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1257 Register Usage Saved By
1259 R0 - R5 parameters(a) -
1260 R6 - R15 Scratch(b) Caller
1261 R16 - R27 Scratch Callee
1262 R28 Scratch(b) Caller
1263 R29 - R31 Stack Frames Callee(c)
1264 P3:0 Processor State Caller
1266 a = the caller can change parameter values
1267 b = R14 - R15 and R28 are used by the procedure linkage table
1268 c = R29 - R31 are saved and restored by allocframe() and deallocframe()
1270 bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) {
1271 return !RegisterIsCalleeSaved(reg_info);
1274 bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1275 int reg = ((reg_info->byte_offset) / 4);
1277 bool save = (reg >= 16) && (reg <= 27);
1278 save |= (reg >= 29) && (reg <= 32);
1283 void ABISysV_hexagon::Initialize() {
1284 PluginManager::RegisterPlugin(GetPluginNameStatic(),
1285 "System V ABI for hexagon targets",
1289 void ABISysV_hexagon::Terminate() {
1290 PluginManager::UnregisterPlugin(CreateInstance);
1293 lldb_private::ConstString ABISysV_hexagon::GetPluginNameStatic() {
1294 static ConstString g_name("sysv-hexagon");
1298 //------------------------------------------------------------------
1299 // PluginInterface protocol
1300 //------------------------------------------------------------------
1302 lldb_private::ConstString ABISysV_hexagon::GetPluginName() {
1303 return GetPluginNameStatic();
1306 uint32_t ABISysV_hexagon::GetPluginVersion() { return 1; }
1308 // get value object specialized to work with llvm IR types
1310 ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread,
1311 llvm::Type &retType) const {
1313 ValueObjectSP vObjSP;
1315 // get the current register context
1316 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1320 // for now just pop R0 to find the return value
1321 const lldb_private::RegisterInfo *r0_info =
1322 reg_ctx->GetRegisterInfoAtIndex(0);
1323 if (r0_info == nullptr)
1327 if (retType.isVoidTy()) {
1328 value.GetScalar() = 0;
1330 // integer / pointer return type
1331 else if (retType.isIntegerTy() || retType.isPointerTy()) {
1332 // read r0 register value
1333 lldb_private::RegisterValue r0_value;
1334 if (!reg_ctx->ReadRegister(r0_info, r0_value))
1337 // push r0 into value
1338 uint32_t r0_u32 = r0_value.GetAsUInt32();
1340 // account for integer size
1341 if (retType.isIntegerTy() && retType.isSized()) {
1342 uint64_t size = retType.getScalarSizeInBits();
1343 uint64_t mask = (1ull << size) - 1;
1344 // mask out higher order bits then the type we expect
1348 value.GetScalar() = r0_u32;
1350 // unsupported return type
1354 // pack the value into a ValueObjectSP
1355 vObjSP = ValueObjectConstResult::Create(thread.GetStackFrameAtIndex(0).get(),
1356 value, ConstString(""));