1 //===-- ABISysV_arm.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_arm.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/Triple.h"
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Value.h"
19 #include "lldb/Core/ValueObjectConstResult.h"
20 #include "lldb/Symbol/UnwindPlan.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 #include "lldb/Utility/ConstString.h"
26 #include "lldb/Utility/RegisterValue.h"
27 #include "lldb/Utility/Scalar.h"
28 #include "lldb/Utility/Status.h"
30 #include "Plugins/Process/Utility/ARMDefines.h"
31 #include "Utility/ARM_DWARF_Registers.h"
32 #include "Utility/ARM_ehframe_Registers.h"
35 using namespace lldb_private;
37 LLDB_PLUGIN_DEFINE(ABISysV_arm)
39 static const RegisterInfo g_register_infos[] = {
40 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
41 // DWARF GENERIC PROCESS PLUGIN
42 // LLDB NATIVE VALUE REGS INVALIDATE REGS
43 // ========== ======= == === ============= ============
44 // ======================= =================== ===========================
45 // ======================= ====================== ==========
53 {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
65 {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
77 {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
89 {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
101 {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
102 LLDB_INVALID_REGNUM},
113 {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
114 LLDB_INVALID_REGNUM},
125 {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
126 LLDB_INVALID_REGNUM},
137 {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
138 LLDB_INVALID_REGNUM},
149 {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
150 LLDB_INVALID_REGNUM},
161 {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
162 LLDB_INVALID_REGNUM},
173 {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
174 LLDB_INVALID_REGNUM},
185 {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
186 LLDB_INVALID_REGNUM},
197 {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
198 LLDB_INVALID_REGNUM},
209 {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
210 LLDB_INVALID_REGNUM},
221 {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
222 LLDB_INVALID_REGNUM},
233 {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
234 LLDB_INVALID_REGNUM},
245 {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
246 LLDB_INVALID_REGNUM},
257 {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
258 LLDB_INVALID_REGNUM},
269 {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
270 LLDB_INVALID_REGNUM},
281 {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
282 LLDB_INVALID_REGNUM},
293 {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
294 LLDB_INVALID_REGNUM},
305 {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
306 LLDB_INVALID_REGNUM},
317 {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
318 LLDB_INVALID_REGNUM},
329 {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
330 LLDB_INVALID_REGNUM},
341 {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
342 LLDB_INVALID_REGNUM},
353 {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
354 LLDB_INVALID_REGNUM},
365 {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
366 LLDB_INVALID_REGNUM},
377 {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
378 LLDB_INVALID_REGNUM},
389 {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
390 LLDB_INVALID_REGNUM},
401 {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
402 LLDB_INVALID_REGNUM},
413 {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
414 LLDB_INVALID_REGNUM},
425 {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
426 LLDB_INVALID_REGNUM},
437 {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
438 LLDB_INVALID_REGNUM},
449 {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
450 LLDB_INVALID_REGNUM},
461 {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
462 LLDB_INVALID_REGNUM},
473 {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
474 LLDB_INVALID_REGNUM},
485 {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
486 LLDB_INVALID_REGNUM},
497 {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
498 LLDB_INVALID_REGNUM},
509 {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
510 LLDB_INVALID_REGNUM},
521 {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
522 LLDB_INVALID_REGNUM},
533 {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
534 LLDB_INVALID_REGNUM},
545 {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
546 LLDB_INVALID_REGNUM},
557 {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
558 LLDB_INVALID_REGNUM},
569 {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
570 LLDB_INVALID_REGNUM},
581 {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
582 LLDB_INVALID_REGNUM},
593 {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
594 LLDB_INVALID_REGNUM},
605 {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
606 LLDB_INVALID_REGNUM},
617 {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
618 LLDB_INVALID_REGNUM},
629 {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
630 LLDB_INVALID_REGNUM},
641 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
642 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
653 {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
654 LLDB_INVALID_REGNUM},
665 {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
666 LLDB_INVALID_REGNUM},
677 {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
678 LLDB_INVALID_REGNUM},
689 {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
690 LLDB_INVALID_REGNUM},
701 {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
702 LLDB_INVALID_REGNUM},
713 {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
714 LLDB_INVALID_REGNUM},
725 {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
726 LLDB_INVALID_REGNUM},
737 {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
738 LLDB_INVALID_REGNUM},
749 {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
750 LLDB_INVALID_REGNUM},
761 {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
762 LLDB_INVALID_REGNUM},
773 {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
774 LLDB_INVALID_REGNUM},
785 {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
786 LLDB_INVALID_REGNUM},
797 {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
798 LLDB_INVALID_REGNUM},
809 {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
810 LLDB_INVALID_REGNUM},
821 {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
822 LLDB_INVALID_REGNUM},
833 {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
834 LLDB_INVALID_REGNUM},
845 {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
846 LLDB_INVALID_REGNUM},
857 {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
858 LLDB_INVALID_REGNUM},
869 {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
870 LLDB_INVALID_REGNUM},
881 {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
882 LLDB_INVALID_REGNUM},
893 {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
894 LLDB_INVALID_REGNUM},
905 {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
906 LLDB_INVALID_REGNUM},
917 {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
918 LLDB_INVALID_REGNUM},
929 {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
930 LLDB_INVALID_REGNUM},
941 {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
942 LLDB_INVALID_REGNUM},
953 {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
954 LLDB_INVALID_REGNUM},
965 {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
966 LLDB_INVALID_REGNUM},
977 {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
978 LLDB_INVALID_REGNUM},
989 {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
990 LLDB_INVALID_REGNUM},
1001 {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1002 LLDB_INVALID_REGNUM},
1013 {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1014 LLDB_INVALID_REGNUM},
1025 {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1026 LLDB_INVALID_REGNUM},
1037 {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM,
1038 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1049 {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM,
1050 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1061 {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM,
1062 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1073 {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM,
1074 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1085 {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM,
1086 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1097 {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM,
1098 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1109 {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM,
1110 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1121 {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM,
1122 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1133 {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM,
1134 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1145 {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM,
1146 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1157 {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM,
1158 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1169 {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM,
1170 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1181 {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM,
1182 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1193 {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM,
1194 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1205 {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM,
1206 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1217 {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM,
1218 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1229 {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM,
1230 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1241 {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM,
1242 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1253 {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM,
1254 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1265 {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM,
1266 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1277 {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM,
1278 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1289 {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM,
1290 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1296 static const uint32_t k_num_register_infos =
1297 llvm::array_lengthof(g_register_infos);
1299 const lldb_private::RegisterInfo *
1300 ABISysV_arm::GetRegisterInfoArray(uint32_t &count) {
1301 count = k_num_register_infos;
1302 return g_register_infos;
1305 size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
1310 ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1311 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1312 const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1314 if (vendor_type != llvm::Triple::Apple) {
1315 if ((arch_type == llvm::Triple::arm) ||
1316 (arch_type == llvm::Triple::thumb)) {
1318 new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1325 bool ABISysV_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
1326 addr_t function_addr, addr_t return_addr,
1327 llvm::ArrayRef<addr_t> args) const {
1328 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1332 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1333 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1334 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1335 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1336 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1337 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1339 RegisterValue reg_value;
1341 const uint8_t reg_names[] = {
1342 LLDB_REGNUM_GENERIC_ARG1, LLDB_REGNUM_GENERIC_ARG2,
1343 LLDB_REGNUM_GENERIC_ARG3, LLDB_REGNUM_GENERIC_ARG4};
1345 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1347 for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) {
1351 reg_value.SetUInt32(*ai);
1352 if (!reg_ctx->WriteRegister(
1353 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]),
1361 // Spill onto the stack
1362 size_t num_stack_regs = ae - ai;
1364 sp -= (num_stack_regs * 4);
1365 // Keep the stack 8 byte aligned, not that we need to
1366 sp &= ~(8ull - 1ull);
1368 // just using arg1 to get the right size
1369 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1370 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1372 addr_t arg_pos = sp;
1374 for (; ai != ae; ++ai) {
1375 reg_value.SetUInt32(*ai);
1377 ->WriteRegisterValueToMemory(reg_info, arg_pos,
1378 reg_info->byte_size, reg_value)
1381 arg_pos += reg_info->byte_size;
1385 TargetSP target_sp(thread.CalculateTarget());
1388 // Figure out if our return address is ARM or Thumb by using the
1389 // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1390 // thumb-ness and set the correct address bits for us.
1391 so_addr.SetLoadAddress(return_addr, target_sp.get());
1392 return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1394 // Set "lr" to the return address
1395 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
1398 // Set "sp" to the requested value
1399 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1402 // If bit zero or 1 is set, this must be a thumb function, no need to figure
1403 // this out from the symbols.
1404 so_addr.SetLoadAddress(function_addr, target_sp.get());
1405 function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1407 const RegisterInfo *cpsr_reg_info =
1408 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
1409 const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
1411 // Make a new CPSR and mask out any Thumb IT (if/then) bits
1412 uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1413 // If bit zero or 1 is set, this must be thumb...
1414 if (function_addr & 1ull)
1415 new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1417 new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1419 if (new_cpsr != curr_cpsr) {
1420 if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1425 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1427 // Set "pc" to the address requested
1428 return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr);
1431 bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
1432 uint32_t num_values = values.GetSize();
1434 ExecutionContext exe_ctx(thread.shared_from_this());
1435 // For now, assume that the types in the AST values come from the Target's
1438 // Extract the register context so we can read arguments from registers
1440 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1447 for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1448 // We currently only support extracting values with Clang QualTypes. Do we
1449 // care about others?
1450 Value *value = values.GetValueAtIndex(value_idx);
1455 CompilerType compiler_type = value->GetCompilerType();
1456 if (compiler_type) {
1457 bool is_signed = false;
1458 size_t bit_width = 0;
1459 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1460 compiler_type.IsPointerOrReferenceType()) {
1461 if (llvm::Optional<uint64_t> size = compiler_type.GetBitSize(&thread))
1464 // We only handle integer, pointer and reference types currently...
1468 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1469 if (value_idx < 4) {
1470 // Arguments 1-4 are in r0-r3...
1471 const RegisterInfo *arg_reg_info = nullptr;
1472 arg_reg_info = reg_ctx->GetRegisterInfo(
1473 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
1475 RegisterValue reg_value;
1477 if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1479 reg_value.SignExtend(bit_width);
1480 if (!reg_value.GetScalarValue(value->GetScalar()))
1488 // Read the stack pointer if it already hasn't been read
1489 sp = reg_ctx->GetSP(0);
1494 // Arguments 5 on up are on the stack
1495 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1497 if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
1498 sp, arg_byte_size, is_signed, value->GetScalar(), error))
1501 sp += arg_byte_size;
1509 static bool GetReturnValuePassedInMemory(Thread &thread,
1510 RegisterContext *reg_ctx,
1511 size_t byte_size, Value &value) {
1513 DataBufferHeap buffer(byte_size, 0);
1515 const RegisterInfo *r0_reg_info =
1516 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1518 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1519 thread.GetProcess()->ReadMemory(address, buffer.GetBytes(),
1520 buffer.GetByteSize(), error);
1525 value.SetBytes(buffer.GetBytes(), buffer.GetByteSize());
1529 bool ABISysV_arm::IsArmHardFloat(Thread &thread) const {
1530 ProcessSP process_sp(thread.GetProcess());
1532 const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1534 return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
1540 ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
1541 Thread &thread, lldb_private::CompilerType &compiler_type) const {
1543 ValueObjectSP return_valobj_sp;
1546 return return_valobj_sp;
1548 // value.SetContext (Value::eContextTypeClangType,
1549 // compiler_type.GetOpaqueQualType());
1550 value.SetCompilerType(compiler_type);
1552 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1554 return return_valobj_sp;
1558 uint32_t float_count;
1559 bool is_vfp_candidate = false;
1560 uint8_t vfp_count = 0;
1561 uint8_t vfp_byte_size = 0;
1563 // Get the pointer to the first stack argument so we have a place to start
1564 // when reading data
1566 const RegisterInfo *r0_reg_info =
1567 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1568 llvm::Optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
1569 llvm::Optional<uint64_t> byte_size = compiler_type.GetByteSize(&thread);
1570 if (!bit_width || !byte_size)
1571 return return_valobj_sp;
1573 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1574 switch (*bit_width) {
1576 return return_valobj_sp;
1578 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1579 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1581 raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1582 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1586 value.GetScalar() = (int64_t)raw_value;
1588 value.GetScalar() = (uint64_t)raw_value;
1592 value.GetScalar() = (int32_t)(
1593 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1595 value.GetScalar() = (uint32_t)(
1596 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1600 value.GetScalar() = (int16_t)(
1601 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1603 value.GetScalar() = (uint16_t)(
1604 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1608 value.GetScalar() = (int8_t)(
1609 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1611 value.GetScalar() = (uint8_t)(
1612 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1615 } else if (compiler_type.IsPointerType()) {
1617 thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1619 value.GetScalar() = ptr;
1620 } else if (compiler_type.IsVectorType()) {
1621 if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
1622 is_vfp_candidate = true;
1624 vfp_count = (*byte_size == 8 ? 1 : 2);
1625 } else if (*byte_size <= 16) {
1626 DataBufferHeap buffer(16, 0);
1627 uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes();
1629 for (uint32_t i = 0; 4 * i < *byte_size; ++i) {
1630 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1631 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
1633 reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX;
1635 value.SetBytes(buffer.GetBytes(), *byte_size);
1637 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1638 return return_valobj_sp;
1640 } else if (compiler_type.IsFloatingPointType(float_count, is_complex)) {
1641 if (float_count == 1 && !is_complex) {
1642 switch (*bit_width) {
1644 return return_valobj_sp;
1646 static_assert(sizeof(double) == sizeof(uint64_t), "");
1648 if (IsArmHardFloat(thread)) {
1649 RegisterValue reg_value;
1650 const RegisterInfo *d0_reg_info =
1651 reg_ctx->GetRegisterInfoByName("d0", 0);
1652 reg_ctx->ReadRegister(d0_reg_info, reg_value);
1653 value.GetScalar() = reg_value.GetAsDouble();
1656 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1657 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1659 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1661 ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1664 value.GetScalar() = *reinterpret_cast<double *>(&raw_value);
1668 case 16: // Half precision returned after a conversion to single precision
1670 static_assert(sizeof(float) == sizeof(uint32_t), "");
1672 if (IsArmHardFloat(thread)) {
1673 RegisterValue reg_value;
1674 const RegisterInfo *s0_reg_info =
1675 reg_ctx->GetRegisterInfoByName("s0", 0);
1676 reg_ctx->ReadRegister(s0_reg_info, reg_value);
1677 value.GetScalar() = reg_value.GetAsFloat();
1681 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1682 value.GetScalar() = *reinterpret_cast<float *>(&raw_value);
1687 } else if (is_complex && float_count == 2) {
1688 if (IsArmHardFloat(thread)) {
1689 is_vfp_candidate = true;
1690 vfp_byte_size = *byte_size / 2;
1692 } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8,
1694 return return_valobj_sp;
1697 return return_valobj_sp;
1698 } else if (compiler_type.IsAggregateType()) {
1699 if (IsArmHardFloat(thread)) {
1700 CompilerType base_type;
1701 const uint32_t homogeneous_count =
1702 compiler_type.IsHomogeneousAggregate(&base_type);
1704 if (homogeneous_count > 0 && homogeneous_count <= 4) {
1705 llvm::Optional<uint64_t> base_byte_size =
1706 base_type.GetByteSize(&thread);
1707 if (base_type.IsVectorType()) {
1708 if (base_byte_size &&
1709 (*base_byte_size == 8 || *base_byte_size == 16)) {
1710 is_vfp_candidate = true;
1712 vfp_count = (*base_byte_size == 8 ? homogeneous_count
1713 : homogeneous_count * 2);
1715 } else if (base_type.IsFloatingPointType(float_count, is_complex)) {
1716 if (float_count == 1 && !is_complex) {
1717 is_vfp_candidate = true;
1719 vfp_byte_size = *base_byte_size;
1720 vfp_count = homogeneous_count;
1723 } else if (homogeneous_count == 0) {
1724 const uint32_t num_children = compiler_type.GetNumFields();
1726 if (num_children > 0 && num_children <= 2) {
1728 for (index = 0; index < num_children; index++) {
1730 base_type = compiler_type.GetFieldAtIndex(index, name, nullptr,
1733 if (base_type.IsFloatingPointType(float_count, is_complex)) {
1734 llvm::Optional<uint64_t> base_byte_size =
1735 base_type.GetByteSize(&thread);
1736 if (float_count == 2 && is_complex) {
1737 if (index != 0 && base_byte_size &&
1738 vfp_byte_size != *base_byte_size)
1740 else if (base_byte_size)
1741 vfp_byte_size = *base_byte_size;
1748 if (index == num_children) {
1749 is_vfp_candidate = true;
1750 vfp_byte_size = (vfp_byte_size >> 1);
1751 vfp_count = (num_children << 1);
1757 if (*byte_size <= 4) {
1758 RegisterValue r0_reg_value;
1759 uint32_t raw_value =
1760 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1761 value.SetBytes(&raw_value, *byte_size);
1762 } else if (!is_vfp_candidate) {
1763 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1764 return return_valobj_sp;
1768 return return_valobj_sp;
1771 if (is_vfp_candidate) {
1772 ProcessSP process_sp(thread.GetProcess());
1773 ByteOrder byte_order = process_sp->GetByteOrder();
1775 DataBufferSP data_sp(new DataBufferHeap(*byte_size, 0));
1776 uint32_t data_offset = 0;
1778 for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) {
1779 uint32_t regnum = 0;
1781 if (vfp_byte_size == 4)
1782 regnum = dwarf_s0 + reg_index;
1783 else if (vfp_byte_size == 8)
1784 regnum = dwarf_d0 + reg_index;
1788 const RegisterInfo *reg_info =
1789 reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum);
1790 if (reg_info == nullptr)
1793 RegisterValue reg_value;
1794 if (!reg_ctx->ReadRegister(reg_info, reg_value))
1797 // Make sure we have enough room in "data_sp"
1798 if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) {
1800 const size_t bytes_copied = reg_value.GetAsMemoryData(
1801 reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size,
1803 if (bytes_copied != vfp_byte_size)
1806 data_offset += bytes_copied;
1810 if (data_offset == *byte_size) {
1812 data.SetByteOrder(byte_order);
1813 data.SetAddressByteSize(process_sp->GetAddressByteSize());
1814 data.SetData(data_sp);
1816 return ValueObjectConstResult::Create(&thread, compiler_type,
1817 ConstString(""), data);
1818 } else { // Some error occurred while getting values from registers
1819 return return_valobj_sp;
1823 // If we get here, we have a valid Value, so make our ValueObject out of it:
1825 return_valobj_sp = ValueObjectConstResult::Create(
1826 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1827 return return_valobj_sp;
1830 Status ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1831 lldb::ValueObjectSP &new_value_sp) {
1833 if (!new_value_sp) {
1834 error.SetErrorString("Empty value object for return value.");
1838 CompilerType compiler_type = new_value_sp->GetCompilerType();
1839 if (!compiler_type) {
1840 error.SetErrorString("Null clang type for return value.");
1844 Thread *thread = frame_sp->GetThread().get();
1850 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1852 bool set_it_simple = false;
1853 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1854 compiler_type.IsPointerType()) {
1857 size_t num_bytes = new_value_sp->GetData(data, data_error);
1858 if (data_error.Fail()) {
1859 error.SetErrorStringWithFormat(
1860 "Couldn't convert return value to raw data: %s",
1861 data_error.AsCString());
1864 lldb::offset_t offset = 0;
1865 if (num_bytes <= 8) {
1866 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo(
1867 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1868 if (num_bytes <= 4) {
1869 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1871 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1872 set_it_simple = true;
1874 uint32_t raw_value = data.GetMaxU32(&offset, 4);
1876 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1877 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo(
1878 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1879 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1881 if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1882 set_it_simple = true;
1886 error.SetErrorString("We don't support returning longer than 64 bit "
1887 "integer values at present.");
1889 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1891 error.SetErrorString(
1892 "We don't support returning complex values at present");
1894 error.SetErrorString(
1895 "We don't support returning float values at present");
1899 error.SetErrorString(
1900 "We only support setting simple integer return types at present.");
1905 bool ABISysV_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1906 unwind_plan.Clear();
1907 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1909 uint32_t lr_reg_num = dwarf_lr;
1910 uint32_t sp_reg_num = dwarf_sp;
1911 uint32_t pc_reg_num = dwarf_pc;
1913 UnwindPlan::RowSP row(new UnwindPlan::Row);
1915 // Our Call Frame Address is the stack pointer value
1916 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1918 // The previous PC is in the LR
1919 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1920 unwind_plan.AppendRow(row);
1922 // All other registers are the same.
1924 unwind_plan.SetSourceName("arm at-func-entry default");
1925 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1930 bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1931 unwind_plan.Clear();
1932 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1934 // TODO: Handle thumb
1935 uint32_t fp_reg_num = dwarf_r11;
1936 uint32_t pc_reg_num = dwarf_pc;
1938 UnwindPlan::RowSP row(new UnwindPlan::Row);
1939 const int32_t ptr_size = 4;
1941 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1943 row->SetUnspecifiedRegistersAreUndefined(true);
1945 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1946 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1948 unwind_plan.AppendRow(row);
1949 unwind_plan.SetSourceName("arm default unwind plan");
1950 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1951 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1952 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1957 // cf. "ARMv6 Function Calling Conventions"
1959 // ARMv7 on GNU/Linux general purpose reg rules:
1960 // r0-r3 not preserved (used for argument passing)
1961 // r4-r11 preserved (v1-v8)
1963 // r13 preserved (stack pointer)
1964 // r14 preserved (link register)
1965 // r15 preserved (pc)
1966 // cpsr not preserved (different rules for different bits)
1968 // ARMv7 VFP register rules:
1969 // d0-d7 not preserved (aka s0-s15, q0-q3)
1970 // d8-d15 preserved (aka s16-s31, q4-q7)
1971 // d16-d31 not preserved (aka q8-q15)
1973 bool ABISysV_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
1975 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1976 const char *name = reg_info->name;
1977 if (name[0] == 'r') {
1980 return name[2] == '\0'; // r0
1986 return name[3] == '\0'; // r12
1993 return name[2] == '\0'; // r2
1995 return name[2] == '\0'; // r3
1999 } else if (name[0] == 'd') {
2002 return name[2] == '\0'; // d0 is volatile
2007 return true; // d1 is volatile
2012 return name[3] == '\0'; // d16 - d19 are volatile
2021 return true; // d2 is volatile
2032 return name[3] == '\0'; // d20 - d29 are volatile
2041 return true; // d3 is volatile
2044 return name[3] == '\0'; // d30 - d31 are volatile
2053 return name[2] == '\0'; // d4 - d7 are volatile
2058 } else if (name[0] == 's') {
2061 return name[2] == '\0'; // s0 is volatile
2066 return true; // s1 is volatile
2073 return name[3] == '\0'; // s10 - s15 are volatile
2087 return name[2] == '\0'; // s2 - s9 are volatile
2092 } else if (name[0] == 'q') {
2097 return true; // q1 is volatile
2104 return true; // q10-q15 are volatile
2113 return name[2] == '\0'; // q0-q3 are volatile
2116 return name[2] == '\0'; // q8-q9 are volatile
2120 } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2126 void ABISysV_arm::Initialize() {
2127 PluginManager::RegisterPlugin(GetPluginNameStatic(),
2128 "SysV ABI for arm targets", CreateInstance);
2131 void ABISysV_arm::Terminate() {
2132 PluginManager::UnregisterPlugin(CreateInstance);
2135 lldb_private::ConstString ABISysV_arm::GetPluginNameStatic() {
2136 static ConstString g_name("SysV-arm");
2140 // PluginInterface protocol
2142 lldb_private::ConstString ABISysV_arm::GetPluginName() {
2143 return GetPluginNameStatic();
2146 uint32_t ABISysV_arm::GetPluginVersion() { return 1; }