1 //===-- ABIMacOSX_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 "ABIMacOSX_arm.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/TargetParser/Triple.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/PluginManager.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObjectConstResult.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
26 #include "lldb/Utility/ConstString.h"
27 #include "lldb/Utility/RegisterValue.h"
28 #include "lldb/Utility/Scalar.h"
29 #include "lldb/Utility/Status.h"
31 #include "Plugins/Process/Utility/ARMDefines.h"
32 #include "Utility/ARM_DWARF_Registers.h"
33 #include "Utility/ARM_ehframe_Registers.h"
36 using namespace lldb_private
;
38 static const RegisterInfo g_register_infos
[] = {
39 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
40 // DWARF GENERIC PROCESS PLUGIN
42 // ========== ======= == === ============= ============
43 // ======================= =================== ===========================
44 // ======================= ======================
51 {ehframe_r0
, dwarf_r0
, LLDB_REGNUM_GENERIC_ARG1
, LLDB_INVALID_REGNUM
,
63 {ehframe_r1
, dwarf_r1
, LLDB_REGNUM_GENERIC_ARG2
, LLDB_INVALID_REGNUM
,
75 {ehframe_r2
, dwarf_r2
, LLDB_REGNUM_GENERIC_ARG3
, LLDB_INVALID_REGNUM
,
87 {ehframe_r3
, dwarf_r3
, LLDB_REGNUM_GENERIC_ARG4
, LLDB_INVALID_REGNUM
,
99 {ehframe_r4
, dwarf_r4
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
100 LLDB_INVALID_REGNUM
},
111 {ehframe_r5
, dwarf_r5
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
112 LLDB_INVALID_REGNUM
},
123 {ehframe_r6
, dwarf_r6
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
124 LLDB_INVALID_REGNUM
},
135 {ehframe_r7
, dwarf_r7
, LLDB_REGNUM_GENERIC_FP
, LLDB_INVALID_REGNUM
,
136 LLDB_INVALID_REGNUM
},
147 {ehframe_r8
, dwarf_r8
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
148 LLDB_INVALID_REGNUM
},
159 {ehframe_r9
, dwarf_r9
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
160 LLDB_INVALID_REGNUM
},
171 {ehframe_r10
, dwarf_r10
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
172 LLDB_INVALID_REGNUM
},
183 {ehframe_r11
, dwarf_r11
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
184 LLDB_INVALID_REGNUM
},
195 {ehframe_r12
, dwarf_r12
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
196 LLDB_INVALID_REGNUM
},
207 {ehframe_sp
, dwarf_sp
, LLDB_REGNUM_GENERIC_SP
, LLDB_INVALID_REGNUM
,
208 LLDB_INVALID_REGNUM
},
219 {ehframe_lr
, dwarf_lr
, LLDB_REGNUM_GENERIC_RA
, LLDB_INVALID_REGNUM
,
220 LLDB_INVALID_REGNUM
},
231 {ehframe_pc
, dwarf_pc
, LLDB_REGNUM_GENERIC_PC
, LLDB_INVALID_REGNUM
,
232 LLDB_INVALID_REGNUM
},
243 {ehframe_cpsr
, dwarf_cpsr
, LLDB_REGNUM_GENERIC_FLAGS
, LLDB_INVALID_REGNUM
,
244 LLDB_INVALID_REGNUM
},
255 {LLDB_INVALID_REGNUM
, dwarf_s0
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
256 LLDB_INVALID_REGNUM
},
267 {LLDB_INVALID_REGNUM
, dwarf_s1
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
268 LLDB_INVALID_REGNUM
},
279 {LLDB_INVALID_REGNUM
, dwarf_s2
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
280 LLDB_INVALID_REGNUM
},
291 {LLDB_INVALID_REGNUM
, dwarf_s3
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
292 LLDB_INVALID_REGNUM
},
303 {LLDB_INVALID_REGNUM
, dwarf_s4
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
304 LLDB_INVALID_REGNUM
},
315 {LLDB_INVALID_REGNUM
, dwarf_s5
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
316 LLDB_INVALID_REGNUM
},
327 {LLDB_INVALID_REGNUM
, dwarf_s6
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
328 LLDB_INVALID_REGNUM
},
339 {LLDB_INVALID_REGNUM
, dwarf_s7
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
340 LLDB_INVALID_REGNUM
},
351 {LLDB_INVALID_REGNUM
, dwarf_s8
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
352 LLDB_INVALID_REGNUM
},
363 {LLDB_INVALID_REGNUM
, dwarf_s9
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
364 LLDB_INVALID_REGNUM
},
375 {LLDB_INVALID_REGNUM
, dwarf_s10
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
376 LLDB_INVALID_REGNUM
},
387 {LLDB_INVALID_REGNUM
, dwarf_s11
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
388 LLDB_INVALID_REGNUM
},
399 {LLDB_INVALID_REGNUM
, dwarf_s12
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
400 LLDB_INVALID_REGNUM
},
411 {LLDB_INVALID_REGNUM
, dwarf_s13
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
412 LLDB_INVALID_REGNUM
},
423 {LLDB_INVALID_REGNUM
, dwarf_s14
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
424 LLDB_INVALID_REGNUM
},
435 {LLDB_INVALID_REGNUM
, dwarf_s15
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
436 LLDB_INVALID_REGNUM
},
447 {LLDB_INVALID_REGNUM
, dwarf_s16
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
448 LLDB_INVALID_REGNUM
},
459 {LLDB_INVALID_REGNUM
, dwarf_s17
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
460 LLDB_INVALID_REGNUM
},
471 {LLDB_INVALID_REGNUM
, dwarf_s18
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
472 LLDB_INVALID_REGNUM
},
483 {LLDB_INVALID_REGNUM
, dwarf_s19
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
484 LLDB_INVALID_REGNUM
},
495 {LLDB_INVALID_REGNUM
, dwarf_s20
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
496 LLDB_INVALID_REGNUM
},
507 {LLDB_INVALID_REGNUM
, dwarf_s21
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
508 LLDB_INVALID_REGNUM
},
519 {LLDB_INVALID_REGNUM
, dwarf_s22
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
520 LLDB_INVALID_REGNUM
},
531 {LLDB_INVALID_REGNUM
, dwarf_s23
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
532 LLDB_INVALID_REGNUM
},
543 {LLDB_INVALID_REGNUM
, dwarf_s24
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
544 LLDB_INVALID_REGNUM
},
555 {LLDB_INVALID_REGNUM
, dwarf_s25
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
556 LLDB_INVALID_REGNUM
},
567 {LLDB_INVALID_REGNUM
, dwarf_s26
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
568 LLDB_INVALID_REGNUM
},
579 {LLDB_INVALID_REGNUM
, dwarf_s27
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
580 LLDB_INVALID_REGNUM
},
591 {LLDB_INVALID_REGNUM
, dwarf_s28
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
592 LLDB_INVALID_REGNUM
},
603 {LLDB_INVALID_REGNUM
, dwarf_s29
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
604 LLDB_INVALID_REGNUM
},
615 {LLDB_INVALID_REGNUM
, dwarf_s30
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
616 LLDB_INVALID_REGNUM
},
627 {LLDB_INVALID_REGNUM
, dwarf_s31
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
628 LLDB_INVALID_REGNUM
},
639 {LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
640 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
651 {LLDB_INVALID_REGNUM
, dwarf_d0
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
652 LLDB_INVALID_REGNUM
},
663 {LLDB_INVALID_REGNUM
, dwarf_d1
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
664 LLDB_INVALID_REGNUM
},
675 {LLDB_INVALID_REGNUM
, dwarf_d2
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
676 LLDB_INVALID_REGNUM
},
687 {LLDB_INVALID_REGNUM
, dwarf_d3
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
688 LLDB_INVALID_REGNUM
},
699 {LLDB_INVALID_REGNUM
, dwarf_d4
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
700 LLDB_INVALID_REGNUM
},
711 {LLDB_INVALID_REGNUM
, dwarf_d5
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
712 LLDB_INVALID_REGNUM
},
723 {LLDB_INVALID_REGNUM
, dwarf_d6
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
724 LLDB_INVALID_REGNUM
},
735 {LLDB_INVALID_REGNUM
, dwarf_d7
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
736 LLDB_INVALID_REGNUM
},
747 {LLDB_INVALID_REGNUM
, dwarf_d8
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
748 LLDB_INVALID_REGNUM
},
759 {LLDB_INVALID_REGNUM
, dwarf_d9
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
760 LLDB_INVALID_REGNUM
},
771 {LLDB_INVALID_REGNUM
, dwarf_d10
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
772 LLDB_INVALID_REGNUM
},
783 {LLDB_INVALID_REGNUM
, dwarf_d11
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
784 LLDB_INVALID_REGNUM
},
795 {LLDB_INVALID_REGNUM
, dwarf_d12
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
796 LLDB_INVALID_REGNUM
},
807 {LLDB_INVALID_REGNUM
, dwarf_d13
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
808 LLDB_INVALID_REGNUM
},
819 {LLDB_INVALID_REGNUM
, dwarf_d14
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
820 LLDB_INVALID_REGNUM
},
831 {LLDB_INVALID_REGNUM
, dwarf_d15
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
832 LLDB_INVALID_REGNUM
},
843 {LLDB_INVALID_REGNUM
, dwarf_d16
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
844 LLDB_INVALID_REGNUM
},
855 {LLDB_INVALID_REGNUM
, dwarf_d17
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
856 LLDB_INVALID_REGNUM
},
867 {LLDB_INVALID_REGNUM
, dwarf_d18
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
868 LLDB_INVALID_REGNUM
},
879 {LLDB_INVALID_REGNUM
, dwarf_d19
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
880 LLDB_INVALID_REGNUM
},
891 {LLDB_INVALID_REGNUM
, dwarf_d20
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
892 LLDB_INVALID_REGNUM
},
903 {LLDB_INVALID_REGNUM
, dwarf_d21
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
904 LLDB_INVALID_REGNUM
},
915 {LLDB_INVALID_REGNUM
, dwarf_d22
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
916 LLDB_INVALID_REGNUM
},
927 {LLDB_INVALID_REGNUM
, dwarf_d23
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
928 LLDB_INVALID_REGNUM
},
939 {LLDB_INVALID_REGNUM
, dwarf_d24
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
940 LLDB_INVALID_REGNUM
},
951 {LLDB_INVALID_REGNUM
, dwarf_d25
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
952 LLDB_INVALID_REGNUM
},
963 {LLDB_INVALID_REGNUM
, dwarf_d26
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
964 LLDB_INVALID_REGNUM
},
975 {LLDB_INVALID_REGNUM
, dwarf_d27
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
976 LLDB_INVALID_REGNUM
},
987 {LLDB_INVALID_REGNUM
, dwarf_d28
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
988 LLDB_INVALID_REGNUM
},
999 {LLDB_INVALID_REGNUM
, dwarf_d29
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
1000 LLDB_INVALID_REGNUM
},
1011 {LLDB_INVALID_REGNUM
, dwarf_d30
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
1012 LLDB_INVALID_REGNUM
},
1023 {LLDB_INVALID_REGNUM
, dwarf_d31
, LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
,
1024 LLDB_INVALID_REGNUM
},
1035 {LLDB_INVALID_REGNUM
, dwarf_r8_usr
, LLDB_INVALID_REGNUM
,
1036 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1047 {LLDB_INVALID_REGNUM
, dwarf_r9_usr
, LLDB_INVALID_REGNUM
,
1048 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1059 {LLDB_INVALID_REGNUM
, dwarf_r10_usr
, LLDB_INVALID_REGNUM
,
1060 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1071 {LLDB_INVALID_REGNUM
, dwarf_r11_usr
, LLDB_INVALID_REGNUM
,
1072 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1083 {LLDB_INVALID_REGNUM
, dwarf_r12_usr
, LLDB_INVALID_REGNUM
,
1084 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1095 {LLDB_INVALID_REGNUM
, dwarf_r13_usr
, LLDB_INVALID_REGNUM
,
1096 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1107 {LLDB_INVALID_REGNUM
, dwarf_r14_usr
, LLDB_INVALID_REGNUM
,
1108 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1119 {LLDB_INVALID_REGNUM
, dwarf_r8_fiq
, LLDB_INVALID_REGNUM
,
1120 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1131 {LLDB_INVALID_REGNUM
, dwarf_r9_fiq
, LLDB_INVALID_REGNUM
,
1132 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1143 {LLDB_INVALID_REGNUM
, dwarf_r10_fiq
, LLDB_INVALID_REGNUM
,
1144 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1155 {LLDB_INVALID_REGNUM
, dwarf_r11_fiq
, LLDB_INVALID_REGNUM
,
1156 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1167 {LLDB_INVALID_REGNUM
, dwarf_r12_fiq
, LLDB_INVALID_REGNUM
,
1168 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1179 {LLDB_INVALID_REGNUM
, dwarf_r13_fiq
, LLDB_INVALID_REGNUM
,
1180 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1191 {LLDB_INVALID_REGNUM
, dwarf_r14_fiq
, LLDB_INVALID_REGNUM
,
1192 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1203 {LLDB_INVALID_REGNUM
, dwarf_r13_irq
, LLDB_INVALID_REGNUM
,
1204 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1215 {LLDB_INVALID_REGNUM
, dwarf_r14_irq
, LLDB_INVALID_REGNUM
,
1216 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1227 {LLDB_INVALID_REGNUM
, dwarf_r13_abt
, LLDB_INVALID_REGNUM
,
1228 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1239 {LLDB_INVALID_REGNUM
, dwarf_r14_abt
, LLDB_INVALID_REGNUM
,
1240 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1251 {LLDB_INVALID_REGNUM
, dwarf_r13_und
, LLDB_INVALID_REGNUM
,
1252 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1263 {LLDB_INVALID_REGNUM
, dwarf_r14_und
, LLDB_INVALID_REGNUM
,
1264 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1275 {LLDB_INVALID_REGNUM
, dwarf_r13_svc
, LLDB_INVALID_REGNUM
,
1276 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1287 {LLDB_INVALID_REGNUM
, dwarf_r14_svc
, LLDB_INVALID_REGNUM
,
1288 LLDB_INVALID_REGNUM
, LLDB_INVALID_REGNUM
},
1294 static const uint32_t k_num_register_infos
= std::size(g_register_infos
);
1296 const lldb_private::RegisterInfo
*
1297 ABIMacOSX_arm::GetRegisterInfoArray(uint32_t &count
) {
1298 count
= k_num_register_infos
;
1299 return g_register_infos
;
1302 size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; }
1307 ABIMacOSX_arm::CreateInstance(ProcessSP process_sp
, const ArchSpec
&arch
) {
1308 const llvm::Triple::ArchType arch_type
= arch
.GetTriple().getArch();
1309 const llvm::Triple::VendorType vendor_type
= arch
.GetTriple().getVendor();
1311 if (vendor_type
== llvm::Triple::Apple
) {
1312 if ((arch_type
== llvm::Triple::arm
) ||
1313 (arch_type
== llvm::Triple::thumb
)) {
1315 new ABIMacOSX_arm(std::move(process_sp
), MakeMCRegisterInfo(arch
)));
1322 bool ABIMacOSX_arm::PrepareTrivialCall(Thread
&thread
, addr_t sp
,
1323 addr_t function_addr
, addr_t return_addr
,
1324 llvm::ArrayRef
<addr_t
> args
) const {
1325 RegisterContext
*reg_ctx
= thread
.GetRegisterContext().get();
1329 const uint32_t pc_reg_num
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1330 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_PC
);
1331 const uint32_t sp_reg_num
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1332 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_SP
);
1333 const uint32_t ra_reg_num
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1334 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_RA
);
1336 RegisterValue reg_value
;
1338 const char *reg_names
[] = {"r0", "r1", "r2", "r3"};
1340 llvm::ArrayRef
<addr_t
>::iterator ai
= args
.begin(), ae
= args
.end();
1342 for (size_t i
= 0; i
< std::size(reg_names
); ++i
) {
1346 reg_value
.SetUInt32(*ai
);
1347 if (!reg_ctx
->WriteRegister(reg_ctx
->GetRegisterInfoByName(reg_names
[i
]),
1355 // Spill onto the stack
1356 size_t num_stack_regs
= ae
- ai
;
1358 sp
-= (num_stack_regs
* 4);
1359 // Keep the stack 16 byte aligned
1360 sp
&= ~(16ull - 1ull);
1362 // just using arg1 to get the right size
1363 const RegisterInfo
*reg_info
= reg_ctx
->GetRegisterInfo(
1364 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG1
);
1366 addr_t arg_pos
= sp
;
1368 for (; ai
!= ae
; ++ai
) {
1369 reg_value
.SetUInt32(*ai
);
1371 ->WriteRegisterValueToMemory(reg_info
, arg_pos
,
1372 reg_info
->byte_size
, reg_value
)
1375 arg_pos
+= reg_info
->byte_size
;
1379 TargetSP
target_sp(thread
.CalculateTarget());
1382 // Figure out if our return address is ARM or Thumb by using the
1383 // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1384 // thumb-ness and set the correct address bits for us.
1385 so_addr
.SetLoadAddress(return_addr
, target_sp
.get());
1386 return_addr
= so_addr
.GetCallableLoadAddress(target_sp
.get());
1388 // Set "lr" to the return address
1389 if (!reg_ctx
->WriteRegisterFromUnsigned(ra_reg_num
, return_addr
))
1392 // If bit zero or 1 is set, this must be a thumb function, no need to figure
1393 // this out from the symbols.
1394 so_addr
.SetLoadAddress(function_addr
, target_sp
.get());
1395 function_addr
= so_addr
.GetCallableLoadAddress(target_sp
.get());
1397 const RegisterInfo
*cpsr_reg_info
= reg_ctx
->GetRegisterInfoByName("cpsr");
1398 const uint32_t curr_cpsr
= reg_ctx
->ReadRegisterAsUnsigned(cpsr_reg_info
, 0);
1400 // Make a new CPSR and mask out any Thumb IT (if/then) bits
1401 uint32_t new_cpsr
= curr_cpsr
& ~MASK_CPSR_IT_MASK
;
1402 // If bit zero or 1 is set, this must be thumb...
1403 if (function_addr
& 1ull)
1404 new_cpsr
|= MASK_CPSR_T
; // Set T bit in CPSR
1406 new_cpsr
&= ~MASK_CPSR_T
; // Clear T bit in CPSR
1408 if (new_cpsr
!= curr_cpsr
) {
1409 if (!reg_ctx
->WriteRegisterFromUnsigned(cpsr_reg_info
, new_cpsr
))
1414 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1416 // Update the sp - stack pointer - to be aligned to 16-bytes
1418 if (!reg_ctx
->WriteRegisterFromUnsigned(sp_reg_num
, sp
))
1421 // Set "pc" to the address requested
1422 if (!reg_ctx
->WriteRegisterFromUnsigned(pc_reg_num
, function_addr
))
1428 bool ABIMacOSX_arm::GetArgumentValues(Thread
&thread
, ValueList
&values
) const {
1429 uint32_t num_values
= values
.GetSize();
1431 ExecutionContext
exe_ctx(thread
.shared_from_this());
1432 // For now, assume that the types in the AST values come from the Target's
1435 // Extract the register context so we can read arguments from registers
1437 RegisterContext
*reg_ctx
= thread
.GetRegisterContext().get();
1444 for (uint32_t value_idx
= 0; value_idx
< num_values
; ++value_idx
) {
1445 // We currently only support extracting values with Clang QualTypes. Do we
1446 // care about others?
1447 Value
*value
= values
.GetValueAtIndex(value_idx
);
1452 CompilerType compiler_type
= value
->GetCompilerType();
1453 if (compiler_type
) {
1454 bool is_signed
= false;
1455 size_t bit_width
= 0;
1456 std::optional
<uint64_t> bit_size
= compiler_type
.GetBitSize(&thread
);
1459 if (compiler_type
.IsIntegerOrEnumerationType(is_signed
))
1460 bit_width
= *bit_size
;
1461 else if (compiler_type
.IsPointerOrReferenceType())
1462 bit_width
= *bit_size
;
1464 // We only handle integer, pointer and reference types currently...
1467 if (bit_width
<= (exe_ctx
.GetProcessRef().GetAddressByteSize() * 8)) {
1468 if (value_idx
< 4) {
1469 // Arguments 1-4 are in r0-r3...
1470 const RegisterInfo
*arg_reg_info
= nullptr;
1471 // Search by generic ID first, then fall back to by name
1472 uint32_t arg_reg_num
= reg_ctx
->ConvertRegisterKindToRegisterNumber(
1473 eRegisterKindGeneric
, LLDB_REGNUM_GENERIC_ARG1
+ value_idx
);
1474 if (arg_reg_num
!= LLDB_INVALID_REGNUM
) {
1475 arg_reg_info
= reg_ctx
->GetRegisterInfoAtIndex(arg_reg_num
);
1477 switch (value_idx
) {
1479 arg_reg_info
= reg_ctx
->GetRegisterInfoByName("r0");
1482 arg_reg_info
= reg_ctx
->GetRegisterInfoByName("r1");
1485 arg_reg_info
= reg_ctx
->GetRegisterInfoByName("r2");
1488 arg_reg_info
= reg_ctx
->GetRegisterInfoByName("r3");
1494 RegisterValue reg_value
;
1496 if (reg_ctx
->ReadRegister(arg_reg_info
, reg_value
)) {
1498 reg_value
.SignExtend(bit_width
);
1499 if (!reg_value
.GetScalarValue(value
->GetScalar()))
1507 // Read the stack pointer if it already hasn't been read
1508 sp
= reg_ctx
->GetSP(0);
1513 // Arguments 5 on up are on the stack
1514 const uint32_t arg_byte_size
= (bit_width
+ (8 - 1)) / 8;
1516 if (!exe_ctx
.GetProcessRef().ReadScalarIntegerFromMemory(
1517 sp
, arg_byte_size
, is_signed
, value
->GetScalar(), error
))
1520 sp
+= arg_byte_size
;
1528 bool ABIMacOSX_arm::IsArmv7kProcess() const {
1529 bool is_armv7k
= false;
1530 ProcessSP
process_sp(GetProcessSP());
1532 const ArchSpec
&arch(process_sp
->GetTarget().GetArchitecture());
1533 const ArchSpec::Core system_core
= arch
.GetCore();
1534 if (system_core
== ArchSpec::eCore_arm_armv7k
) {
1541 ValueObjectSP
ABIMacOSX_arm::GetReturnValueObjectImpl(
1542 Thread
&thread
, lldb_private::CompilerType
&compiler_type
) const {
1544 ValueObjectSP return_valobj_sp
;
1547 return return_valobj_sp
;
1549 value
.SetCompilerType(compiler_type
);
1551 RegisterContext
*reg_ctx
= thread
.GetRegisterContext().get();
1553 return return_valobj_sp
;
1557 // Get the pointer to the first stack argument so we have a place to start
1558 // when reading data
1560 const RegisterInfo
*r0_reg_info
= reg_ctx
->GetRegisterInfoByName("r0", 0);
1561 if (compiler_type
.IsIntegerOrEnumerationType(is_signed
)) {
1562 std::optional
<uint64_t> bit_width
= compiler_type
.GetBitSize(&thread
);
1564 return return_valobj_sp
;
1566 switch (*bit_width
) {
1568 return return_valobj_sp
;
1570 if (IsArmv7kProcess()) {
1571 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1572 // format is as if the result had been stored in memory at a word-
1573 // aligned address and then loaded into r0-r3 with an ldm instruction"
1575 const RegisterInfo
*r1_reg_info
=
1576 reg_ctx
->GetRegisterInfoByName("r1", 0);
1577 const RegisterInfo
*r2_reg_info
=
1578 reg_ctx
->GetRegisterInfoByName("r2", 0);
1579 const RegisterInfo
*r3_reg_info
=
1580 reg_ctx
->GetRegisterInfoByName("r3", 0);
1581 if (r1_reg_info
&& r2_reg_info
&& r3_reg_info
) {
1582 std::optional
<uint64_t> byte_size
=
1583 compiler_type
.GetByteSize(&thread
);
1585 return return_valobj_sp
;
1586 ProcessSP
process_sp(thread
.GetProcess());
1587 if (*byte_size
<= r0_reg_info
->byte_size
+ r1_reg_info
->byte_size
+
1588 r2_reg_info
->byte_size
+
1589 r3_reg_info
->byte_size
&&
1591 std::unique_ptr
<DataBufferHeap
> heap_data_up(
1592 new DataBufferHeap(*byte_size
, 0));
1593 const ByteOrder byte_order
= process_sp
->GetByteOrder();
1594 RegisterValue r0_reg_value
;
1595 RegisterValue r1_reg_value
;
1596 RegisterValue r2_reg_value
;
1597 RegisterValue r3_reg_value
;
1598 if (reg_ctx
->ReadRegister(r0_reg_info
, r0_reg_value
) &&
1599 reg_ctx
->ReadRegister(r1_reg_info
, r1_reg_value
) &&
1600 reg_ctx
->ReadRegister(r2_reg_info
, r2_reg_value
) &&
1601 reg_ctx
->ReadRegister(r3_reg_info
, r3_reg_value
)) {
1603 if (r0_reg_value
.GetAsMemoryData(*r0_reg_info
,
1604 heap_data_up
->GetBytes() + 0,
1605 4, byte_order
, error
) &&
1606 r1_reg_value
.GetAsMemoryData(*r1_reg_info
,
1607 heap_data_up
->GetBytes() + 4,
1608 4, byte_order
, error
) &&
1609 r2_reg_value
.GetAsMemoryData(*r2_reg_info
,
1610 heap_data_up
->GetBytes() + 8,
1611 4, byte_order
, error
) &&
1612 r3_reg_value
.GetAsMemoryData(*r3_reg_info
,
1613 heap_data_up
->GetBytes() + 12,
1614 4, byte_order
, error
)) {
1615 DataExtractor
data(DataBufferSP(heap_data_up
.release()),
1617 process_sp
->GetAddressByteSize());
1619 return_valobj_sp
= ValueObjectConstResult::Create(
1620 &thread
, compiler_type
, ConstString(""), data
);
1621 return return_valobj_sp
;
1628 return return_valobj_sp
;
1632 const RegisterInfo
*r1_reg_info
= reg_ctx
->GetRegisterInfoByName("r1", 0);
1634 raw_value
= reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
;
1635 raw_value
|= ((uint64_t)(reg_ctx
->ReadRegisterAsUnsigned(r1_reg_info
, 0) &
1639 value
.GetScalar() = (int64_t)raw_value
;
1641 value
.GetScalar() = (uint64_t)raw_value
;
1645 value
.GetScalar() = (int32_t)(
1646 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
);
1648 value
.GetScalar() = (uint32_t)(
1649 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT32_MAX
);
1653 value
.GetScalar() = (int16_t)(
1654 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT16_MAX
);
1656 value
.GetScalar() = (uint16_t)(
1657 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT16_MAX
);
1661 value
.GetScalar() = (int8_t)(
1662 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT8_MAX
);
1664 value
.GetScalar() = (uint8_t)(
1665 reg_ctx
->ReadRegisterAsUnsigned(r0_reg_info
, 0) & UINT8_MAX
);
1668 } else if (compiler_type
.IsPointerType()) {
1670 thread
.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info
, 0) &
1672 value
.GetScalar() = ptr
;
1675 return return_valobj_sp
;
1678 // If we get here, we have a valid Value, so make our ValueObject out of it:
1680 return_valobj_sp
= ValueObjectConstResult::Create(
1681 thread
.GetStackFrameAtIndex(0).get(), value
, ConstString(""));
1682 return return_valobj_sp
;
1685 Status
ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP
&frame_sp
,
1686 lldb::ValueObjectSP
&new_value_sp
) {
1688 if (!new_value_sp
) {
1689 error
.SetErrorString("Empty value object for return value.");
1693 CompilerType compiler_type
= new_value_sp
->GetCompilerType();
1694 if (!compiler_type
) {
1695 error
.SetErrorString("Null clang type for return value.");
1699 Thread
*thread
= frame_sp
->GetThread().get();
1705 RegisterContext
*reg_ctx
= thread
->GetRegisterContext().get();
1707 bool set_it_simple
= false;
1708 if (compiler_type
.IsIntegerOrEnumerationType(is_signed
) ||
1709 compiler_type
.IsPointerType()) {
1712 size_t num_bytes
= new_value_sp
->GetData(data
, data_error
);
1713 if (data_error
.Fail()) {
1714 error
.SetErrorStringWithFormat(
1715 "Couldn't convert return value to raw data: %s",
1716 data_error
.AsCString());
1719 lldb::offset_t offset
= 0;
1720 if (num_bytes
<= 8) {
1721 const RegisterInfo
*r0_info
= reg_ctx
->GetRegisterInfoByName("r0", 0);
1722 if (num_bytes
<= 4) {
1723 uint32_t raw_value
= data
.GetMaxU32(&offset
, num_bytes
);
1725 if (reg_ctx
->WriteRegisterFromUnsigned(r0_info
, raw_value
))
1726 set_it_simple
= true;
1728 uint32_t raw_value
= data
.GetMaxU32(&offset
, 4);
1730 if (reg_ctx
->WriteRegisterFromUnsigned(r0_info
, raw_value
)) {
1731 const RegisterInfo
*r1_info
= reg_ctx
->GetRegisterInfoByName("r1", 0);
1732 uint32_t raw_value
= data
.GetMaxU32(&offset
, num_bytes
- offset
);
1734 if (reg_ctx
->WriteRegisterFromUnsigned(r1_info
, raw_value
))
1735 set_it_simple
= true;
1738 } else if (num_bytes
<= 16 && IsArmv7kProcess()) {
1739 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1740 // format is as if the result had been stored in memory at a word-aligned
1741 // address and then loaded into r0-r3 with an ldm instruction"
1743 const RegisterInfo
*r0_info
= reg_ctx
->GetRegisterInfoByName("r0", 0);
1744 const RegisterInfo
*r1_info
= reg_ctx
->GetRegisterInfoByName("r1", 0);
1745 const RegisterInfo
*r2_info
= reg_ctx
->GetRegisterInfoByName("r2", 0);
1746 const RegisterInfo
*r3_info
= reg_ctx
->GetRegisterInfoByName("r3", 0);
1747 lldb::offset_t offset
= 0;
1748 uint32_t bytes_written
= 4;
1749 uint32_t raw_value
= data
.GetMaxU64(&offset
, 4);
1750 if (reg_ctx
->WriteRegisterFromUnsigned(r0_info
, raw_value
) &&
1751 bytes_written
<= num_bytes
) {
1753 raw_value
= data
.GetMaxU64(&offset
, 4);
1754 if (bytes_written
<= num_bytes
&&
1755 reg_ctx
->WriteRegisterFromUnsigned(r1_info
, raw_value
)) {
1757 raw_value
= data
.GetMaxU64(&offset
, 4);
1758 if (bytes_written
<= num_bytes
&&
1759 reg_ctx
->WriteRegisterFromUnsigned(r2_info
, raw_value
)) {
1761 raw_value
= data
.GetMaxU64(&offset
, 4);
1762 if (bytes_written
<= num_bytes
&&
1763 reg_ctx
->WriteRegisterFromUnsigned(r3_info
, raw_value
)) {
1764 set_it_simple
= true;
1770 error
.SetErrorString("We don't support returning longer than 64 bit "
1771 "integer values at present.");
1773 } else if (compiler_type
.IsFloatingPointType(count
, is_complex
)) {
1775 error
.SetErrorString(
1776 "We don't support returning complex values at present");
1778 error
.SetErrorString(
1779 "We don't support returning float values at present");
1783 error
.SetErrorString(
1784 "We only support setting simple integer return types at present.");
1789 bool ABIMacOSX_arm::CreateFunctionEntryUnwindPlan(UnwindPlan
&unwind_plan
) {
1790 unwind_plan
.Clear();
1791 unwind_plan
.SetRegisterKind(eRegisterKindDWARF
);
1793 uint32_t lr_reg_num
= dwarf_lr
;
1794 uint32_t sp_reg_num
= dwarf_sp
;
1795 uint32_t pc_reg_num
= dwarf_pc
;
1797 UnwindPlan::RowSP
row(new UnwindPlan::Row
);
1799 // Our Call Frame Address is the stack pointer value
1800 row
->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num
, 0);
1802 // The previous PC is in the LR
1803 row
->SetRegisterLocationToRegister(pc_reg_num
, lr_reg_num
, true);
1804 unwind_plan
.AppendRow(row
);
1806 // All other registers are the same.
1808 unwind_plan
.SetSourceName("arm at-func-entry default");
1809 unwind_plan
.SetSourcedFromCompiler(eLazyBoolNo
);
1814 bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan
&unwind_plan
) {
1815 unwind_plan
.Clear();
1816 unwind_plan
.SetRegisterKind(eRegisterKindDWARF
);
1818 uint32_t fp_reg_num
=
1819 dwarf_r7
; // apple uses r7 for all frames. Normal arm uses r11
1820 uint32_t pc_reg_num
= dwarf_pc
;
1822 UnwindPlan::RowSP
row(new UnwindPlan::Row
);
1823 const int32_t ptr_size
= 4;
1825 row
->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num
, 2 * ptr_size
);
1827 row
->SetUnspecifiedRegistersAreUndefined(true);
1829 row
->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num
, ptr_size
* -2, true);
1830 row
->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num
, ptr_size
* -1, true);
1832 unwind_plan
.AppendRow(row
);
1833 unwind_plan
.SetSourceName("arm-apple-ios default unwind plan");
1834 unwind_plan
.SetSourcedFromCompiler(eLazyBoolNo
);
1835 unwind_plan
.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo
);
1836 unwind_plan
.SetUnwindPlanForSignalTrap(eLazyBoolNo
);
1841 // cf. "ARMv6 Function Calling Conventions"
1842 // https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
1843 // and "ARMv7 Function Calling Conventions"
1844 // https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv7FunctionCallingConventions.html
1846 // ARMv7 on iOS general purpose reg rules:
1847 // r0-r3 not preserved (used for argument passing)
1849 // r7 preserved (frame pointer)
1851 // r9 not preserved (usable as volatile scratch register with iOS 3.x and
1853 // r10-r11 preserved
1855 // r13 preserved (stack pointer)
1856 // r14 not preserved (link register)
1857 // r15 preserved (pc)
1858 // cpsr not preserved (different rules for different bits)
1860 // ARMv7 on iOS floating point rules:
1861 // d0-d7 not preserved (aka s0-s15, q0-q3)
1862 // d8-d15 preserved (aka s16-s31, q4-q7)
1863 // d16-d31 not preserved (aka q8-q15)
1865 bool ABIMacOSX_arm::RegisterIsVolatile(const RegisterInfo
*reg_info
) {
1867 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1868 const char *name
= reg_info
->name
;
1869 if (name
[0] == 'r') {
1872 return name
[2] == '\0'; // r0
1879 return name
[3] == '\0'; // r12, r13 (sp)
1886 return name
[2] == '\0'; // r2
1888 return name
[2] == '\0'; // r3
1890 return name
[2] == '\0'; // r9 (apple-ios only...)
1894 } else if (name
[0] == 'd') {
1897 return name
[2] == '\0'; // d0 is volatile
1902 return true; // d1 is volatile
1907 return name
[3] == '\0'; // d16 - d19 are volatile
1916 return true; // d2 is volatile
1927 return name
[3] == '\0'; // d20 - d29 are volatile
1936 return true; // d3 is volatile
1939 return name
[3] == '\0'; // d30 - d31 are volatile
1948 return name
[2] == '\0'; // d4 - d7 are volatile
1953 } else if (name
[0] == 's') {
1956 return name
[2] == '\0'; // s0 is volatile
1961 return true; // s1 is volatile
1968 return name
[3] == '\0'; // s10 - s15 are volatile
1982 return name
[2] == '\0'; // s2 - s9 are volatile
1987 } else if (name
[0] == 'q') {
1992 return true; // q1 is volatile
1999 return true; // q10-q15 are volatile
2007 return name
[2] == '\0'; // q0-q3 are volatile
2010 return name
[2] == '\0'; // q8-q9 are volatile
2014 } else if (name
[0] == 's' && name
[1] == 'p' && name
[2] == '\0')
2020 void ABIMacOSX_arm::Initialize() {
2021 PluginManager::RegisterPlugin(GetPluginNameStatic(),
2022 "Mac OS X ABI for arm targets", CreateInstance
);
2025 void ABIMacOSX_arm::Terminate() {
2026 PluginManager::UnregisterPlugin(CreateInstance
);