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"
21#include "lldb/Target/Process.h"
23#include "lldb/Target/Target.h"
24#include "lldb/Target/Thread.h"
27#include "lldb/Utility/Scalar.h"
28#include "lldb/Utility/Status.h"
30
34
35using namespace lldb;
36using namespace lldb_private;
37
39 {"r0",
40 nullptr,
41 4,
42 0,
47 nullptr,
48 nullptr,
49 nullptr,
50 },
51 {"r1",
52 nullptr,
53 4,
54 0,
59 nullptr,
60 nullptr,
61 nullptr,
62 },
63 {"r2",
64 nullptr,
65 4,
66 0,
71 nullptr,
72 nullptr,
73 nullptr,
74 },
75 {"r3",
76 nullptr,
77 4,
78 0,
83 nullptr,
84 nullptr,
85 nullptr,
86 },
87 {"r4",
88 nullptr,
89 4,
90 0,
95 nullptr,
96 nullptr,
97 nullptr,
98 },
99 {"r5",
100 nullptr,
101 4,
102 0,
107 nullptr,
108 nullptr,
109 nullptr,
110 },
111 {"r6",
112 nullptr,
113 4,
114 0,
119 nullptr,
120 nullptr,
121 nullptr,
122 },
123 {"r7",
124 nullptr,
125 4,
126 0,
131 nullptr,
132 nullptr,
133 nullptr,
134 },
135 {"r8",
136 nullptr,
137 4,
138 0,
143 nullptr,
144 nullptr,
145 nullptr,
146 },
147 {"r9",
148 nullptr,
149 4,
150 0,
155 nullptr,
156 nullptr,
157 nullptr,
158 },
159 {"r10",
160 nullptr,
161 4,
162 0,
167 nullptr,
168 nullptr,
169 nullptr,
170 },
171 {"r11",
172 nullptr,
173 4,
174 0,
179 nullptr,
180 nullptr,
181 nullptr,
182 },
183 {"r12",
184 nullptr,
185 4,
186 0,
191 nullptr,
192 nullptr,
193 nullptr,
194 },
195 {"sp",
196 "r13",
197 4,
198 0,
203 nullptr,
204 nullptr,
205 nullptr,
206 },
207 {"lr",
208 "r14",
209 4,
210 0,
215 nullptr,
216 nullptr,
217 nullptr,
218 },
219 {"pc",
220 "r15",
221 4,
222 0,
227 nullptr,
228 nullptr,
229 nullptr,
230 },
231 {"cpsr",
232 "psr",
233 4,
234 0,
239 nullptr,
240 nullptr,
241 nullptr,
242 },
243 {"s0",
244 nullptr,
245 4,
246 0,
251 nullptr,
252 nullptr,
253 nullptr,
254 },
255 {"s1",
256 nullptr,
257 4,
258 0,
263 nullptr,
264 nullptr,
265 nullptr,
266 },
267 {"s2",
268 nullptr,
269 4,
270 0,
275 nullptr,
276 nullptr,
277 nullptr,
278 },
279 {"s3",
280 nullptr,
281 4,
282 0,
287 nullptr,
288 nullptr,
289 nullptr,
290 },
291 {"s4",
292 nullptr,
293 4,
294 0,
299 nullptr,
300 nullptr,
301 nullptr,
302 },
303 {"s5",
304 nullptr,
305 4,
306 0,
311 nullptr,
312 nullptr,
313 nullptr,
314 },
315 {"s6",
316 nullptr,
317 4,
318 0,
323 nullptr,
324 nullptr,
325 nullptr,
326 },
327 {"s7",
328 nullptr,
329 4,
330 0,
335 nullptr,
336 nullptr,
337 nullptr,
338 },
339 {"s8",
340 nullptr,
341 4,
342 0,
347 nullptr,
348 nullptr,
349 nullptr,
350 },
351 {"s9",
352 nullptr,
353 4,
354 0,
359 nullptr,
360 nullptr,
361 nullptr,
362 },
363 {"s10",
364 nullptr,
365 4,
366 0,
371 nullptr,
372 nullptr,
373 nullptr,
374 },
375 {"s11",
376 nullptr,
377 4,
378 0,
383 nullptr,
384 nullptr,
385 nullptr,
386 },
387 {"s12",
388 nullptr,
389 4,
390 0,
395 nullptr,
396 nullptr,
397 nullptr,
398 },
399 {"s13",
400 nullptr,
401 4,
402 0,
407 nullptr,
408 nullptr,
409 nullptr,
410 },
411 {"s14",
412 nullptr,
413 4,
414 0,
419 nullptr,
420 nullptr,
421 nullptr,
422 },
423 {"s15",
424 nullptr,
425 4,
426 0,
431 nullptr,
432 nullptr,
433 nullptr,
434 },
435 {"s16",
436 nullptr,
437 4,
438 0,
443 nullptr,
444 nullptr,
445 nullptr,
446 },
447 {"s17",
448 nullptr,
449 4,
450 0,
455 nullptr,
456 nullptr,
457 nullptr,
458 },
459 {"s18",
460 nullptr,
461 4,
462 0,
467 nullptr,
468 nullptr,
469 nullptr,
470 },
471 {"s19",
472 nullptr,
473 4,
474 0,
479 nullptr,
480 nullptr,
481 nullptr,
482 },
483 {"s20",
484 nullptr,
485 4,
486 0,
491 nullptr,
492 nullptr,
493 nullptr,
494 },
495 {"s21",
496 nullptr,
497 4,
498 0,
503 nullptr,
504 nullptr,
505 nullptr,
506 },
507 {"s22",
508 nullptr,
509 4,
510 0,
515 nullptr,
516 nullptr,
517 nullptr,
518 },
519 {"s23",
520 nullptr,
521 4,
522 0,
527 nullptr,
528 nullptr,
529 nullptr,
530 },
531 {"s24",
532 nullptr,
533 4,
534 0,
539 nullptr,
540 nullptr,
541 nullptr,
542 },
543 {"s25",
544 nullptr,
545 4,
546 0,
551 nullptr,
552 nullptr,
553 nullptr,
554 },
555 {"s26",
556 nullptr,
557 4,
558 0,
563 nullptr,
564 nullptr,
565 nullptr,
566 },
567 {"s27",
568 nullptr,
569 4,
570 0,
575 nullptr,
576 nullptr,
577 nullptr,
578 },
579 {"s28",
580 nullptr,
581 4,
582 0,
587 nullptr,
588 nullptr,
589 nullptr,
590 },
591 {"s29",
592 nullptr,
593 4,
594 0,
599 nullptr,
600 nullptr,
601 nullptr,
602 },
603 {"s30",
604 nullptr,
605 4,
606 0,
611 nullptr,
612 nullptr,
613 nullptr,
614 },
615 {"s31",
616 nullptr,
617 4,
618 0,
623 nullptr,
624 nullptr,
625 nullptr,
626 },
627 {"fpscr",
628 nullptr,
629 4,
630 0,
635 nullptr,
636 nullptr,
637 nullptr,
638 },
639 {"d0",
640 nullptr,
641 8,
642 0,
647 nullptr,
648 nullptr,
649 nullptr,
650 },
651 {"d1",
652 nullptr,
653 8,
654 0,
659 nullptr,
660 nullptr,
661 nullptr,
662 },
663 {"d2",
664 nullptr,
665 8,
666 0,
671 nullptr,
672 nullptr,
673 nullptr,
674 },
675 {"d3",
676 nullptr,
677 8,
678 0,
683 nullptr,
684 nullptr,
685 nullptr,
686 },
687 {"d4",
688 nullptr,
689 8,
690 0,
695 nullptr,
696 nullptr,
697 nullptr,
698 },
699 {"d5",
700 nullptr,
701 8,
702 0,
707 nullptr,
708 nullptr,
709 nullptr,
710 },
711 {"d6",
712 nullptr,
713 8,
714 0,
719 nullptr,
720 nullptr,
721 nullptr,
722 },
723 {"d7",
724 nullptr,
725 8,
726 0,
731 nullptr,
732 nullptr,
733 nullptr,
734 },
735 {"d8",
736 nullptr,
737 8,
738 0,
743 nullptr,
744 nullptr,
745 nullptr,
746 },
747 {"d9",
748 nullptr,
749 8,
750 0,
755 nullptr,
756 nullptr,
757 nullptr,
758 },
759 {"d10",
760 nullptr,
761 8,
762 0,
767 nullptr,
768 nullptr,
769 nullptr,
770 },
771 {"d11",
772 nullptr,
773 8,
774 0,
779 nullptr,
780 nullptr,
781 nullptr,
782 },
783 {"d12",
784 nullptr,
785 8,
786 0,
791 nullptr,
792 nullptr,
793 nullptr,
794 },
795 {"d13",
796 nullptr,
797 8,
798 0,
803 nullptr,
804 nullptr,
805 nullptr,
806 },
807 {"d14",
808 nullptr,
809 8,
810 0,
815 nullptr,
816 nullptr,
817 nullptr,
818 },
819 {"d15",
820 nullptr,
821 8,
822 0,
827 nullptr,
828 nullptr,
829 nullptr,
830 },
831 {"d16",
832 nullptr,
833 8,
834 0,
839 nullptr,
840 nullptr,
841 nullptr,
842 },
843 {"d17",
844 nullptr,
845 8,
846 0,
851 nullptr,
852 nullptr,
853 nullptr,
854 },
855 {"d18",
856 nullptr,
857 8,
858 0,
863 nullptr,
864 nullptr,
865 nullptr,
866 },
867 {"d19",
868 nullptr,
869 8,
870 0,
875 nullptr,
876 nullptr,
877 nullptr,
878 },
879 {"d20",
880 nullptr,
881 8,
882 0,
887 nullptr,
888 nullptr,
889 nullptr,
890 },
891 {"d21",
892 nullptr,
893 8,
894 0,
899 nullptr,
900 nullptr,
901 nullptr,
902 },
903 {"d22",
904 nullptr,
905 8,
906 0,
911 nullptr,
912 nullptr,
913 nullptr,
914 },
915 {"d23",
916 nullptr,
917 8,
918 0,
923 nullptr,
924 nullptr,
925 nullptr,
926 },
927 {"d24",
928 nullptr,
929 8,
930 0,
935 nullptr,
936 nullptr,
937 nullptr,
938 },
939 {"d25",
940 nullptr,
941 8,
942 0,
947 nullptr,
948 nullptr,
949 nullptr,
950 },
951 {"d26",
952 nullptr,
953 8,
954 0,
959 nullptr,
960 nullptr,
961 nullptr,
962 },
963 {"d27",
964 nullptr,
965 8,
966 0,
971 nullptr,
972 nullptr,
973 nullptr,
974 },
975 {"d28",
976 nullptr,
977 8,
978 0,
983 nullptr,
984 nullptr,
985 nullptr,
986 },
987 {"d29",
988 nullptr,
989 8,
990 0,
995 nullptr,
996 nullptr,
997 nullptr,
998 },
999 {"d30",
1000 nullptr,
1001 8,
1002 0,
1007 nullptr,
1008 nullptr,
1009 nullptr,
1010 },
1011 {"d31",
1012 nullptr,
1013 8,
1014 0,
1019 nullptr,
1020 nullptr,
1021 nullptr,
1022 },
1023 {"r8_usr",
1024 nullptr,
1025 4,
1026 0,
1028 eFormatHex,
1031 nullptr,
1032 nullptr,
1033 nullptr,
1034 },
1035 {"r9_usr",
1036 nullptr,
1037 4,
1038 0,
1040 eFormatHex,
1043 nullptr,
1044 nullptr,
1045 nullptr,
1046 },
1047 {"r10_usr",
1048 nullptr,
1049 4,
1050 0,
1052 eFormatHex,
1055 nullptr,
1056 nullptr,
1057 nullptr,
1058 },
1059 {"r11_usr",
1060 nullptr,
1061 4,
1062 0,
1064 eFormatHex,
1067 nullptr,
1068 nullptr,
1069 nullptr,
1070 },
1071 {"r12_usr",
1072 nullptr,
1073 4,
1074 0,
1076 eFormatHex,
1079 nullptr,
1080 nullptr,
1081 nullptr,
1082 },
1083 {"r13_usr",
1084 "sp_usr",
1085 4,
1086 0,
1088 eFormatHex,
1091 nullptr,
1092 nullptr,
1093 nullptr,
1094 },
1095 {"r14_usr",
1096 "lr_usr",
1097 4,
1098 0,
1100 eFormatHex,
1103 nullptr,
1104 nullptr,
1105 nullptr,
1106 },
1107 {"r8_fiq",
1108 nullptr,
1109 4,
1110 0,
1112 eFormatHex,
1115 nullptr,
1116 nullptr,
1117 nullptr,
1118 },
1119 {"r9_fiq",
1120 nullptr,
1121 4,
1122 0,
1124 eFormatHex,
1127 nullptr,
1128 nullptr,
1129 nullptr,
1130 },
1131 {"r10_fiq",
1132 nullptr,
1133 4,
1134 0,
1136 eFormatHex,
1139 nullptr,
1140 nullptr,
1141 nullptr,
1142 },
1143 {"r11_fiq",
1144 nullptr,
1145 4,
1146 0,
1148 eFormatHex,
1151 nullptr,
1152 nullptr,
1153 nullptr,
1154 },
1155 {"r12_fiq",
1156 nullptr,
1157 4,
1158 0,
1160 eFormatHex,
1163 nullptr,
1164 nullptr,
1165 nullptr,
1166 },
1167 {"r13_fiq",
1168 "sp_fiq",
1169 4,
1170 0,
1172 eFormatHex,
1175 nullptr,
1176 nullptr,
1177 nullptr,
1178 },
1179 {"r14_fiq",
1180 "lr_fiq",
1181 4,
1182 0,
1184 eFormatHex,
1187 nullptr,
1188 nullptr,
1189 nullptr,
1190 },
1191 {"r13_irq",
1192 "sp_irq",
1193 4,
1194 0,
1196 eFormatHex,
1199 nullptr,
1200 nullptr,
1201 nullptr,
1202 },
1203 {"r14_irq",
1204 "lr_irq",
1205 4,
1206 0,
1208 eFormatHex,
1211 nullptr,
1212 nullptr,
1213 nullptr,
1214 },
1215 {"r13_abt",
1216 "sp_abt",
1217 4,
1218 0,
1220 eFormatHex,
1223 nullptr,
1224 nullptr,
1225 nullptr,
1226 },
1227 {"r14_abt",
1228 "lr_abt",
1229 4,
1230 0,
1232 eFormatHex,
1235 nullptr,
1236 nullptr,
1237 nullptr,
1238 },
1239 {"r13_und",
1240 "sp_und",
1241 4,
1242 0,
1244 eFormatHex,
1247 nullptr,
1248 nullptr,
1249 nullptr,
1250 },
1251 {"r14_und",
1252 "lr_und",
1253 4,
1254 0,
1256 eFormatHex,
1259 nullptr,
1260 nullptr,
1261 nullptr,
1262 },
1263 {"r13_svc",
1264 "sp_svc",
1265 4,
1266 0,
1268 eFormatHex,
1271 nullptr,
1272 nullptr,
1273 nullptr,
1274 },
1275 {"r14_svc",
1276 "lr_svc",
1277 4,
1278 0,
1280 eFormatHex,
1283 nullptr,
1284 nullptr,
1285 nullptr,
1286 }};
1287
1288static const uint32_t k_num_register_infos = std::size(g_register_infos);
1289
1292 count = k_num_register_infos;
1293 return g_register_infos;
1294}
1295
1296size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; }
1297
1298// Static Functions
1299
1300ABISP
1302 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1303 const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1304
1305 if (vendor_type == llvm::Triple::Apple) {
1306 if ((arch_type == llvm::Triple::arm) ||
1307 (arch_type == llvm::Triple::thumb)) {
1308 return ABISP(
1309 new ABIMacOSX_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1310 }
1311 }
1312
1313 return ABISP();
1314}
1315
1317 addr_t function_addr, addr_t return_addr,
1318 llvm::ArrayRef<addr_t> args) const {
1319 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1320 if (!reg_ctx)
1321 return false;
1322
1323 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1325 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1327 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1329
1330 RegisterValue reg_value;
1331
1332 const char *reg_names[] = {"r0", "r1", "r2", "r3"};
1333
1334 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1335
1336 for (size_t i = 0; i < std::size(reg_names); ++i) {
1337 if (ai == ae)
1338 break;
1339
1340 reg_value.SetUInt32(*ai);
1341 if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName(reg_names[i]),
1342 reg_value))
1343 return false;
1344
1345 ++ai;
1346 }
1347
1348 if (ai != ae) {
1349 // Spill onto the stack
1350 size_t num_stack_regs = ae - ai;
1351
1352 sp -= (num_stack_regs * 4);
1353 // Keep the stack 16 byte aligned
1354 sp &= ~(16ull - 1ull);
1355
1356 // just using arg1 to get the right size
1357 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1359
1360 addr_t arg_pos = sp;
1361
1362 for (; ai != ae; ++ai) {
1363 reg_value.SetUInt32(*ai);
1364 if (reg_ctx
1365 ->WriteRegisterValueToMemory(reg_info, arg_pos,
1366 reg_info->byte_size, reg_value)
1367 .Fail())
1368 return false;
1369 arg_pos += reg_info->byte_size;
1370 }
1371 }
1372
1373 TargetSP target_sp(thread.CalculateTarget());
1374 Address so_addr;
1375
1376 // Figure out if our return address is ARM or Thumb by using the
1377 // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1378 // thumb-ness and set the correct address bits for us.
1379 so_addr.SetLoadAddress(return_addr, target_sp.get());
1380 return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1381
1382 // Set "lr" to the return address
1383 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
1384 return false;
1385
1386 // If bit zero or 1 is set, this must be a thumb function, no need to figure
1387 // this out from the symbols.
1388 so_addr.SetLoadAddress(function_addr, target_sp.get());
1389 function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1390
1391 const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
1392 const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
1393
1394 // Make a new CPSR and mask out any Thumb IT (if/then) bits
1395 uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1396 // If bit zero or 1 is set, this must be thumb...
1397 if (function_addr & 1ull)
1398 new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1399 else
1400 new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1401
1402 if (new_cpsr != curr_cpsr) {
1403 if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1404 return false;
1405 }
1406
1407 function_addr &=
1408 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1409
1410 // Update the sp - stack pointer - to be aligned to 16-bytes
1411 sp &= ~(0xfull);
1412 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1413 return false;
1414
1415 // Set "pc" to the address requested
1416 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr))
1417 return false;
1418
1419 return true;
1420}
1421
1423 uint32_t num_values = values.GetSize();
1424
1425 ExecutionContext exe_ctx(thread.shared_from_this());
1426 // For now, assume that the types in the AST values come from the Target's
1427 // scratch AST.
1428
1429 // Extract the register context so we can read arguments from registers
1430
1431 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1432
1433 if (!reg_ctx)
1434 return false;
1435
1436 addr_t sp = 0;
1437
1438 for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1439 // We currently only support extracting values with Clang QualTypes. Do we
1440 // care about others?
1441 Value *value = values.GetValueAtIndex(value_idx);
1442
1443 if (!value)
1444 return false;
1445
1446 CompilerType compiler_type = value->GetCompilerType();
1447 if (compiler_type) {
1448 bool is_signed = false;
1449 size_t bit_width = 0;
1450 std::optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
1451 if (!bit_size)
1452 return false;
1453 if (compiler_type.IsIntegerOrEnumerationType(is_signed))
1454 bit_width = *bit_size;
1455 else if (compiler_type.IsPointerOrReferenceType())
1456 bit_width = *bit_size;
1457 else
1458 // We only handle integer, pointer and reference types currently...
1459 return false;
1460
1461 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1462 if (value_idx < 4) {
1463 // Arguments 1-4 are in r0-r3...
1464 const RegisterInfo *arg_reg_info = nullptr;
1465 // Search by generic ID first, then fall back to by name
1466 uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1468 if (arg_reg_num != LLDB_INVALID_REGNUM) {
1469 arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
1470 } else {
1471 switch (value_idx) {
1472 case 0:
1473 arg_reg_info = reg_ctx->GetRegisterInfoByName("r0");
1474 break;
1475 case 1:
1476 arg_reg_info = reg_ctx->GetRegisterInfoByName("r1");
1477 break;
1478 case 2:
1479 arg_reg_info = reg_ctx->GetRegisterInfoByName("r2");
1480 break;
1481 case 3:
1482 arg_reg_info = reg_ctx->GetRegisterInfoByName("r3");
1483 break;
1484 }
1485 }
1486
1487 if (arg_reg_info) {
1488 RegisterValue reg_value;
1489
1490 if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1491 if (is_signed)
1492 reg_value.SignExtend(bit_width);
1493 if (!reg_value.GetScalarValue(value->GetScalar()))
1494 return false;
1495 continue;
1496 }
1497 }
1498 return false;
1499 } else {
1500 if (sp == 0) {
1501 // Read the stack pointer if it already hasn't been read
1502 sp = reg_ctx->GetSP(0);
1503 if (sp == 0)
1504 return false;
1505 }
1506
1507 // Arguments 5 on up are on the stack
1508 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1509 Status error;
1511 sp, arg_byte_size, is_signed, value->GetScalar(), error))
1512 return false;
1513
1514 sp += arg_byte_size;
1515 }
1516 }
1517 }
1518 }
1519 return true;
1520}
1521
1523 bool is_armv7k = false;
1524 ProcessSP process_sp(GetProcessSP());
1525 if (process_sp) {
1526 const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1527 const ArchSpec::Core system_core = arch.GetCore();
1528 if (system_core == ArchSpec::eCore_arm_armv7k) {
1529 is_armv7k = true;
1530 }
1531 }
1532 return is_armv7k;
1533}
1534
1536 Thread &thread, lldb_private::CompilerType &compiler_type) const {
1537 Value value;
1538 ValueObjectSP return_valobj_sp;
1539
1540 if (!compiler_type)
1541 return return_valobj_sp;
1542
1543 value.SetCompilerType(compiler_type);
1544
1545 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1546 if (!reg_ctx)
1547 return return_valobj_sp;
1548
1549 bool is_signed;
1550
1551 // Get the pointer to the first stack argument so we have a place to start
1552 // when reading data
1553
1554 const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
1555 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1556 std::optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
1557 if (!bit_width)
1558 return return_valobj_sp;
1559
1560 switch (*bit_width) {
1561 default:
1562 return return_valobj_sp;
1563 case 128:
1564 if (IsArmv7kProcess()) {
1565 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1566 // format is as if the result had been stored in memory at a word-
1567 // aligned address and then loaded into r0-r3 with an ldm instruction"
1568 {
1569 const RegisterInfo *r1_reg_info =
1570 reg_ctx->GetRegisterInfoByName("r1", 0);
1571 const RegisterInfo *r2_reg_info =
1572 reg_ctx->GetRegisterInfoByName("r2", 0);
1573 const RegisterInfo *r3_reg_info =
1574 reg_ctx->GetRegisterInfoByName("r3", 0);
1575 if (r1_reg_info && r2_reg_info && r3_reg_info) {
1576 std::optional<uint64_t> byte_size =
1577 compiler_type.GetByteSize(&thread);
1578 if (!byte_size)
1579 return return_valobj_sp;
1580 ProcessSP process_sp(thread.GetProcess());
1581 if (*byte_size <= r0_reg_info->byte_size + r1_reg_info->byte_size +
1582 r2_reg_info->byte_size +
1583 r3_reg_info->byte_size &&
1584 process_sp) {
1585 std::unique_ptr<DataBufferHeap> heap_data_up(
1586 new DataBufferHeap(*byte_size, 0));
1587 const ByteOrder byte_order = process_sp->GetByteOrder();
1588 RegisterValue r0_reg_value;
1589 RegisterValue r1_reg_value;
1590 RegisterValue r2_reg_value;
1591 RegisterValue r3_reg_value;
1592 if (reg_ctx->ReadRegister(r0_reg_info, r0_reg_value) &&
1593 reg_ctx->ReadRegister(r1_reg_info, r1_reg_value) &&
1594 reg_ctx->ReadRegister(r2_reg_info, r2_reg_value) &&
1595 reg_ctx->ReadRegister(r3_reg_info, r3_reg_value)) {
1596 Status error;
1597 if (r0_reg_value.GetAsMemoryData(*r0_reg_info,
1598 heap_data_up->GetBytes() + 0,
1599 4, byte_order, error) &&
1600 r1_reg_value.GetAsMemoryData(*r1_reg_info,
1601 heap_data_up->GetBytes() + 4,
1602 4, byte_order, error) &&
1603 r2_reg_value.GetAsMemoryData(*r2_reg_info,
1604 heap_data_up->GetBytes() + 8,
1605 4, byte_order, error) &&
1606 r3_reg_value.GetAsMemoryData(*r3_reg_info,
1607 heap_data_up->GetBytes() + 12,
1608 4, byte_order, error)) {
1609 DataExtractor data(DataBufferSP(heap_data_up.release()),
1610 byte_order,
1611 process_sp->GetAddressByteSize());
1612
1613 return_valobj_sp = ValueObjectConstResult::Create(
1614 &thread, compiler_type, ConstString(""), data);
1615 return return_valobj_sp;
1616 }
1617 }
1618 }
1619 }
1620 }
1621 } else {
1622 return return_valobj_sp;
1623 }
1624 break;
1625 case 64: {
1626 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
1627 uint64_t raw_value;
1628 raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1629 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1630 UINT32_MAX))
1631 << 32;
1632 if (is_signed)
1633 value.GetScalar() = (int64_t)raw_value;
1634 else
1635 value.GetScalar() = (uint64_t)raw_value;
1636 } break;
1637 case 32:
1638 if (is_signed)
1639 value.GetScalar() = (int32_t)(
1640 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1641 else
1642 value.GetScalar() = (uint32_t)(
1643 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1644 break;
1645 case 16:
1646 if (is_signed)
1647 value.GetScalar() = (int16_t)(
1648 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1649 else
1650 value.GetScalar() = (uint16_t)(
1651 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1652 break;
1653 case 8:
1654 if (is_signed)
1655 value.GetScalar() = (int8_t)(
1656 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1657 else
1658 value.GetScalar() = (uint8_t)(
1659 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1660 break;
1661 }
1662 } else if (compiler_type.IsPointerType()) {
1663 uint32_t ptr =
1664 thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1665 UINT32_MAX;
1666 value.GetScalar() = ptr;
1667 } else {
1668 // not handled yet
1669 return return_valobj_sp;
1670 }
1671
1672 // If we get here, we have a valid Value, so make our ValueObject out of it:
1673
1674 return_valobj_sp = ValueObjectConstResult::Create(
1675 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1676 return return_valobj_sp;
1677}
1678
1680 lldb::ValueObjectSP &new_value_sp) {
1681 Status error;
1682 if (!new_value_sp) {
1683 error = Status::FromErrorString("Empty value object for return value.");
1684 return error;
1685 }
1686
1687 CompilerType compiler_type = new_value_sp->GetCompilerType();
1688 if (!compiler_type) {
1689 error = Status::FromErrorString("Null clang type for return value.");
1690 return error;
1691 }
1692
1693 Thread *thread = frame_sp->GetThread().get();
1694
1695 bool is_signed;
1696 uint32_t count;
1697 bool is_complex;
1698
1699 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1700
1701 bool set_it_simple = false;
1702 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1703 compiler_type.IsPointerType()) {
1704 DataExtractor data;
1705 Status data_error;
1706 size_t num_bytes = new_value_sp->GetData(data, data_error);
1707 if (data_error.Fail()) {
1709 "Couldn't convert return value to raw data: %s",
1710 data_error.AsCString());
1711 return error;
1712 }
1713 lldb::offset_t offset = 0;
1714 if (num_bytes <= 8) {
1715 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
1716 if (num_bytes <= 4) {
1717 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1718
1719 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1720 set_it_simple = true;
1721 } else {
1722 uint32_t raw_value = data.GetMaxU32(&offset, 4);
1723
1724 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1725 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
1726 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1727
1728 if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1729 set_it_simple = true;
1730 }
1731 }
1732 } else if (num_bytes <= 16 && IsArmv7kProcess()) {
1733 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1734 // format is as if the result had been stored in memory at a word-aligned
1735 // address and then loaded into r0-r3 with an ldm instruction"
1736
1737 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
1738 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
1739 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
1740 const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
1741 lldb::offset_t offset = 0;
1742 uint32_t bytes_written = 4;
1743 uint32_t raw_value = data.GetMaxU64(&offset, 4);
1744 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value) &&
1745 bytes_written <= num_bytes) {
1746 bytes_written += 4;
1747 raw_value = data.GetMaxU64(&offset, 4);
1748 if (bytes_written <= num_bytes &&
1749 reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value)) {
1750 bytes_written += 4;
1751 raw_value = data.GetMaxU64(&offset, 4);
1752 if (bytes_written <= num_bytes &&
1753 reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
1754 bytes_written += 4;
1755 raw_value = data.GetMaxU64(&offset, 4);
1756 if (bytes_written <= num_bytes &&
1757 reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) {
1758 set_it_simple = true;
1759 }
1760 }
1761 }
1762 }
1763 } else {
1765 "We don't support returning longer than 64 bit "
1766 "integer values at present.");
1767 }
1768 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1769 if (is_complex)
1771 "We don't support returning complex values at present");
1772 else
1774 "We don't support returning float values at present");
1775 }
1776
1777 if (!set_it_simple)
1779 "We only support setting simple integer return types at present.");
1780
1781 return error;
1782}
1783
1785 unwind_plan.Clear();
1787
1788 uint32_t lr_reg_num = dwarf_lr;
1789 uint32_t sp_reg_num = dwarf_sp;
1790 uint32_t pc_reg_num = dwarf_pc;
1791
1793
1794 // Our Call Frame Address is the stack pointer value
1795 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1796
1797 // The previous PC is in the LR
1798 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1799 unwind_plan.AppendRow(row);
1800
1801 // All other registers are the same.
1802
1803 unwind_plan.SetSourceName("arm at-func-entry default");
1805
1806 return true;
1807}
1808
1810 unwind_plan.Clear();
1812
1813 uint32_t fp_reg_num =
1814 dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11
1815 uint32_t pc_reg_num = dwarf_pc;
1816
1818 const int32_t ptr_size = 4;
1819
1820 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1821 row->SetOffset(0);
1822 row->SetUnspecifiedRegistersAreUndefined(true);
1823
1824 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1825 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1826
1827 unwind_plan.AppendRow(row);
1828 unwind_plan.SetSourceName("arm-apple-ios default unwind plan");
1832
1833 return true;
1834}
1835
1836// cf. "ARMv6 Function Calling Conventions"
1837// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
1838// and "ARMv7 Function Calling Conventions"
1839// https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv7FunctionCallingConventions.html
1840
1841// ARMv7 on iOS general purpose reg rules:
1842// r0-r3 not preserved (used for argument passing)
1843// r4-r6 preserved
1844// r7 preserved (frame pointer)
1845// r8 preserved
1846// r9 not preserved (usable as volatile scratch register with iOS 3.x and
1847// later)
1848// r10-r11 preserved
1849// r12 not presrved
1850// r13 preserved (stack pointer)
1851// r14 not preserved (link register)
1852// r15 preserved (pc)
1853// cpsr not preserved (different rules for different bits)
1854
1855// ARMv7 on iOS floating point rules:
1856// d0-d7 not preserved (aka s0-s15, q0-q3)
1857// d8-d15 preserved (aka s16-s31, q4-q7)
1858// d16-d31 not preserved (aka q8-q15)
1859
1861 if (reg_info) {
1862 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1863 const char *name = reg_info->name;
1864 if (name[0] == 'r') {
1865 switch (name[1]) {
1866 case '0':
1867 return name[2] == '\0'; // r0
1868 case '1':
1869 switch (name[2]) {
1870 case '\0':
1871 return true; // r1
1872 case '2':
1873 case '3':
1874 return name[3] == '\0'; // r12, r13 (sp)
1875 default:
1876 break;
1877 }
1878 break;
1879
1880 case '2':
1881 return name[2] == '\0'; // r2
1882 case '3':
1883 return name[2] == '\0'; // r3
1884 case '9':
1885 return name[2] == '\0'; // r9 (apple-ios only...)
1886
1887 break;
1888 }
1889 } else if (name[0] == 'd') {
1890 switch (name[1]) {
1891 case '0':
1892 return name[2] == '\0'; // d0 is volatile
1893
1894 case '1':
1895 switch (name[2]) {
1896 case '\0':
1897 return true; // d1 is volatile
1898 case '6':
1899 case '7':
1900 case '8':
1901 case '9':
1902 return name[3] == '\0'; // d16 - d19 are volatile
1903 default:
1904 break;
1905 }
1906 break;
1907
1908 case '2':
1909 switch (name[2]) {
1910 case '\0':
1911 return true; // d2 is volatile
1912 case '0':
1913 case '1':
1914 case '2':
1915 case '3':
1916 case '4':
1917 case '5':
1918 case '6':
1919 case '7':
1920 case '8':
1921 case '9':
1922 return name[3] == '\0'; // d20 - d29 are volatile
1923 default:
1924 break;
1925 }
1926 break;
1927
1928 case '3':
1929 switch (name[2]) {
1930 case '\0':
1931 return true; // d3 is volatile
1932 case '0':
1933 case '1':
1934 return name[3] == '\0'; // d30 - d31 are volatile
1935 default:
1936 break;
1937 }
1938 break;
1939 case '4':
1940 case '5':
1941 case '6':
1942 case '7':
1943 return name[2] == '\0'; // d4 - d7 are volatile
1944
1945 default:
1946 break;
1947 }
1948 } else if (name[0] == 's') {
1949 switch (name[1]) {
1950 case '0':
1951 return name[2] == '\0'; // s0 is volatile
1952
1953 case '1':
1954 switch (name[2]) {
1955 case '\0':
1956 return true; // s1 is volatile
1957 case '0':
1958 case '1':
1959 case '2':
1960 case '3':
1961 case '4':
1962 case '5':
1963 return name[3] == '\0'; // s10 - s15 are volatile
1964 default:
1965 break;
1966 }
1967 break;
1968
1969 case '2':
1970 case '3':
1971 case '4':
1972 case '5':
1973 case '6':
1974 case '7':
1975 case '8':
1976 case '9':
1977 return name[2] == '\0'; // s2 - s9 are volatile
1978
1979 default:
1980 break;
1981 }
1982 } else if (name[0] == 'q') {
1983 switch (name[1]) {
1984 case '1':
1985 switch (name[2]) {
1986 case '\0':
1987 return true; // q1 is volatile
1988 case '0':
1989 case '1':
1990 case '2':
1991 case '3':
1992 case '4':
1993 case '5':
1994 return true; // q10-q15 are volatile
1995 default:
1996 break;
1997 };
1998 break;
1999 case '0':
2000 case '2':
2001 case '3':
2002 return name[2] == '\0'; // q0-q3 are volatile
2003 case '8':
2004 case '9':
2005 return name[2] == '\0'; // q8-q9 are volatile
2006 default:
2007 break;
2008 }
2009 } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2010 return true;
2011 }
2012 return false;
2013}
2014
2017 "Mac OS X ABI for arm targets", CreateInstance);
2018}
2019
2022}
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_sp
@ 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_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:234
lldb::ProcessSP GetProcessSP() const
Request to get a Process shared pointer.
Definition: ABI.h:96
A section + offset based address class.
Definition: Address.h:62
lldb::addr_t GetCallableLoadAddress(Target *target, bool is_indirect=false) const
Get the load address as a callable code load address.
Definition: Address.cpp:338
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
Definition: Address.cpp:1047
An architecture specification class.
Definition: ArchSpec.h:31
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:461
Core GetCore() const
Definition: ArchSpec.h:440
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:40
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:2375
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3615
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:115
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition: Status.cpp:106
static Status FromErrorString(const char *str)
Definition: Status.h:138
bool Fail() const
Test for error condition.
Definition: Status.cpp:270
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:195
virtual lldb::StackFrameSP GetStackFrameAtIndex(uint32_t idx)
Definition: Thread.h:408
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb::TargetSP CalculateTarget() override
Definition: Thread.cpp:1408
lldb::ProcessSP GetProcess() const
Definition: Thread.h:157
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
Definition: UnwindPlan.h:536
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:471
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:392
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:429
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:512
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:594
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:524
Value * GetValueAtIndex(size_t idx)
Definition: Value.cpp:691
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:268
const CompilerType & GetCompilerType()
Definition: Value.cpp:239
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:59
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:57
#define LLDB_REGNUM_GENERIC_ARG4
Definition: lldb-defines.h:67
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:65
#define LLDB_REGNUM_GENERIC_ARG1
Definition: lldb-defines.h:61
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:60
#define UINT32_MAX
Definition: lldb-defines.h:19
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:87
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:63
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:56
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:58
A class that represents a running process on the host machine.
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::ABI > ABISP
Definition: lldb-forward.h:317
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
Definition: lldb-forward.h:424
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Definition: lldb-forward.h:484
uint64_t offset_t
Definition: lldb-types.h:85
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:389
@ eEncodingIEEE754
float
@ eEncodingUint
unsigned integer
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
Definition: lldb-forward.h:336
uint64_t addr_t
Definition: lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:448
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindDWARF
the register numbers seen DWARF
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_size
Size in bytes of the register.
const char * name
Name of this register, can't be NULL.