LLDB mainline
ABIMacOSX_arm.cpp
Go to the documentation of this file.
1//===-- ABIMacOSX_arm.cpp -------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include "ABIMacOSX_arm.h"
10
11#include <optional>
12#include <vector>
13
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/TargetParser/Triple.h"
16
17#include "lldb/Core/Module.h"
19#include "lldb/Core/Value.h"
22#include "lldb/Target/Process.h"
24#include "lldb/Target/Target.h"
25#include "lldb/Target/Thread.h"
28#include "lldb/Utility/Scalar.h"
29#include "lldb/Utility/Status.h"
30
34
35using namespace lldb;
36using namespace lldb_private;
37
38static const RegisterInfo g_register_infos[] = {
39 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
40 // DWARF GENERIC PROCESS PLUGIN
41 // LLDB NATIVE
42 // ========== ======= == === ============= ============
43 // ======================= =================== ===========================
44 // ======================= ======================
45 {"r0",
46 nullptr,
47 4,
48 0,
53 nullptr,
54 nullptr,
55 },
56 {"r1",
57 nullptr,
58 4,
59 0,
64 nullptr,
65 nullptr,
66 },
67 {"r2",
68 nullptr,
69 4,
70 0,
75 nullptr,
76 nullptr,
77 },
78 {"r3",
79 nullptr,
80 4,
81 0,
86 nullptr,
87 nullptr,
88 },
89 {"r4",
90 nullptr,
91 4,
92 0,
97 nullptr,
98 nullptr,
99 },
100 {"r5",
101 nullptr,
102 4,
103 0,
108 nullptr,
109 nullptr,
110 },
111 {"r6",
112 nullptr,
113 4,
114 0,
119 nullptr,
120 nullptr,
121 },
122 {"r7",
123 nullptr,
124 4,
125 0,
130 nullptr,
131 nullptr,
132 },
133 {"r8",
134 nullptr,
135 4,
136 0,
141 nullptr,
142 nullptr,
143 },
144 {"r9",
145 nullptr,
146 4,
147 0,
152 nullptr,
153 nullptr,
154 },
155 {"r10",
156 nullptr,
157 4,
158 0,
163 nullptr,
164 nullptr,
165 },
166 {"r11",
167 nullptr,
168 4,
169 0,
174 nullptr,
175 nullptr,
176 },
177 {"r12",
178 nullptr,
179 4,
180 0,
185 nullptr,
186 nullptr,
187 },
188 {"sp",
189 "r13",
190 4,
191 0,
196 nullptr,
197 nullptr,
198 },
199 {"lr",
200 "r14",
201 4,
202 0,
207 nullptr,
208 nullptr,
209 },
210 {"pc",
211 "r15",
212 4,
213 0,
218 nullptr,
219 nullptr,
220 },
221 {"cpsr",
222 "psr",
223 4,
224 0,
229 nullptr,
230 nullptr,
231 },
232 {"s0",
233 nullptr,
234 4,
235 0,
240 nullptr,
241 nullptr,
242 },
243 {"s1",
244 nullptr,
245 4,
246 0,
251 nullptr,
252 nullptr,
253 },
254 {"s2",
255 nullptr,
256 4,
257 0,
262 nullptr,
263 nullptr,
264 },
265 {"s3",
266 nullptr,
267 4,
268 0,
273 nullptr,
274 nullptr,
275 },
276 {"s4",
277 nullptr,
278 4,
279 0,
284 nullptr,
285 nullptr,
286 },
287 {"s5",
288 nullptr,
289 4,
290 0,
295 nullptr,
296 nullptr,
297 },
298 {"s6",
299 nullptr,
300 4,
301 0,
306 nullptr,
307 nullptr,
308 },
309 {"s7",
310 nullptr,
311 4,
312 0,
317 nullptr,
318 nullptr,
319 },
320 {"s8",
321 nullptr,
322 4,
323 0,
328 nullptr,
329 nullptr,
330 },
331 {"s9",
332 nullptr,
333 4,
334 0,
339 nullptr,
340 nullptr,
341 },
342 {"s10",
343 nullptr,
344 4,
345 0,
350 nullptr,
351 nullptr,
352 },
353 {"s11",
354 nullptr,
355 4,
356 0,
361 nullptr,
362 nullptr,
363 },
364 {"s12",
365 nullptr,
366 4,
367 0,
372 nullptr,
373 nullptr,
374 },
375 {"s13",
376 nullptr,
377 4,
378 0,
383 nullptr,
384 nullptr,
385 },
386 {"s14",
387 nullptr,
388 4,
389 0,
394 nullptr,
395 nullptr,
396 },
397 {"s15",
398 nullptr,
399 4,
400 0,
405 nullptr,
406 nullptr,
407 },
408 {"s16",
409 nullptr,
410 4,
411 0,
416 nullptr,
417 nullptr,
418 },
419 {"s17",
420 nullptr,
421 4,
422 0,
427 nullptr,
428 nullptr,
429 },
430 {"s18",
431 nullptr,
432 4,
433 0,
438 nullptr,
439 nullptr,
440 },
441 {"s19",
442 nullptr,
443 4,
444 0,
449 nullptr,
450 nullptr,
451 },
452 {"s20",
453 nullptr,
454 4,
455 0,
460 nullptr,
461 nullptr,
462 },
463 {"s21",
464 nullptr,
465 4,
466 0,
471 nullptr,
472 nullptr,
473 },
474 {"s22",
475 nullptr,
476 4,
477 0,
482 nullptr,
483 nullptr,
484 },
485 {"s23",
486 nullptr,
487 4,
488 0,
493 nullptr,
494 nullptr,
495 },
496 {"s24",
497 nullptr,
498 4,
499 0,
504 nullptr,
505 nullptr,
506 },
507 {"s25",
508 nullptr,
509 4,
510 0,
515 nullptr,
516 nullptr,
517 },
518 {"s26",
519 nullptr,
520 4,
521 0,
526 nullptr,
527 nullptr,
528 },
529 {"s27",
530 nullptr,
531 4,
532 0,
537 nullptr,
538 nullptr,
539 },
540 {"s28",
541 nullptr,
542 4,
543 0,
548 nullptr,
549 nullptr,
550 },
551 {"s29",
552 nullptr,
553 4,
554 0,
559 nullptr,
560 nullptr,
561 },
562 {"s30",
563 nullptr,
564 4,
565 0,
570 nullptr,
571 nullptr,
572 },
573 {"s31",
574 nullptr,
575 4,
576 0,
581 nullptr,
582 nullptr,
583 },
584 {"fpscr",
585 nullptr,
586 4,
587 0,
592 nullptr,
593 nullptr,
594 },
595 {"d0",
596 nullptr,
597 8,
598 0,
603 nullptr,
604 nullptr,
605 },
606 {"d1",
607 nullptr,
608 8,
609 0,
614 nullptr,
615 nullptr,
616 },
617 {"d2",
618 nullptr,
619 8,
620 0,
625 nullptr,
626 nullptr,
627 },
628 {"d3",
629 nullptr,
630 8,
631 0,
636 nullptr,
637 nullptr,
638 },
639 {"d4",
640 nullptr,
641 8,
642 0,
647 nullptr,
648 nullptr,
649 },
650 {"d5",
651 nullptr,
652 8,
653 0,
658 nullptr,
659 nullptr,
660 },
661 {"d6",
662 nullptr,
663 8,
664 0,
669 nullptr,
670 nullptr,
671 },
672 {"d7",
673 nullptr,
674 8,
675 0,
680 nullptr,
681 nullptr,
682 },
683 {"d8",
684 nullptr,
685 8,
686 0,
691 nullptr,
692 nullptr,
693 },
694 {"d9",
695 nullptr,
696 8,
697 0,
702 nullptr,
703 nullptr,
704 },
705 {"d10",
706 nullptr,
707 8,
708 0,
713 nullptr,
714 nullptr,
715 },
716 {"d11",
717 nullptr,
718 8,
719 0,
724 nullptr,
725 nullptr,
726 },
727 {"d12",
728 nullptr,
729 8,
730 0,
735 nullptr,
736 nullptr,
737 },
738 {"d13",
739 nullptr,
740 8,
741 0,
746 nullptr,
747 nullptr,
748 },
749 {"d14",
750 nullptr,
751 8,
752 0,
757 nullptr,
758 nullptr,
759 },
760 {"d15",
761 nullptr,
762 8,
763 0,
768 nullptr,
769 nullptr,
770 },
771 {"d16",
772 nullptr,
773 8,
774 0,
779 nullptr,
780 nullptr,
781 },
782 {"d17",
783 nullptr,
784 8,
785 0,
790 nullptr,
791 nullptr,
792 },
793 {"d18",
794 nullptr,
795 8,
796 0,
801 nullptr,
802 nullptr,
803 },
804 {"d19",
805 nullptr,
806 8,
807 0,
812 nullptr,
813 nullptr,
814 },
815 {"d20",
816 nullptr,
817 8,
818 0,
823 nullptr,
824 nullptr,
825 },
826 {"d21",
827 nullptr,
828 8,
829 0,
834 nullptr,
835 nullptr,
836 },
837 {"d22",
838 nullptr,
839 8,
840 0,
845 nullptr,
846 nullptr,
847 },
848 {"d23",
849 nullptr,
850 8,
851 0,
856 nullptr,
857 nullptr,
858 },
859 {"d24",
860 nullptr,
861 8,
862 0,
867 nullptr,
868 nullptr,
869 },
870 {"d25",
871 nullptr,
872 8,
873 0,
878 nullptr,
879 nullptr,
880 },
881 {"d26",
882 nullptr,
883 8,
884 0,
889 nullptr,
890 nullptr,
891 },
892 {"d27",
893 nullptr,
894 8,
895 0,
900 nullptr,
901 nullptr,
902 },
903 {"d28",
904 nullptr,
905 8,
906 0,
911 nullptr,
912 nullptr,
913 },
914 {"d29",
915 nullptr,
916 8,
917 0,
922 nullptr,
923 nullptr,
924 },
925 {"d30",
926 nullptr,
927 8,
928 0,
933 nullptr,
934 nullptr,
935 },
936 {"d31",
937 nullptr,
938 8,
939 0,
944 nullptr,
945 nullptr,
946 },
947 {"r8_usr",
948 nullptr,
949 4,
950 0,
955 nullptr,
956 nullptr,
957 },
958 {"r9_usr",
959 nullptr,
960 4,
961 0,
966 nullptr,
967 nullptr,
968 },
969 {"r10_usr",
970 nullptr,
971 4,
972 0,
977 nullptr,
978 nullptr,
979 },
980 {"r11_usr",
981 nullptr,
982 4,
983 0,
988 nullptr,
989 nullptr,
990 },
991 {"r12_usr",
992 nullptr,
993 4,
994 0,
999 nullptr,
1000 nullptr,
1001 },
1002 {"r13_usr",
1003 "sp_usr",
1004 4,
1005 0,
1007 eFormatHex,
1010 nullptr,
1011 nullptr,
1012 },
1013 {"r14_usr",
1014 "lr_usr",
1015 4,
1016 0,
1018 eFormatHex,
1021 nullptr,
1022 nullptr,
1023 },
1024 {"r8_fiq",
1025 nullptr,
1026 4,
1027 0,
1029 eFormatHex,
1032 nullptr,
1033 nullptr,
1034 },
1035 {"r9_fiq",
1036 nullptr,
1037 4,
1038 0,
1040 eFormatHex,
1043 nullptr,
1044 nullptr,
1045 },
1046 {"r10_fiq",
1047 nullptr,
1048 4,
1049 0,
1051 eFormatHex,
1054 nullptr,
1055 nullptr,
1056 },
1057 {"r11_fiq",
1058 nullptr,
1059 4,
1060 0,
1062 eFormatHex,
1065 nullptr,
1066 nullptr,
1067 },
1068 {"r12_fiq",
1069 nullptr,
1070 4,
1071 0,
1073 eFormatHex,
1076 nullptr,
1077 nullptr,
1078 },
1079 {"r13_fiq",
1080 "sp_fiq",
1081 4,
1082 0,
1084 eFormatHex,
1087 nullptr,
1088 nullptr,
1089 },
1090 {"r14_fiq",
1091 "lr_fiq",
1092 4,
1093 0,
1095 eFormatHex,
1098 nullptr,
1099 nullptr,
1100 },
1101 {"r13_irq",
1102 "sp_irq",
1103 4,
1104 0,
1106 eFormatHex,
1109 nullptr,
1110 nullptr,
1111 },
1112 {"r14_irq",
1113 "lr_irq",
1114 4,
1115 0,
1117 eFormatHex,
1120 nullptr,
1121 nullptr,
1122 },
1123 {"r13_abt",
1124 "sp_abt",
1125 4,
1126 0,
1128 eFormatHex,
1131 nullptr,
1132 nullptr,
1133 },
1134 {"r14_abt",
1135 "lr_abt",
1136 4,
1137 0,
1139 eFormatHex,
1142 nullptr,
1143 nullptr,
1144 },
1145 {"r13_und",
1146 "sp_und",
1147 4,
1148 0,
1150 eFormatHex,
1153 nullptr,
1154 nullptr,
1155 },
1156 {"r14_und",
1157 "lr_und",
1158 4,
1159 0,
1161 eFormatHex,
1164 nullptr,
1165 nullptr,
1166 },
1167 {"r13_svc",
1168 "sp_svc",
1169 4,
1170 0,
1172 eFormatHex,
1175 nullptr,
1176 nullptr,
1177 },
1178 {"r14_svc",
1179 "lr_svc",
1180 4,
1181 0,
1183 eFormatHex,
1186 nullptr,
1187 nullptr,
1188 }};
1189
1191
1192const lldb_private::RegisterInfo *
1194 count = k_num_register_infos;
1195 return g_register_infos;
1196}
1197
1198size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; }
1199
1200// Static Functions
1201
1202ABISP
1203ABIMacOSX_arm::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
1204 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1205 const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1206
1207 if (vendor_type == llvm::Triple::Apple) {
1208 if ((arch_type == llvm::Triple::arm) ||
1209 (arch_type == llvm::Triple::thumb)) {
1210 return ABISP(
1211 new ABIMacOSX_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1212 }
1213 }
1214
1215 return ABISP();
1216}
1217
1219 addr_t function_addr, addr_t return_addr,
1220 llvm::ArrayRef<addr_t> args) const {
1221 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1222 if (!reg_ctx)
1223 return false;
1224
1225 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1227 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1229 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1231
1232 RegisterValue reg_value;
1233
1234 const char *reg_names[] = {"r0", "r1", "r2", "r3"};
1235
1236 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1237
1238 for (size_t i = 0; i < std::size(reg_names); ++i) {
1239 if (ai == ae)
1240 break;
1241
1242 reg_value.SetUInt32(*ai);
1243 if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName(reg_names[i]),
1244 reg_value))
1245 return false;
1246
1247 ++ai;
1248 }
1249
1250 if (ai != ae) {
1251 // Spill onto the stack
1252 size_t num_stack_regs = ae - ai;
1253
1254 sp -= (num_stack_regs * 4);
1255 // Keep the stack 16 byte aligned
1256 sp &= ~(16ull - 1ull);
1257
1258 // just using arg1 to get the right size
1259 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1261
1262 addr_t arg_pos = sp;
1263
1264 for (; ai != ae; ++ai) {
1265 reg_value.SetUInt32(*ai);
1266 if (reg_ctx
1267 ->WriteRegisterValueToMemory(reg_info, arg_pos,
1268 reg_info->byte_size, reg_value)
1269 .Fail())
1270 return false;
1271 arg_pos += reg_info->byte_size;
1272 }
1273 }
1274
1275 TargetSP target_sp(thread.CalculateTarget());
1276 Address so_addr;
1277
1278 // Figure out if our return address is ARM or Thumb by using the
1279 // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1280 // thumb-ness and set the correct address bits for us.
1281 so_addr.SetLoadAddress(return_addr, target_sp.get());
1282 return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1283
1284 // Set "lr" to the return address
1285 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
1286 return false;
1287
1288 // If bit zero or 1 is set, this must be a thumb function, no need to figure
1289 // this out from the symbols.
1290 so_addr.SetLoadAddress(function_addr, target_sp.get());
1291 function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1292
1293 const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
1294 const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
1295
1296 // Make a new CPSR and mask out any Thumb IT (if/then) bits
1297 uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1298 // If bit zero or 1 is set, this must be thumb...
1299 if (function_addr & 1ull)
1300 new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1301 else
1302 new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1303
1304 if (new_cpsr != curr_cpsr) {
1305 if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1306 return false;
1307 }
1308
1309 function_addr &=
1310 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1311
1312 // Update the sp - stack pointer - to be aligned to 16-bytes
1313 sp &= ~(0xfull);
1314 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1315 return false;
1316
1317 // Set "pc" to the address requested
1318 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr))
1319 return false;
1320
1321 return true;
1322}
1323
1325 uint32_t num_values = values.GetSize();
1326
1327 ExecutionContext exe_ctx(thread.shared_from_this());
1328 // For now, assume that the types in the AST values come from the Target's
1329 // scratch AST.
1330
1331 // Extract the register context so we can read arguments from registers
1332
1333 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1334
1335 if (!reg_ctx)
1336 return false;
1337
1338 addr_t sp = 0;
1339
1340 for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1341 // We currently only support extracting values with Clang QualTypes. Do we
1342 // care about others?
1343 Value *value = values.GetValueAtIndex(value_idx);
1344
1345 if (!value)
1346 return false;
1347
1348 CompilerType compiler_type = value->GetCompilerType();
1349 if (compiler_type) {
1350 bool is_signed = false;
1351 size_t bit_width = 0;
1352 std::optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
1353 if (!bit_size)
1354 return false;
1355 if (compiler_type.IsIntegerOrEnumerationType(is_signed))
1356 bit_width = *bit_size;
1357 else if (compiler_type.IsPointerOrReferenceType())
1358 bit_width = *bit_size;
1359 else
1360 // We only handle integer, pointer and reference types currently...
1361 return false;
1362
1363 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1364 if (value_idx < 4) {
1365 // Arguments 1-4 are in r0-r3...
1366 const RegisterInfo *arg_reg_info = nullptr;
1367 // Search by generic ID first, then fall back to by name
1368 uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1370 if (arg_reg_num != LLDB_INVALID_REGNUM) {
1371 arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
1372 } else {
1373 switch (value_idx) {
1374 case 0:
1375 arg_reg_info = reg_ctx->GetRegisterInfoByName("r0");
1376 break;
1377 case 1:
1378 arg_reg_info = reg_ctx->GetRegisterInfoByName("r1");
1379 break;
1380 case 2:
1381 arg_reg_info = reg_ctx->GetRegisterInfoByName("r2");
1382 break;
1383 case 3:
1384 arg_reg_info = reg_ctx->GetRegisterInfoByName("r3");
1385 break;
1386 }
1387 }
1388
1389 if (arg_reg_info) {
1390 RegisterValue reg_value;
1391
1392 if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1393 if (is_signed)
1394 reg_value.SignExtend(bit_width);
1395 if (!reg_value.GetScalarValue(value->GetScalar()))
1396 return false;
1397 continue;
1398 }
1399 }
1400 return false;
1401 } else {
1402 if (sp == 0) {
1403 // Read the stack pointer if it already hasn't been read
1404 sp = reg_ctx->GetSP(0);
1405 if (sp == 0)
1406 return false;
1407 }
1408
1409 // Arguments 5 on up are on the stack
1410 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1411 Status error;
1413 sp, arg_byte_size, is_signed, value->GetScalar(), error))
1414 return false;
1415
1416 sp += arg_byte_size;
1417 }
1418 }
1419 }
1420 }
1421 return true;
1422}
1423
1425 bool is_armv7k = false;
1426 ProcessSP process_sp(GetProcessSP());
1427 if (process_sp) {
1428 const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1429 const ArchSpec::Core system_core = arch.GetCore();
1430 if (system_core == ArchSpec::eCore_arm_armv7k) {
1431 is_armv7k = true;
1432 }
1433 }
1434 return is_armv7k;
1435}
1436
1438 Thread &thread, lldb_private::CompilerType &compiler_type) const {
1439 Value value;
1440 ValueObjectSP return_valobj_sp;
1441
1442 if (!compiler_type)
1443 return return_valobj_sp;
1444
1445 value.SetCompilerType(compiler_type);
1446
1447 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1448 if (!reg_ctx)
1449 return return_valobj_sp;
1450
1451 bool is_signed;
1452
1453 // Get the pointer to the first stack argument so we have a place to start
1454 // when reading data
1455
1456 const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
1457 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1458 std::optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
1459 if (!bit_width)
1460 return return_valobj_sp;
1461
1462 switch (*bit_width) {
1463 default:
1464 return return_valobj_sp;
1465 case 128:
1466 if (IsArmv7kProcess()) {
1467 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1468 // format is as if the result had been stored in memory at a word-
1469 // aligned address and then loaded into r0-r3 with an ldm instruction"
1470 {
1471 const RegisterInfo *r1_reg_info =
1472 reg_ctx->GetRegisterInfoByName("r1", 0);
1473 const RegisterInfo *r2_reg_info =
1474 reg_ctx->GetRegisterInfoByName("r2", 0);
1475 const RegisterInfo *r3_reg_info =
1476 reg_ctx->GetRegisterInfoByName("r3", 0);
1477 if (r1_reg_info && r2_reg_info && r3_reg_info) {
1478 std::optional<uint64_t> byte_size =
1479 compiler_type.GetByteSize(&thread);
1480 if (!byte_size)
1481 return return_valobj_sp;
1482 ProcessSP process_sp(thread.GetProcess());
1483 if (*byte_size <= r0_reg_info->byte_size + r1_reg_info->byte_size +
1484 r2_reg_info->byte_size +
1485 r3_reg_info->byte_size &&
1486 process_sp) {
1487 std::unique_ptr<DataBufferHeap> heap_data_up(
1488 new DataBufferHeap(*byte_size, 0));
1489 const ByteOrder byte_order = process_sp->GetByteOrder();
1490 RegisterValue r0_reg_value;
1491 RegisterValue r1_reg_value;
1492 RegisterValue r2_reg_value;
1493 RegisterValue r3_reg_value;
1494 if (reg_ctx->ReadRegister(r0_reg_info, r0_reg_value) &&
1495 reg_ctx->ReadRegister(r1_reg_info, r1_reg_value) &&
1496 reg_ctx->ReadRegister(r2_reg_info, r2_reg_value) &&
1497 reg_ctx->ReadRegister(r3_reg_info, r3_reg_value)) {
1498 Status error;
1499 if (r0_reg_value.GetAsMemoryData(*r0_reg_info,
1500 heap_data_up->GetBytes() + 0,
1501 4, byte_order, error) &&
1502 r1_reg_value.GetAsMemoryData(*r1_reg_info,
1503 heap_data_up->GetBytes() + 4,
1504 4, byte_order, error) &&
1505 r2_reg_value.GetAsMemoryData(*r2_reg_info,
1506 heap_data_up->GetBytes() + 8,
1507 4, byte_order, error) &&
1508 r3_reg_value.GetAsMemoryData(*r3_reg_info,
1509 heap_data_up->GetBytes() + 12,
1510 4, byte_order, error)) {
1511 DataExtractor data(DataBufferSP(heap_data_up.release()),
1512 byte_order,
1513 process_sp->GetAddressByteSize());
1514
1515 return_valobj_sp = ValueObjectConstResult::Create(
1516 &thread, compiler_type, ConstString(""), data);
1517 return return_valobj_sp;
1518 }
1519 }
1520 }
1521 }
1522 }
1523 } else {
1524 return return_valobj_sp;
1525 }
1526 break;
1527 case 64: {
1528 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
1529 uint64_t raw_value;
1530 raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1531 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1532 UINT32_MAX))
1533 << 32;
1534 if (is_signed)
1535 value.GetScalar() = (int64_t)raw_value;
1536 else
1537 value.GetScalar() = (uint64_t)raw_value;
1538 } break;
1539 case 32:
1540 if (is_signed)
1541 value.GetScalar() = (int32_t)(
1542 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1543 else
1544 value.GetScalar() = (uint32_t)(
1545 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1546 break;
1547 case 16:
1548 if (is_signed)
1549 value.GetScalar() = (int16_t)(
1550 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1551 else
1552 value.GetScalar() = (uint16_t)(
1553 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1554 break;
1555 case 8:
1556 if (is_signed)
1557 value.GetScalar() = (int8_t)(
1558 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1559 else
1560 value.GetScalar() = (uint8_t)(
1561 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1562 break;
1563 }
1564 } else if (compiler_type.IsPointerType()) {
1565 uint32_t ptr =
1566 thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1567 UINT32_MAX;
1568 value.GetScalar() = ptr;
1569 } else {
1570 // not handled yet
1571 return return_valobj_sp;
1572 }
1573
1574 // If we get here, we have a valid Value, so make our ValueObject out of it:
1575
1576 return_valobj_sp = ValueObjectConstResult::Create(
1577 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1578 return return_valobj_sp;
1579}
1580
1581Status ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1582 lldb::ValueObjectSP &new_value_sp) {
1583 Status error;
1584 if (!new_value_sp) {
1585 error.SetErrorString("Empty value object for return value.");
1586 return error;
1587 }
1588
1589 CompilerType compiler_type = new_value_sp->GetCompilerType();
1590 if (!compiler_type) {
1591 error.SetErrorString("Null clang type for return value.");
1592 return error;
1593 }
1594
1595 Thread *thread = frame_sp->GetThread().get();
1596
1597 bool is_signed;
1598 uint32_t count;
1599 bool is_complex;
1600
1601 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1602
1603 bool set_it_simple = false;
1604 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1605 compiler_type.IsPointerType()) {
1606 DataExtractor data;
1607 Status data_error;
1608 size_t num_bytes = new_value_sp->GetData(data, data_error);
1609 if (data_error.Fail()) {
1610 error.SetErrorStringWithFormat(
1611 "Couldn't convert return value to raw data: %s",
1612 data_error.AsCString());
1613 return error;
1614 }
1615 lldb::offset_t offset = 0;
1616 if (num_bytes <= 8) {
1617 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
1618 if (num_bytes <= 4) {
1619 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1620
1621 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1622 set_it_simple = true;
1623 } else {
1624 uint32_t raw_value = data.GetMaxU32(&offset, 4);
1625
1626 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1627 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
1628 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1629
1630 if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1631 set_it_simple = true;
1632 }
1633 }
1634 } else if (num_bytes <= 16 && IsArmv7kProcess()) {
1635 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1636 // format is as if the result had been stored in memory at a word-aligned
1637 // address and then loaded into r0-r3 with an ldm instruction"
1638
1639 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
1640 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
1641 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
1642 const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
1643 lldb::offset_t offset = 0;
1644 uint32_t bytes_written = 4;
1645 uint32_t raw_value = data.GetMaxU64(&offset, 4);
1646 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value) &&
1647 bytes_written <= num_bytes) {
1648 bytes_written += 4;
1649 raw_value = data.GetMaxU64(&offset, 4);
1650 if (bytes_written <= num_bytes &&
1651 reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value)) {
1652 bytes_written += 4;
1653 raw_value = data.GetMaxU64(&offset, 4);
1654 if (bytes_written <= num_bytes &&
1655 reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
1656 bytes_written += 4;
1657 raw_value = data.GetMaxU64(&offset, 4);
1658 if (bytes_written <= num_bytes &&
1659 reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) {
1660 set_it_simple = true;
1661 }
1662 }
1663 }
1664 }
1665 } else {
1666 error.SetErrorString("We don't support returning longer than 64 bit "
1667 "integer values at present.");
1668 }
1669 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1670 if (is_complex)
1671 error.SetErrorString(
1672 "We don't support returning complex values at present");
1673 else
1674 error.SetErrorString(
1675 "We don't support returning float values at present");
1676 }
1677
1678 if (!set_it_simple)
1679 error.SetErrorString(
1680 "We only support setting simple integer return types at present.");
1681
1682 return error;
1683}
1684
1686 unwind_plan.Clear();
1688
1689 uint32_t lr_reg_num = dwarf_lr;
1690 uint32_t sp_reg_num = dwarf_sp;
1691 uint32_t pc_reg_num = dwarf_pc;
1692
1694
1695 // Our Call Frame Address is the stack pointer value
1696 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1697
1698 // The previous PC is in the LR
1699 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1700 unwind_plan.AppendRow(row);
1701
1702 // All other registers are the same.
1703
1704 unwind_plan.SetSourceName("arm at-func-entry default");
1706
1707 return true;
1708}
1709
1711 unwind_plan.Clear();
1713
1714 uint32_t fp_reg_num =
1715 dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11
1716 uint32_t pc_reg_num = dwarf_pc;
1717
1719 const int32_t ptr_size = 4;
1720
1721 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1722 row->SetOffset(0);
1723 row->SetUnspecifiedRegistersAreUndefined(true);
1724
1725 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1726 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1727
1728 unwind_plan.AppendRow(row);
1729 unwind_plan.SetSourceName("arm-apple-ios default unwind plan");
1733
1734 return true;
1735}
1736
1737// cf. "ARMv6 Function Calling Conventions"
1738// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
1739// and "ARMv7 Function Calling Conventions"
1740// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv7FunctionCallingConventions.html
1741
1742// ARMv7 on iOS general purpose reg rules:
1743// r0-r3 not preserved (used for argument passing)
1744// r4-r6 preserved
1745// r7 preserved (frame pointer)
1746// r8 preserved
1747// r9 not preserved (usable as volatile scratch register with iOS 3.x and
1748// later)
1749// r10-r11 preserved
1750// r12 not presrved
1751// r13 preserved (stack pointer)
1752// r14 not preserved (link register)
1753// r15 preserved (pc)
1754// cpsr not preserved (different rules for different bits)
1755
1756// ARMv7 on iOS floating point rules:
1757// d0-d7 not preserved (aka s0-s15, q0-q3)
1758// d8-d15 preserved (aka s16-s31, q4-q7)
1759// d16-d31 not preserved (aka q8-q15)
1760
1761bool ABIMacOSX_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
1762 if (reg_info) {
1763 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1764 const char *name = reg_info->name;
1765 if (name[0] == 'r') {
1766 switch (name[1]) {
1767 case '0':
1768 return name[2] == '\0'; // r0
1769 case '1':
1770 switch (name[2]) {
1771 case '\0':
1772 return true; // r1
1773 case '2':
1774 case '3':
1775 return name[3] == '\0'; // r12, r13 (sp)
1776 default:
1777 break;
1778 }
1779 break;
1780
1781 case '2':
1782 return name[2] == '\0'; // r2
1783 case '3':
1784 return name[2] == '\0'; // r3
1785 case '9':
1786 return name[2] == '\0'; // r9 (apple-ios only...)
1787
1788 break;
1789 }
1790 } else if (name[0] == 'd') {
1791 switch (name[1]) {
1792 case '0':
1793 return name[2] == '\0'; // d0 is volatile
1794
1795 case '1':
1796 switch (name[2]) {
1797 case '\0':
1798 return true; // d1 is volatile
1799 case '6':
1800 case '7':
1801 case '8':
1802 case '9':
1803 return name[3] == '\0'; // d16 - d19 are volatile
1804 default:
1805 break;
1806 }
1807 break;
1808
1809 case '2':
1810 switch (name[2]) {
1811 case '\0':
1812 return true; // d2 is volatile
1813 case '0':
1814 case '1':
1815 case '2':
1816 case '3':
1817 case '4':
1818 case '5':
1819 case '6':
1820 case '7':
1821 case '8':
1822 case '9':
1823 return name[3] == '\0'; // d20 - d29 are volatile
1824 default:
1825 break;
1826 }
1827 break;
1828
1829 case '3':
1830 switch (name[2]) {
1831 case '\0':
1832 return true; // d3 is volatile
1833 case '0':
1834 case '1':
1835 return name[3] == '\0'; // d30 - d31 are volatile
1836 default:
1837 break;
1838 }
1839 break;
1840 case '4':
1841 case '5':
1842 case '6':
1843 case '7':
1844 return name[2] == '\0'; // d4 - d7 are volatile
1845
1846 default:
1847 break;
1848 }
1849 } else if (name[0] == 's') {
1850 switch (name[1]) {
1851 case '0':
1852 return name[2] == '\0'; // s0 is volatile
1853
1854 case '1':
1855 switch (name[2]) {
1856 case '\0':
1857 return true; // s1 is volatile
1858 case '0':
1859 case '1':
1860 case '2':
1861 case '3':
1862 case '4':
1863 case '5':
1864 return name[3] == '\0'; // s10 - s15 are volatile
1865 default:
1866 break;
1867 }
1868 break;
1869
1870 case '2':
1871 case '3':
1872 case '4':
1873 case '5':
1874 case '6':
1875 case '7':
1876 case '8':
1877 case '9':
1878 return name[2] == '\0'; // s2 - s9 are volatile
1879
1880 default:
1881 break;
1882 }
1883 } else if (name[0] == 'q') {
1884 switch (name[1]) {
1885 case '1':
1886 switch (name[2]) {
1887 case '\0':
1888 return true; // q1 is volatile
1889 case '0':
1890 case '1':
1891 case '2':
1892 case '3':
1893 case '4':
1894 case '5':
1895 return true; // q10-q15 are volatile
1896 default:
1897 break;
1898 };
1899 break;
1900 case '0':
1901 case '2':
1902 case '3':
1903 return name[2] == '\0'; // q0-q3 are volatile
1904 case '8':
1905 case '9':
1906 return name[2] == '\0'; // q8-q9 are volatile
1907 default:
1908 break;
1909 }
1910 } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
1911 return true;
1912 }
1913 return false;
1914}
1915
1918 "Mac OS X ABI for arm targets", CreateInstance);
1919}
1920
1923}
static const uint32_t k_num_register_infos
static const RegisterInfo g_register_infos[]
@ dwarf_r7
@ dwarf_r12
@ dwarf_r3
@ dwarf_r2
@ dwarf_r8
@ dwarf_r11
@ dwarf_r1
@ dwarf_r9
@ dwarf_pc
@ dwarf_r10
@ dwarf_r6
@ dwarf_r0
@ dwarf_r5
@ dwarf_r4
@ dwarf_lr
#define MASK_CPSR_T
Definition: ARMDefines.h:176
@ dwarf_s15
@ dwarf_s30
@ dwarf_s12
@ dwarf_r8_usr
@ dwarf_s18
@ dwarf_s8
@ dwarf_s27
@ dwarf_s5
@ dwarf_r14_abt
@ dwarf_s14
@ dwarf_s4
@ dwarf_r11_fiq
@ dwarf_d18
@ dwarf_r13_irq
@ dwarf_r14_svc
@ dwarf_d1
@ dwarf_s2
@ dwarf_d2
@ dwarf_r14_usr
@ dwarf_d5
@ dwarf_r11_usr
@ dwarf_s3
@ dwarf_d11
@ dwarf_s10
@ dwarf_s21
@ dwarf_r10_fiq
@ dwarf_s26
@ dwarf_s20
@ dwarf_r14_und
@ dwarf_d28
@ dwarf_d12
@ dwarf_d17
@ dwarf_d21
@ dwarf_d10
@ dwarf_d7
@ dwarf_r13_und
@ dwarf_d29
@ dwarf_s6
@ dwarf_d23
@ dwarf_s23
@ dwarf_d25
@ dwarf_s19
@ dwarf_s28
@ dwarf_s29
@ dwarf_sp
@ dwarf_d8
@ dwarf_r13_abt
@ dwarf_s17
@ dwarf_d24
@ dwarf_r9_fiq
@ dwarf_d27
@ dwarf_s13
@ dwarf_r9_usr
@ dwarf_d13
@ dwarf_d22
@ dwarf_r13_usr
@ dwarf_s0
@ dwarf_s7
@ dwarf_r14_fiq
@ dwarf_d15
@ dwarf_d9
@ dwarf_d6
@ dwarf_r14_irq
@ dwarf_r13_fiq
@ dwarf_s1
@ dwarf_r8_fiq
@ dwarf_d16
@ dwarf_s31
@ dwarf_d4
@ dwarf_cpsr
@ dwarf_s16
@ dwarf_s24
@ dwarf_d19
@ dwarf_r10_usr
@ dwarf_d20
@ dwarf_d0
@ dwarf_d3
@ dwarf_d30
@ dwarf_r13_svc
@ dwarf_d14
@ dwarf_s22
@ dwarf_r12_fiq
@ dwarf_d31
@ dwarf_s25
@ dwarf_r12_usr
@ dwarf_s9
@ dwarf_s11
@ dwarf_d26
@ ehframe_r9
@ ehframe_pc
@ ehframe_lr
@ ehframe_r2
@ ehframe_r5
@ ehframe_r10
@ ehframe_sp
@ ehframe_r1
@ ehframe_r0
@ ehframe_r11
@ ehframe_r4
@ ehframe_r8
@ ehframe_r3
@ ehframe_r6
@ ehframe_cpsr
@ ehframe_r7
@ ehframe_r12
static llvm::raw_ostream & error(Stream &strm)
static void Initialize()
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const override
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
size_t GetRedZoneSize() const override
bool IsArmv7kProcess() const
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, lldb::addr_t func_addr, lldb::addr_t returnAddress, llvm::ArrayRef< lldb::addr_t > args) const override
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
static llvm::StringRef GetPluginNameStatic()
Definition: ABIMacOSX_arm.h:74
static void Terminate()
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
static std::unique_ptr< llvm::MCRegisterInfo > MakeMCRegisterInfo(const ArchSpec &arch)
Utility function to construct a MCRegisterInfo using the ArchSpec triple.
Definition: ABI.cpp:201
lldb::ProcessSP GetProcessSP() const
Request to get a Process shared pointer.
Definition: ABI.h:96
A section + offset based address class.
Definition: Address.h:59
lldb::addr_t GetCallableLoadAddress(Target *target, bool is_indirect=false) const
Get the load address as a callable code load address.
Definition: Address.cpp:336
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
Definition: Address.cpp:1040
An architecture specification class.
Definition: ArchSpec.h:32
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:463
Core GetCore() const
Definition: ArchSpec.h:442
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
std::optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
bool IsFloatingPointType(uint32_t &count, bool &is_complex) const
bool IsIntegerOrEnumerationType(bool &is_signed) const
std::optional< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
bool IsPointerOrReferenceType(CompilerType *pointee_type=nullptr) const
bool IsPointerType(CompilerType *pointee_type=nullptr) const
A uniqued constant string class.
Definition: ConstString.h:39
A subclass of DataBuffer that stores a data buffer on the heap.
An data extractor class.
Definition: DataExtractor.h:48
uint32_t GetMaxU32(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an integer of size byte_size from *offset_ptr.
uint64_t GetMaxU64(lldb::offset_t *offset_ptr, size_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
Process & GetProcessRef() const
Returns a reference to the process object.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
size_t ReadScalarIntegerFromMemory(lldb::addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, Status &error)
Definition: Process.cpp:2224
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3383
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
uint64_t ReadRegisterAsUnsigned(uint32_t reg, uint64_t fail_value)
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
virtual bool WriteRegister(const RegisterInfo *reg_info, const RegisterValue &reg_value)=0
const RegisterInfo * GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)
bool WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue &reg_value)=0
bool SignExtend(uint32_t sign_bitpos)
uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
bool GetScalarValue(Scalar &scalar) const
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
An error handling class.
Definition: Status.h:44
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:130
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:399
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb::TargetSP CalculateTarget() override
Definition: Thread.cpp:1406
lldb::ProcessSP GetProcess() const
Definition: Thread.h:153
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
Definition: UnwindPlan.h:502
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:437
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:362
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:478
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:564
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:490
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:670
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS)
const Scalar & GetScalar() const
Definition: Value.h:112
void SetCompilerType(const CompilerType &compiler_type)
Definition: Value.cpp:252
const CompilerType & GetCompilerType()
Definition: Value.cpp:223
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:54
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:52
#define LLDB_REGNUM_GENERIC_ARG4
Definition: lldb-defines.h:62
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:60
#define LLDB_REGNUM_GENERIC_ARG1
Definition: lldb-defines.h:56
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:55
#define UINT32_MAX
Definition: lldb-defines.h:19
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:79
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:58
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:51
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:53
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Definition: SBAddress.h:15
uint64_t offset_t
Definition: lldb-types.h:83
@ eEncodingIEEE754
float
@ eEncodingUint
unsigned integer
ByteOrder
Byte ordering definitions.
uint64_t addr_t
Definition: lldb-types.h:79
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindDWARF
the register numbers seen DWARF