LLDB mainline
ABISysV_arm.cpp
Go to the documentation of this file.
1//===-- ABISysV_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 "ABISysV_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
39
41 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
42 // DWARF GENERIC PROCESS PLUGIN
43 // LLDB NATIVE VALUE REGS INVALIDATE REGS
44 // ========== ======= == === ============= ============
45 // ======================= =================== ===========================
46 // ======================= ====================== ==========
47 // ===============
48 {"r0",
49 nullptr,
50 4,
51 0,
56 nullptr,
57 nullptr,
58 nullptr,
59 },
60 {"r1",
61 nullptr,
62 4,
63 0,
68 nullptr,
69 nullptr,
70 nullptr,
71 },
72 {"r2",
73 nullptr,
74 4,
75 0,
80 nullptr,
81 nullptr,
82 nullptr,
83 },
84 {"r3",
85 nullptr,
86 4,
87 0,
92 nullptr,
93 nullptr,
94 nullptr,
95 },
96 {"r4",
97 nullptr,
98 4,
99 0,
104 nullptr,
105 nullptr,
106 nullptr,
107 },
108 {"r5",
109 nullptr,
110 4,
111 0,
116 nullptr,
117 nullptr,
118 nullptr,
119 },
120 {"r6",
121 nullptr,
122 4,
123 0,
128 nullptr,
129 nullptr,
130 nullptr,
131 },
132 {"r7",
133 nullptr,
134 4,
135 0,
140 nullptr,
141 nullptr,
142 nullptr,
143 },
144 {"r8",
145 nullptr,
146 4,
147 0,
152 nullptr,
153 nullptr,
154 nullptr,
155 },
156 {"r9",
157 nullptr,
158 4,
159 0,
164 nullptr,
165 nullptr,
166 nullptr,
167 },
168 {"r10",
169 nullptr,
170 4,
171 0,
176 nullptr,
177 nullptr,
178 nullptr,
179 },
180 {"r11",
181 nullptr,
182 4,
183 0,
188 nullptr,
189 nullptr,
190 nullptr,
191 },
192 {"r12",
193 nullptr,
194 4,
195 0,
200 nullptr,
201 nullptr,
202 nullptr,
203 },
204 {"sp",
205 "r13",
206 4,
207 0,
212 nullptr,
213 nullptr,
214 nullptr,
215 },
216 {"lr",
217 "r14",
218 4,
219 0,
224 nullptr,
225 nullptr,
226 nullptr,
227 },
228 {"pc",
229 "r15",
230 4,
231 0,
236 nullptr,
237 nullptr,
238 nullptr,
239 },
240 {"cpsr",
241 "psr",
242 4,
243 0,
248 nullptr,
249 nullptr,
250 nullptr,
251 },
252 {"s0",
253 nullptr,
254 4,
255 0,
260 nullptr,
261 nullptr,
262 nullptr,
263 },
264 {"s1",
265 nullptr,
266 4,
267 0,
272 nullptr,
273 nullptr,
274 nullptr,
275 },
276 {"s2",
277 nullptr,
278 4,
279 0,
284 nullptr,
285 nullptr,
286 nullptr,
287 },
288 {"s3",
289 nullptr,
290 4,
291 0,
296 nullptr,
297 nullptr,
298 nullptr,
299 },
300 {"s4",
301 nullptr,
302 4,
303 0,
308 nullptr,
309 nullptr,
310 nullptr,
311 },
312 {"s5",
313 nullptr,
314 4,
315 0,
320 nullptr,
321 nullptr,
322 nullptr,
323 },
324 {"s6",
325 nullptr,
326 4,
327 0,
332 nullptr,
333 nullptr,
334 nullptr,
335 },
336 {"s7",
337 nullptr,
338 4,
339 0,
344 nullptr,
345 nullptr,
346 nullptr,
347 },
348 {"s8",
349 nullptr,
350 4,
351 0,
356 nullptr,
357 nullptr,
358 nullptr,
359 },
360 {"s9",
361 nullptr,
362 4,
363 0,
368 nullptr,
369 nullptr,
370 nullptr,
371 },
372 {"s10",
373 nullptr,
374 4,
375 0,
380 nullptr,
381 nullptr,
382 nullptr,
383 },
384 {"s11",
385 nullptr,
386 4,
387 0,
392 nullptr,
393 nullptr,
394 nullptr,
395 },
396 {"s12",
397 nullptr,
398 4,
399 0,
404 nullptr,
405 nullptr,
406 nullptr,
407 },
408 {"s13",
409 nullptr,
410 4,
411 0,
416 nullptr,
417 nullptr,
418 nullptr,
419 },
420 {"s14",
421 nullptr,
422 4,
423 0,
428 nullptr,
429 nullptr,
430 nullptr,
431 },
432 {"s15",
433 nullptr,
434 4,
435 0,
440 nullptr,
441 nullptr,
442 nullptr,
443 },
444 {"s16",
445 nullptr,
446 4,
447 0,
452 nullptr,
453 nullptr,
454 nullptr,
455 },
456 {"s17",
457 nullptr,
458 4,
459 0,
464 nullptr,
465 nullptr,
466 nullptr,
467 },
468 {"s18",
469 nullptr,
470 4,
471 0,
476 nullptr,
477 nullptr,
478 nullptr,
479 },
480 {"s19",
481 nullptr,
482 4,
483 0,
488 nullptr,
489 nullptr,
490 nullptr,
491 },
492 {"s20",
493 nullptr,
494 4,
495 0,
500 nullptr,
501 nullptr,
502 nullptr,
503 },
504 {"s21",
505 nullptr,
506 4,
507 0,
512 nullptr,
513 nullptr,
514 nullptr,
515 },
516 {"s22",
517 nullptr,
518 4,
519 0,
524 nullptr,
525 nullptr,
526 nullptr,
527 },
528 {"s23",
529 nullptr,
530 4,
531 0,
536 nullptr,
537 nullptr,
538 nullptr,
539 },
540 {"s24",
541 nullptr,
542 4,
543 0,
548 nullptr,
549 nullptr,
550 nullptr,
551 },
552 {"s25",
553 nullptr,
554 4,
555 0,
560 nullptr,
561 nullptr,
562 nullptr,
563 },
564 {"s26",
565 nullptr,
566 4,
567 0,
572 nullptr,
573 nullptr,
574 nullptr,
575 },
576 {"s27",
577 nullptr,
578 4,
579 0,
584 nullptr,
585 nullptr,
586 nullptr,
587 },
588 {"s28",
589 nullptr,
590 4,
591 0,
596 nullptr,
597 nullptr,
598 nullptr,
599 },
600 {"s29",
601 nullptr,
602 4,
603 0,
608 nullptr,
609 nullptr,
610 nullptr,
611 },
612 {"s30",
613 nullptr,
614 4,
615 0,
620 nullptr,
621 nullptr,
622 nullptr,
623 },
624 {"s31",
625 nullptr,
626 4,
627 0,
632 nullptr,
633 nullptr,
634 nullptr,
635 },
636 {"fpscr",
637 nullptr,
638 4,
639 0,
644 nullptr,
645 nullptr,
646 nullptr,
647 },
648 {"d0",
649 nullptr,
650 8,
651 0,
656 nullptr,
657 nullptr,
658 nullptr,
659 },
660 {"d1",
661 nullptr,
662 8,
663 0,
668 nullptr,
669 nullptr,
670 nullptr,
671 },
672 {"d2",
673 nullptr,
674 8,
675 0,
680 nullptr,
681 nullptr,
682 nullptr,
683 },
684 {"d3",
685 nullptr,
686 8,
687 0,
692 nullptr,
693 nullptr,
694 nullptr,
695 },
696 {"d4",
697 nullptr,
698 8,
699 0,
704 nullptr,
705 nullptr,
706 nullptr,
707 },
708 {"d5",
709 nullptr,
710 8,
711 0,
716 nullptr,
717 nullptr,
718 nullptr,
719 },
720 {"d6",
721 nullptr,
722 8,
723 0,
728 nullptr,
729 nullptr,
730 nullptr,
731 },
732 {"d7",
733 nullptr,
734 8,
735 0,
740 nullptr,
741 nullptr,
742 nullptr,
743 },
744 {"d8",
745 nullptr,
746 8,
747 0,
752 nullptr,
753 nullptr,
754 nullptr,
755 },
756 {"d9",
757 nullptr,
758 8,
759 0,
764 nullptr,
765 nullptr,
766 nullptr,
767 },
768 {"d10",
769 nullptr,
770 8,
771 0,
776 nullptr,
777 nullptr,
778 nullptr,
779 },
780 {"d11",
781 nullptr,
782 8,
783 0,
788 nullptr,
789 nullptr,
790 nullptr,
791 },
792 {"d12",
793 nullptr,
794 8,
795 0,
800 nullptr,
801 nullptr,
802 nullptr,
803 },
804 {"d13",
805 nullptr,
806 8,
807 0,
812 nullptr,
813 nullptr,
814 nullptr,
815 },
816 {"d14",
817 nullptr,
818 8,
819 0,
824 nullptr,
825 nullptr,
826 nullptr,
827 },
828 {"d15",
829 nullptr,
830 8,
831 0,
836 nullptr,
837 nullptr,
838 nullptr,
839 },
840 {"d16",
841 nullptr,
842 8,
843 0,
848 nullptr,
849 nullptr,
850 nullptr,
851 },
852 {"d17",
853 nullptr,
854 8,
855 0,
860 nullptr,
861 nullptr,
862 nullptr,
863 },
864 {"d18",
865 nullptr,
866 8,
867 0,
872 nullptr,
873 nullptr,
874 nullptr,
875 },
876 {"d19",
877 nullptr,
878 8,
879 0,
884 nullptr,
885 nullptr,
886 nullptr,
887 },
888 {"d20",
889 nullptr,
890 8,
891 0,
896 nullptr,
897 nullptr,
898 nullptr,
899 },
900 {"d21",
901 nullptr,
902 8,
903 0,
908 nullptr,
909 nullptr,
910 nullptr,
911 },
912 {"d22",
913 nullptr,
914 8,
915 0,
920 nullptr,
921 nullptr,
922 nullptr,
923 },
924 {"d23",
925 nullptr,
926 8,
927 0,
932 nullptr,
933 nullptr,
934 nullptr,
935 },
936 {"d24",
937 nullptr,
938 8,
939 0,
944 nullptr,
945 nullptr,
946 nullptr,
947 },
948 {"d25",
949 nullptr,
950 8,
951 0,
956 nullptr,
957 nullptr,
958 nullptr,
959 },
960 {"d26",
961 nullptr,
962 8,
963 0,
968 nullptr,
969 nullptr,
970 nullptr,
971 },
972 {"d27",
973 nullptr,
974 8,
975 0,
980 nullptr,
981 nullptr,
982 nullptr,
983 },
984 {"d28",
985 nullptr,
986 8,
987 0,
992 nullptr,
993 nullptr,
994 nullptr,
995 },
996 {"d29",
997 nullptr,
998 8,
999 0,
1004 nullptr,
1005 nullptr,
1006 nullptr,
1007 },
1008 {"d30",
1009 nullptr,
1010 8,
1011 0,
1016 nullptr,
1017 nullptr,
1018 nullptr,
1019 },
1020 {"d31",
1021 nullptr,
1022 8,
1023 0,
1028 nullptr,
1029 nullptr,
1030 nullptr,
1031 },
1032 {"r8_usr",
1033 nullptr,
1034 4,
1035 0,
1037 eFormatHex,
1040 nullptr,
1041 nullptr,
1042 nullptr,
1043 },
1044 {"r9_usr",
1045 nullptr,
1046 4,
1047 0,
1049 eFormatHex,
1052 nullptr,
1053 nullptr,
1054 nullptr,
1055 },
1056 {"r10_usr",
1057 nullptr,
1058 4,
1059 0,
1061 eFormatHex,
1064 nullptr,
1065 nullptr,
1066 nullptr,
1067 },
1068 {"r11_usr",
1069 nullptr,
1070 4,
1071 0,
1073 eFormatHex,
1076 nullptr,
1077 nullptr,
1078 nullptr,
1079 },
1080 {"r12_usr",
1081 nullptr,
1082 4,
1083 0,
1085 eFormatHex,
1088 nullptr,
1089 nullptr,
1090 nullptr,
1091 },
1092 {"r13_usr",
1093 "sp_usr",
1094 4,
1095 0,
1097 eFormatHex,
1100 nullptr,
1101 nullptr,
1102 nullptr,
1103 },
1104 {"r14_usr",
1105 "lr_usr",
1106 4,
1107 0,
1109 eFormatHex,
1112 nullptr,
1113 nullptr,
1114 nullptr,
1115 },
1116 {"r8_fiq",
1117 nullptr,
1118 4,
1119 0,
1121 eFormatHex,
1124 nullptr,
1125 nullptr,
1126 nullptr,
1127 },
1128 {"r9_fiq",
1129 nullptr,
1130 4,
1131 0,
1133 eFormatHex,
1136 nullptr,
1137 nullptr,
1138 nullptr,
1139 },
1140 {"r10_fiq",
1141 nullptr,
1142 4,
1143 0,
1145 eFormatHex,
1148 nullptr,
1149 nullptr,
1150 nullptr,
1151 },
1152 {"r11_fiq",
1153 nullptr,
1154 4,
1155 0,
1157 eFormatHex,
1160 nullptr,
1161 nullptr,
1162 nullptr,
1163 },
1164 {"r12_fiq",
1165 nullptr,
1166 4,
1167 0,
1169 eFormatHex,
1172 nullptr,
1173 nullptr,
1174 nullptr,
1175 },
1176 {"r13_fiq",
1177 "sp_fiq",
1178 4,
1179 0,
1181 eFormatHex,
1184 nullptr,
1185 nullptr,
1186 nullptr,
1187 },
1188 {"r14_fiq",
1189 "lr_fiq",
1190 4,
1191 0,
1193 eFormatHex,
1196 nullptr,
1197 nullptr,
1198 nullptr,
1199 },
1200 {"r13_irq",
1201 "sp_irq",
1202 4,
1203 0,
1205 eFormatHex,
1208 nullptr,
1209 nullptr,
1210 nullptr,
1211 },
1212 {"r14_irq",
1213 "lr_irq",
1214 4,
1215 0,
1217 eFormatHex,
1220 nullptr,
1221 nullptr,
1222 nullptr,
1223 },
1224 {"r13_abt",
1225 "sp_abt",
1226 4,
1227 0,
1229 eFormatHex,
1232 nullptr,
1233 nullptr,
1234 nullptr,
1235 },
1236 {"r14_abt",
1237 "lr_abt",
1238 4,
1239 0,
1241 eFormatHex,
1244 nullptr,
1245 nullptr,
1246 nullptr,
1247 },
1248 {"r13_und",
1249 "sp_und",
1250 4,
1251 0,
1253 eFormatHex,
1256 nullptr,
1257 nullptr,
1258 nullptr,
1259 },
1260 {"r14_und",
1261 "lr_und",
1262 4,
1263 0,
1265 eFormatHex,
1268 nullptr,
1269 nullptr,
1270 nullptr,
1271
1272 },
1273 {"r13_svc",
1274 "sp_svc",
1275 4,
1276 0,
1278 eFormatHex,
1281 nullptr,
1282 nullptr,
1283 nullptr,
1284 },
1285 {"r14_svc",
1286 "lr_svc",
1287 4,
1288 0,
1290 eFormatHex,
1293 nullptr,
1294 nullptr,
1295 nullptr,
1296 }};
1297
1298static const uint32_t k_num_register_infos = std::size(g_register_infos);
1299
1302 count = k_num_register_infos;
1303 return g_register_infos;
1304}
1305
1306size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
1307
1308// Static Functions
1309
1310ABISP
1312 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1313 const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1314
1315 if (vendor_type != llvm::Triple::Apple) {
1316 if ((arch_type == llvm::Triple::arm) ||
1317 (arch_type == llvm::Triple::thumb)) {
1318 return ABISP(
1319 new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1320 }
1321 }
1322
1323 return ABISP();
1324}
1325
1327 addr_t function_addr, addr_t return_addr,
1328 llvm::ArrayRef<addr_t> args) const {
1329 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1330 if (!reg_ctx)
1331 return false;
1332
1333 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1335 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1337 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1339
1340 RegisterValue reg_value;
1341
1342 const uint8_t reg_names[] = {
1345
1346 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1347
1348 for (size_t i = 0; i < std::size(reg_names); ++i) {
1349 if (ai == ae)
1350 break;
1351
1352 reg_value.SetUInt32(*ai);
1353 if (!reg_ctx->WriteRegister(
1354 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]),
1355 reg_value))
1356 return false;
1357
1358 ++ai;
1359 }
1360
1361 if (ai != ae) {
1362 // Spill onto the stack
1363 size_t num_stack_regs = ae - ai;
1364
1365 sp -= (num_stack_regs * 4);
1366 // Keep the stack 8 byte aligned, not that we need to
1367 sp &= ~(8ull - 1ull);
1368
1369 // just using arg1 to get the right size
1370 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1372
1373 addr_t arg_pos = sp;
1374
1375 for (; ai != ae; ++ai) {
1376 reg_value.SetUInt32(*ai);
1377 if (reg_ctx
1378 ->WriteRegisterValueToMemory(reg_info, arg_pos,
1379 reg_info->byte_size, reg_value)
1380 .Fail())
1381 return false;
1382 arg_pos += reg_info->byte_size;
1383 }
1384 }
1385
1386 TargetSP target_sp(thread.CalculateTarget());
1387 Address so_addr;
1388
1389 // Figure out if our return address is ARM or Thumb by using the
1390 // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1391 // thumb-ness and set the correct address bits for us.
1392 so_addr.SetLoadAddress(return_addr, target_sp.get());
1393 return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1394
1395 // Set "lr" to the return address
1396 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
1397 return false;
1398
1399 // Set "sp" to the requested value
1400 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1401 return false;
1402
1403 // If bit zero or 1 is set, this must be a thumb function, no need to figure
1404 // this out from the symbols.
1405 so_addr.SetLoadAddress(function_addr, target_sp.get());
1406 function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1407
1408 const RegisterInfo *cpsr_reg_info =
1410 const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
1411
1412 // Make a new CPSR and mask out any Thumb IT (if/then) bits
1413 uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1414 // If bit zero or 1 is set, this must be thumb...
1415 if (function_addr & 1ull)
1416 new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1417 else
1418 new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1419
1420 if (new_cpsr != curr_cpsr) {
1421 if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1422 return false;
1423 }
1424
1425 function_addr &=
1426 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1427
1428 // Set "pc" to the address requested
1429 return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr);
1430}
1431
1433 uint32_t num_values = values.GetSize();
1434
1435 ExecutionContext exe_ctx(thread.shared_from_this());
1436 // For now, assume that the types in the AST values come from the Target's
1437 // scratch AST.
1438
1439 // Extract the register context so we can read arguments from registers
1440
1441 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1442
1443 if (!reg_ctx)
1444 return false;
1445
1446 addr_t sp = 0;
1447
1448 for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1449 // We currently only support extracting values with Clang QualTypes. Do we
1450 // care about others?
1451 Value *value = values.GetValueAtIndex(value_idx);
1452
1453 if (!value)
1454 return false;
1455
1456 CompilerType compiler_type = value->GetCompilerType();
1457 if (compiler_type) {
1458 bool is_signed = false;
1459 size_t bit_width = 0;
1460 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1461 compiler_type.IsPointerOrReferenceType()) {
1462 if (std::optional<uint64_t> size = compiler_type.GetBitSize(&thread))
1463 bit_width = *size;
1464 } else {
1465 // We only handle integer, pointer and reference types currently...
1466 return false;
1467 }
1468
1469 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1470 if (value_idx < 4) {
1471 // Arguments 1-4 are in r0-r3...
1472 const RegisterInfo *arg_reg_info = nullptr;
1473 arg_reg_info = reg_ctx->GetRegisterInfo(
1475 if (arg_reg_info) {
1476 RegisterValue reg_value;
1477
1478 if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1479 if (is_signed)
1480 reg_value.SignExtend(bit_width);
1481 if (!reg_value.GetScalarValue(value->GetScalar()))
1482 return false;
1483 continue;
1484 }
1485 }
1486 return false;
1487 } else {
1488 if (sp == 0) {
1489 // Read the stack pointer if it already hasn't been read
1490 sp = reg_ctx->GetSP(0);
1491 if (sp == 0)
1492 return false;
1493 }
1494
1495 // Arguments 5 on up are on the stack
1496 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1497 Status error;
1499 sp, arg_byte_size, is_signed, value->GetScalar(), error))
1500 return false;
1501
1502 sp += arg_byte_size;
1503 }
1504 }
1505 }
1506 }
1507 return true;
1508}
1509
1511 RegisterContext *reg_ctx,
1512 size_t byte_size, Value &value) {
1513 Status error;
1514 DataBufferHeap buffer(byte_size, 0);
1515
1516 const RegisterInfo *r0_reg_info =
1518 uint32_t address =
1519 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1520 thread.GetProcess()->ReadMemory(address, buffer.GetBytes(),
1521 buffer.GetByteSize(), error);
1522
1523 if (error.Fail())
1524 return false;
1525
1526 value.SetBytes(buffer.GetBytes(), buffer.GetByteSize());
1527 return true;
1528}
1529
1531 ProcessSP process_sp(thread.GetProcess());
1532 if (process_sp) {
1533 const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1534
1535 return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
1536 }
1537
1538 return false;
1539}
1540
1542 Thread &thread, lldb_private::CompilerType &compiler_type) const {
1543 Value value;
1544 ValueObjectSP return_valobj_sp;
1545
1546 if (!compiler_type)
1547 return return_valobj_sp;
1548
1549 // value.SetContext (Value::eContextTypeClangType,
1550 // compiler_type.GetOpaqueQualType());
1551 value.SetCompilerType(compiler_type);
1552
1553 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1554 if (!reg_ctx)
1555 return return_valobj_sp;
1556
1557 bool is_signed;
1558 bool is_complex;
1559 uint32_t float_count;
1560 bool is_vfp_candidate = false;
1561 uint8_t vfp_count = 0;
1562 uint8_t vfp_byte_size = 0;
1563
1564 // Get the pointer to the first stack argument so we have a place to start
1565 // when reading data
1566
1567 const RegisterInfo *r0_reg_info =
1569 std::optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
1570 std::optional<uint64_t> byte_size = compiler_type.GetByteSize(&thread);
1571 if (!bit_width || !byte_size)
1572 return return_valobj_sp;
1573
1574 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1575 switch (*bit_width) {
1576 default:
1577 return return_valobj_sp;
1578 case 64: {
1579 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1581 uint64_t raw_value;
1582 raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1583 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1584 UINT32_MAX))
1585 << 32;
1586 if (is_signed)
1587 value.GetScalar() = (int64_t)raw_value;
1588 else
1589 value.GetScalar() = (uint64_t)raw_value;
1590 } break;
1591 case 32:
1592 if (is_signed)
1593 value.GetScalar() = (int32_t)(
1594 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1595 else
1596 value.GetScalar() = (uint32_t)(
1597 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1598 break;
1599 case 16:
1600 if (is_signed)
1601 value.GetScalar() = (int16_t)(
1602 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1603 else
1604 value.GetScalar() = (uint16_t)(
1605 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1606 break;
1607 case 8:
1608 if (is_signed)
1609 value.GetScalar() = (int8_t)(
1610 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1611 else
1612 value.GetScalar() = (uint8_t)(
1613 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1614 break;
1615 }
1616 } else if (compiler_type.IsPointerType()) {
1617 uint32_t ptr =
1618 thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1619 UINT32_MAX;
1620 value.GetScalar() = ptr;
1621 } else if (compiler_type.IsVectorType()) {
1622 if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
1623 is_vfp_candidate = true;
1624 vfp_byte_size = 8;
1625 vfp_count = (*byte_size == 8 ? 1 : 2);
1626 } else if (*byte_size <= 16) {
1627 DataBufferHeap buffer(16, 0);
1628 uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes();
1629
1630 for (uint32_t i = 0; 4 * i < *byte_size; ++i) {
1631 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1633 buffer_ptr[i] =
1634 reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX;
1635 }
1636 value.SetBytes(buffer.GetBytes(), *byte_size);
1637 } else {
1638 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1639 return return_valobj_sp;
1640 }
1641 } else if (compiler_type.IsFloatingPointType(float_count, is_complex)) {
1642 if (float_count == 1 && !is_complex) {
1643 switch (*bit_width) {
1644 default:
1645 return return_valobj_sp;
1646 case 64: {
1647 static_assert(sizeof(double) == sizeof(uint64_t));
1648
1649 if (IsArmHardFloat(thread)) {
1650 RegisterValue reg_value;
1651 const RegisterInfo *d0_reg_info =
1652 reg_ctx->GetRegisterInfoByName("d0", 0);
1653 reg_ctx->ReadRegister(d0_reg_info, reg_value);
1654 value.GetScalar() = reg_value.GetAsDouble();
1655 } else {
1656 uint64_t raw_value;
1657 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1659 raw_value =
1660 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1661 raw_value |=
1662 ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1663 UINT32_MAX))
1664 << 32;
1665 value.GetScalar() = *reinterpret_cast<double *>(&raw_value);
1666 }
1667 break;
1668 }
1669 case 16: // Half precision returned after a conversion to single precision
1670 case 32: {
1671 static_assert(sizeof(float) == sizeof(uint32_t));
1672
1673 if (IsArmHardFloat(thread)) {
1674 RegisterValue reg_value;
1675 const RegisterInfo *s0_reg_info =
1676 reg_ctx->GetRegisterInfoByName("s0", 0);
1677 reg_ctx->ReadRegister(s0_reg_info, reg_value);
1678 value.GetScalar() = reg_value.GetAsFloat();
1679 } else {
1680 uint32_t raw_value;
1681 raw_value =
1682 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1683 value.GetScalar() = *reinterpret_cast<float *>(&raw_value);
1684 }
1685 break;
1686 }
1687 }
1688 } else if (is_complex && float_count == 2) {
1689 if (IsArmHardFloat(thread)) {
1690 is_vfp_candidate = true;
1691 vfp_byte_size = *byte_size / 2;
1692 vfp_count = 2;
1693 } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8,
1694 value))
1695 return return_valobj_sp;
1696 } else
1697 // not handled yet
1698 return return_valobj_sp;
1699 } else if (compiler_type.IsAggregateType()) {
1700 if (IsArmHardFloat(thread)) {
1701 CompilerType base_type;
1702 const uint32_t homogeneous_count =
1703 compiler_type.IsHomogeneousAggregate(&base_type);
1704
1705 if (homogeneous_count > 0 && homogeneous_count <= 4) {
1706 std::optional<uint64_t> base_byte_size = base_type.GetByteSize(&thread);
1707 if (base_type.IsVectorType()) {
1708 if (base_byte_size &&
1709 (*base_byte_size == 8 || *base_byte_size == 16)) {
1710 is_vfp_candidate = true;
1711 vfp_byte_size = 8;
1712 vfp_count = (*base_byte_size == 8 ? homogeneous_count
1713 : homogeneous_count * 2);
1714 }
1715 } else if (base_type.IsFloatingPointType(float_count, is_complex)) {
1716 if (float_count == 1 && !is_complex) {
1717 is_vfp_candidate = true;
1718 if (base_byte_size)
1719 vfp_byte_size = *base_byte_size;
1720 vfp_count = homogeneous_count;
1721 }
1722 }
1723 } else if (homogeneous_count == 0) {
1724 const uint32_t num_children = compiler_type.GetNumFields();
1725
1726 if (num_children > 0 && num_children <= 2) {
1727 uint32_t index = 0;
1728 for (index = 0; index < num_children; index++) {
1729 std::string name;
1730 base_type = compiler_type.GetFieldAtIndex(index, name, nullptr,
1731 nullptr, nullptr);
1732
1733 if (base_type.IsFloatingPointType(float_count, is_complex)) {
1734 std::optional<uint64_t> base_byte_size =
1735 base_type.GetByteSize(&thread);
1736 if (float_count == 2 && is_complex) {
1737 if (index != 0 && base_byte_size &&
1738 vfp_byte_size != *base_byte_size)
1739 break;
1740 else if (base_byte_size)
1741 vfp_byte_size = *base_byte_size;
1742 } else
1743 break;
1744 } else
1745 break;
1746 }
1747
1748 if (index == num_children) {
1749 is_vfp_candidate = true;
1750 vfp_byte_size = (vfp_byte_size >> 1);
1751 vfp_count = (num_children << 1);
1752 }
1753 }
1754 }
1755 }
1756
1757 if (*byte_size <= 4) {
1758 RegisterValue r0_reg_value;
1759 uint32_t raw_value =
1760 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1761 value.SetBytes(&raw_value, *byte_size);
1762 } else if (!is_vfp_candidate) {
1763 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1764 return return_valobj_sp;
1765 }
1766 } else {
1767 // not handled yet
1768 return return_valobj_sp;
1769 }
1770
1771 if (is_vfp_candidate) {
1772 ProcessSP process_sp(thread.GetProcess());
1773 ByteOrder byte_order = process_sp->GetByteOrder();
1774
1775 WritableDataBufferSP data_sp(new DataBufferHeap(*byte_size, 0));
1776 uint32_t data_offset = 0;
1777
1778 for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) {
1779 uint32_t regnum = 0;
1780
1781 if (vfp_byte_size == 4)
1782 regnum = dwarf_s0 + reg_index;
1783 else if (vfp_byte_size == 8)
1784 regnum = dwarf_d0 + reg_index;
1785 else
1786 break;
1787
1788 const RegisterInfo *reg_info =
1789 reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum);
1790 if (reg_info == nullptr)
1791 break;
1792
1793 RegisterValue reg_value;
1794 if (!reg_ctx->ReadRegister(reg_info, reg_value))
1795 break;
1796
1797 // Make sure we have enough room in "data_sp"
1798 if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) {
1799 Status error;
1800 const size_t bytes_copied = reg_value.GetAsMemoryData(
1801 *reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size,
1802 byte_order, error);
1803 if (bytes_copied != vfp_byte_size)
1804 break;
1805
1806 data_offset += bytes_copied;
1807 }
1808 }
1809
1810 if (data_offset == *byte_size) {
1811 DataExtractor data;
1812 data.SetByteOrder(byte_order);
1813 data.SetAddressByteSize(process_sp->GetAddressByteSize());
1814 data.SetData(data_sp);
1815
1816 return ValueObjectConstResult::Create(&thread, compiler_type,
1817 ConstString(""), data);
1818 } else { // Some error occurred while getting values from registers
1819 return return_valobj_sp;
1820 }
1821 }
1822
1823 // If we get here, we have a valid Value, so make our ValueObject out of it:
1824
1825 return_valobj_sp = ValueObjectConstResult::Create(
1826 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1827 return return_valobj_sp;
1828}
1829
1831 lldb::ValueObjectSP &new_value_sp) {
1832 Status error;
1833 if (!new_value_sp) {
1834 error.SetErrorString("Empty value object for return value.");
1835 return error;
1836 }
1837
1838 CompilerType compiler_type = new_value_sp->GetCompilerType();
1839 if (!compiler_type) {
1840 error.SetErrorString("Null clang type for return value.");
1841 return error;
1842 }
1843
1844 Thread *thread = frame_sp->GetThread().get();
1845
1846 bool is_signed;
1847 uint32_t count;
1848 bool is_complex;
1849
1850 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1851
1852 bool set_it_simple = false;
1853 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1854 compiler_type.IsPointerType()) {
1855 DataExtractor data;
1856 Status data_error;
1857 size_t num_bytes = new_value_sp->GetData(data, data_error);
1858 if (data_error.Fail()) {
1859 error.SetErrorStringWithFormat(
1860 "Couldn't convert return value to raw data: %s",
1861 data_error.AsCString());
1862 return error;
1863 }
1864 lldb::offset_t offset = 0;
1865 if (num_bytes <= 8) {
1866 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo(
1868 if (num_bytes <= 4) {
1869 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1870
1871 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1872 set_it_simple = true;
1873 } else {
1874 uint32_t raw_value = data.GetMaxU32(&offset, 4);
1875
1876 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1877 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo(
1879 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1880
1881 if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1882 set_it_simple = true;
1883 }
1884 }
1885 } else {
1886 error.SetErrorString("We don't support returning longer than 64 bit "
1887 "integer values at present.");
1888 }
1889 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1890 if (is_complex)
1891 error.SetErrorString(
1892 "We don't support returning complex values at present");
1893 else
1894 error.SetErrorString(
1895 "We don't support returning float values at present");
1896 }
1897
1898 if (!set_it_simple)
1899 error.SetErrorString(
1900 "We only support setting simple integer return types at present.");
1901
1902 return error;
1903}
1904
1906 unwind_plan.Clear();
1908
1909 uint32_t lr_reg_num = dwarf_lr;
1910 uint32_t sp_reg_num = dwarf_sp;
1911 uint32_t pc_reg_num = dwarf_pc;
1912
1914
1915 // Our Call Frame Address is the stack pointer value
1916 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1917
1918 // The previous PC is in the LR
1919 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1920 unwind_plan.AppendRow(row);
1921
1922 // All other registers are the same.
1923
1924 unwind_plan.SetSourceName("arm at-func-entry default");
1926
1927 return true;
1928}
1929
1931 unwind_plan.Clear();
1933
1934 // TODO: Handle thumb
1935 uint32_t fp_reg_num = dwarf_r11;
1936 uint32_t pc_reg_num = dwarf_pc;
1937
1939 const int32_t ptr_size = 4;
1940
1941 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1942 row->SetOffset(0);
1943 row->SetUnspecifiedRegistersAreUndefined(true);
1944
1945 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1946 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1947
1948 unwind_plan.AppendRow(row);
1949 unwind_plan.SetSourceName("arm default unwind plan");
1953
1954 return true;
1955}
1956
1957// cf. "ARMv6 Function Calling Conventions"
1958
1959// ARMv7 on GNU/Linux general purpose reg rules:
1960// r0-r3 not preserved (used for argument passing)
1961// r4-r11 preserved (v1-v8)
1962// r12 not presrved
1963// r13 preserved (stack pointer)
1964// r14 preserved (link register)
1965// r15 preserved (pc)
1966// cpsr not preserved (different rules for different bits)
1967
1968// ARMv7 VFP register rules:
1969// d0-d7 not preserved (aka s0-s15, q0-q3)
1970// d8-d15 preserved (aka s16-s31, q4-q7)
1971// d16-d31 not preserved (aka q8-q15)
1972
1974 if (reg_info) {
1975 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1976 const char *name = reg_info->name;
1977 if (name[0] == 'r') {
1978 switch (name[1]) {
1979 case '0':
1980 return name[2] == '\0'; // r0
1981 case '1':
1982 switch (name[2]) {
1983 case '\0':
1984 return true; // r1
1985 case '2':
1986 return name[3] == '\0'; // r12
1987 default:
1988 break;
1989 }
1990 break;
1991
1992 case '2':
1993 return name[2] == '\0'; // r2
1994 case '3':
1995 return name[2] == '\0'; // r3
1996 default:
1997 break;
1998 }
1999 } else if (name[0] == 'd') {
2000 switch (name[1]) {
2001 case '0':
2002 return name[2] == '\0'; // d0 is volatile
2003
2004 case '1':
2005 switch (name[2]) {
2006 case '\0':
2007 return true; // d1 is volatile
2008 case '6':
2009 case '7':
2010 case '8':
2011 case '9':
2012 return name[3] == '\0'; // d16 - d19 are volatile
2013 default:
2014 break;
2015 }
2016 break;
2017
2018 case '2':
2019 switch (name[2]) {
2020 case '\0':
2021 return true; // d2 is volatile
2022 case '0':
2023 case '1':
2024 case '2':
2025 case '3':
2026 case '4':
2027 case '5':
2028 case '6':
2029 case '7':
2030 case '8':
2031 case '9':
2032 return name[3] == '\0'; // d20 - d29 are volatile
2033 default:
2034 break;
2035 }
2036 break;
2037
2038 case '3':
2039 switch (name[2]) {
2040 case '\0':
2041 return true; // d3 is volatile
2042 case '0':
2043 case '1':
2044 return name[3] == '\0'; // d30 - d31 are volatile
2045 default:
2046 break;
2047 }
2048 break;
2049 case '4':
2050 case '5':
2051 case '6':
2052 case '7':
2053 return name[2] == '\0'; // d4 - d7 are volatile
2054
2055 default:
2056 break;
2057 }
2058 } else if (name[0] == 's') {
2059 switch (name[1]) {
2060 case '0':
2061 return name[2] == '\0'; // s0 is volatile
2062
2063 case '1':
2064 switch (name[2]) {
2065 case '\0':
2066 return true; // s1 is volatile
2067 case '0':
2068 case '1':
2069 case '2':
2070 case '3':
2071 case '4':
2072 case '5':
2073 return name[3] == '\0'; // s10 - s15 are volatile
2074 default:
2075 break;
2076 }
2077 break;
2078
2079 case '2':
2080 case '3':
2081 case '4':
2082 case '5':
2083 case '6':
2084 case '7':
2085 case '8':
2086 case '9':
2087 return name[2] == '\0'; // s2 - s9 are volatile
2088
2089 default:
2090 break;
2091 }
2092 } else if (name[0] == 'q') {
2093 switch (name[1]) {
2094 case '1':
2095 switch (name[2]) {
2096 case '\0':
2097 return true; // q1 is volatile
2098 case '0':
2099 case '1':
2100 case '2':
2101 case '3':
2102 case '4':
2103 case '5':
2104 return true; // q10-q15 are volatile
2105 default:
2106 return false;
2107 }
2108 break;
2109
2110 case '0':
2111 case '2':
2112 case '3':
2113 return name[2] == '\0'; // q0-q3 are volatile
2114 case '8':
2115 case '9':
2116 return name[2] == '\0'; // q8-q9 are volatile
2117 default:
2118 break;
2119 }
2120 } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2121 return true;
2122 }
2123 return false;
2124}
2125
2128 "SysV ABI for arm targets", CreateInstance);
2129}
2130
2133}
static const uint32_t k_num_register_infos
static const RegisterInfo g_register_infos[]
static const uint32_t k_num_register_infos
static bool GetReturnValuePassedInMemory(Thread &thread, RegisterContext *reg_ctx, size_t byte_size, Value &value)
static const RegisterInfo g_register_infos[]
Definition: ABISysV_arm.cpp:40
@ 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)
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const override
bool CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
bool IsArmHardFloat(lldb_private::Thread &thread) const
lldb::ValueObjectSP GetReturnValueObjectImpl(lldb_private::Thread &thread, lldb_private::CompilerType &ast_type) const override
bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override
static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, const lldb_private::ArchSpec &arch)
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
static void Initialize()
lldb_private::Status SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) override
static llvm::StringRef GetPluginNameStatic()
Definition: ABISysV_arm.h:74
bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
static void Terminate()
size_t GetRedZoneSize() const override
static std::unique_ptr< llvm::MCRegisterInfo > MakeMCRegisterInfo(const ArchSpec &arch)
Utility function to construct a MCRegisterInfo using the ArchSpec triple.
Definition: ABI.cpp:234
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:1046
An architecture specification class.
Definition: ArchSpec.h:31
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:450
uint32_t GetFlags() const
Definition: ArchSpec.h:521
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.
uint32_t IsHomogeneousAggregate(CompilerType *base_type_ptr) const
CompilerType GetFieldAtIndex(size_t idx, std::string &name, uint64_t *bit_offset_ptr, uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) const
bool IsFloatingPointType(uint32_t &count, bool &is_complex) const
uint32_t GetNumFields() 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 IsVectorType(CompilerType *element_type=nullptr, uint64_t *size=nullptr) const
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.
lldb::offset_t GetByteSize() const override
Get the number of bytes in the data buffer.
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.
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
void SetAddressByteSize(uint32_t addr_size)
Set the address byte size.
"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:2238
uint32_t GetAddressByteSize() const
Definition: Process.cpp:3404
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)
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)
double GetAsDouble(double fail_value=0.0, bool *success_ptr=nullptr) const
uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
float GetAsFloat(float fail_value=0.0f, bool *success_ptr=nullptr) 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:405
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb::TargetSP CalculateTarget() override
Definition: Thread.cpp:1390
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
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:686
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
void SetBytes(const void *bytes, int len)
Definition: Value.cpp:88
uint8_t * GetBytes()
Get a pointer to the data.
Definition: DataBuffer.h:108
#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: SBAttachInfo.h:14
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::ABI > ABISP
Definition: lldb-forward.h:310
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
Definition: lldb-forward.h:412
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Definition: lldb-forward.h:472
uint64_t offset_t
Definition: lldb-types.h:83
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:381
@ eEncodingIEEE754
float
@ eEncodingUint
unsigned integer
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
Definition: lldb-forward.h:329
uint64_t addr_t
Definition: lldb-types.h:79
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:436
@ 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.