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"
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
41 {"r0",
42 nullptr,
43 4,
44 0,
49 nullptr,
50 nullptr,
51 nullptr,
52 },
53 {"r1",
54 nullptr,
55 4,
56 0,
61 nullptr,
62 nullptr,
63 nullptr,
64 },
65 {"r2",
66 nullptr,
67 4,
68 0,
73 nullptr,
74 nullptr,
75 nullptr,
76 },
77 {"r3",
78 nullptr,
79 4,
80 0,
85 nullptr,
86 nullptr,
87 nullptr,
88 },
89 {"r4",
90 nullptr,
91 4,
92 0,
97 nullptr,
98 nullptr,
99 nullptr,
100 },
101 {"r5",
102 nullptr,
103 4,
104 0,
109 nullptr,
110 nullptr,
111 nullptr,
112 },
113 {"r6",
114 nullptr,
115 4,
116 0,
121 nullptr,
122 nullptr,
123 nullptr,
124 },
125 {"r7",
126 nullptr,
127 4,
128 0,
133 nullptr,
134 nullptr,
135 nullptr,
136 },
137 {"r8",
138 nullptr,
139 4,
140 0,
145 nullptr,
146 nullptr,
147 nullptr,
148 },
149 {"r9",
150 nullptr,
151 4,
152 0,
157 nullptr,
158 nullptr,
159 nullptr,
160 },
161 {"r10",
162 nullptr,
163 4,
164 0,
169 nullptr,
170 nullptr,
171 nullptr,
172 },
173 {"r11",
174 nullptr,
175 4,
176 0,
181 nullptr,
182 nullptr,
183 nullptr,
184 },
185 {"r12",
186 nullptr,
187 4,
188 0,
193 nullptr,
194 nullptr,
195 nullptr,
196 },
197 {"sp",
198 "r13",
199 4,
200 0,
205 nullptr,
206 nullptr,
207 nullptr,
208 },
209 {"lr",
210 "r14",
211 4,
212 0,
217 nullptr,
218 nullptr,
219 nullptr,
220 },
221 {"pc",
222 "r15",
223 4,
224 0,
229 nullptr,
230 nullptr,
231 nullptr,
232 },
233 {"cpsr",
234 "psr",
235 4,
236 0,
241 nullptr,
242 nullptr,
243 nullptr,
244 },
245 {"s0",
246 nullptr,
247 4,
248 0,
253 nullptr,
254 nullptr,
255 nullptr,
256 },
257 {"s1",
258 nullptr,
259 4,
260 0,
265 nullptr,
266 nullptr,
267 nullptr,
268 },
269 {"s2",
270 nullptr,
271 4,
272 0,
277 nullptr,
278 nullptr,
279 nullptr,
280 },
281 {"s3",
282 nullptr,
283 4,
284 0,
289 nullptr,
290 nullptr,
291 nullptr,
292 },
293 {"s4",
294 nullptr,
295 4,
296 0,
301 nullptr,
302 nullptr,
303 nullptr,
304 },
305 {"s5",
306 nullptr,
307 4,
308 0,
313 nullptr,
314 nullptr,
315 nullptr,
316 },
317 {"s6",
318 nullptr,
319 4,
320 0,
325 nullptr,
326 nullptr,
327 nullptr,
328 },
329 {"s7",
330 nullptr,
331 4,
332 0,
337 nullptr,
338 nullptr,
339 nullptr,
340 },
341 {"s8",
342 nullptr,
343 4,
344 0,
349 nullptr,
350 nullptr,
351 nullptr,
352 },
353 {"s9",
354 nullptr,
355 4,
356 0,
361 nullptr,
362 nullptr,
363 nullptr,
364 },
365 {"s10",
366 nullptr,
367 4,
368 0,
373 nullptr,
374 nullptr,
375 nullptr,
376 },
377 {"s11",
378 nullptr,
379 4,
380 0,
385 nullptr,
386 nullptr,
387 nullptr,
388 },
389 {"s12",
390 nullptr,
391 4,
392 0,
397 nullptr,
398 nullptr,
399 nullptr,
400 },
401 {"s13",
402 nullptr,
403 4,
404 0,
409 nullptr,
410 nullptr,
411 nullptr,
412 },
413 {"s14",
414 nullptr,
415 4,
416 0,
421 nullptr,
422 nullptr,
423 nullptr,
424 },
425 {"s15",
426 nullptr,
427 4,
428 0,
433 nullptr,
434 nullptr,
435 nullptr,
436 },
437 {"s16",
438 nullptr,
439 4,
440 0,
445 nullptr,
446 nullptr,
447 nullptr,
448 },
449 {"s17",
450 nullptr,
451 4,
452 0,
457 nullptr,
458 nullptr,
459 nullptr,
460 },
461 {"s18",
462 nullptr,
463 4,
464 0,
469 nullptr,
470 nullptr,
471 nullptr,
472 },
473 {"s19",
474 nullptr,
475 4,
476 0,
481 nullptr,
482 nullptr,
483 nullptr,
484 },
485 {"s20",
486 nullptr,
487 4,
488 0,
493 nullptr,
494 nullptr,
495 nullptr,
496 },
497 {"s21",
498 nullptr,
499 4,
500 0,
505 nullptr,
506 nullptr,
507 nullptr,
508 },
509 {"s22",
510 nullptr,
511 4,
512 0,
517 nullptr,
518 nullptr,
519 nullptr,
520 },
521 {"s23",
522 nullptr,
523 4,
524 0,
529 nullptr,
530 nullptr,
531 nullptr,
532 },
533 {"s24",
534 nullptr,
535 4,
536 0,
541 nullptr,
542 nullptr,
543 nullptr,
544 },
545 {"s25",
546 nullptr,
547 4,
548 0,
553 nullptr,
554 nullptr,
555 nullptr,
556 },
557 {"s26",
558 nullptr,
559 4,
560 0,
565 nullptr,
566 nullptr,
567 nullptr,
568 },
569 {"s27",
570 nullptr,
571 4,
572 0,
577 nullptr,
578 nullptr,
579 nullptr,
580 },
581 {"s28",
582 nullptr,
583 4,
584 0,
589 nullptr,
590 nullptr,
591 nullptr,
592 },
593 {"s29",
594 nullptr,
595 4,
596 0,
601 nullptr,
602 nullptr,
603 nullptr,
604 },
605 {"s30",
606 nullptr,
607 4,
608 0,
613 nullptr,
614 nullptr,
615 nullptr,
616 },
617 {"s31",
618 nullptr,
619 4,
620 0,
625 nullptr,
626 nullptr,
627 nullptr,
628 },
629 {"fpscr",
630 nullptr,
631 4,
632 0,
637 nullptr,
638 nullptr,
639 nullptr,
640 },
641 {"d0",
642 nullptr,
643 8,
644 0,
649 nullptr,
650 nullptr,
651 nullptr,
652 },
653 {"d1",
654 nullptr,
655 8,
656 0,
661 nullptr,
662 nullptr,
663 nullptr,
664 },
665 {"d2",
666 nullptr,
667 8,
668 0,
673 nullptr,
674 nullptr,
675 nullptr,
676 },
677 {"d3",
678 nullptr,
679 8,
680 0,
685 nullptr,
686 nullptr,
687 nullptr,
688 },
689 {"d4",
690 nullptr,
691 8,
692 0,
697 nullptr,
698 nullptr,
699 nullptr,
700 },
701 {"d5",
702 nullptr,
703 8,
704 0,
709 nullptr,
710 nullptr,
711 nullptr,
712 },
713 {"d6",
714 nullptr,
715 8,
716 0,
721 nullptr,
722 nullptr,
723 nullptr,
724 },
725 {"d7",
726 nullptr,
727 8,
728 0,
733 nullptr,
734 nullptr,
735 nullptr,
736 },
737 {"d8",
738 nullptr,
739 8,
740 0,
745 nullptr,
746 nullptr,
747 nullptr,
748 },
749 {"d9",
750 nullptr,
751 8,
752 0,
757 nullptr,
758 nullptr,
759 nullptr,
760 },
761 {"d10",
762 nullptr,
763 8,
764 0,
769 nullptr,
770 nullptr,
771 nullptr,
772 },
773 {"d11",
774 nullptr,
775 8,
776 0,
781 nullptr,
782 nullptr,
783 nullptr,
784 },
785 {"d12",
786 nullptr,
787 8,
788 0,
793 nullptr,
794 nullptr,
795 nullptr,
796 },
797 {"d13",
798 nullptr,
799 8,
800 0,
805 nullptr,
806 nullptr,
807 nullptr,
808 },
809 {"d14",
810 nullptr,
811 8,
812 0,
817 nullptr,
818 nullptr,
819 nullptr,
820 },
821 {"d15",
822 nullptr,
823 8,
824 0,
829 nullptr,
830 nullptr,
831 nullptr,
832 },
833 {"d16",
834 nullptr,
835 8,
836 0,
841 nullptr,
842 nullptr,
843 nullptr,
844 },
845 {"d17",
846 nullptr,
847 8,
848 0,
853 nullptr,
854 nullptr,
855 nullptr,
856 },
857 {"d18",
858 nullptr,
859 8,
860 0,
865 nullptr,
866 nullptr,
867 nullptr,
868 },
869 {"d19",
870 nullptr,
871 8,
872 0,
877 nullptr,
878 nullptr,
879 nullptr,
880 },
881 {"d20",
882 nullptr,
883 8,
884 0,
889 nullptr,
890 nullptr,
891 nullptr,
892 },
893 {"d21",
894 nullptr,
895 8,
896 0,
901 nullptr,
902 nullptr,
903 nullptr,
904 },
905 {"d22",
906 nullptr,
907 8,
908 0,
913 nullptr,
914 nullptr,
915 nullptr,
916 },
917 {"d23",
918 nullptr,
919 8,
920 0,
925 nullptr,
926 nullptr,
927 nullptr,
928 },
929 {"d24",
930 nullptr,
931 8,
932 0,
937 nullptr,
938 nullptr,
939 nullptr,
940 },
941 {"d25",
942 nullptr,
943 8,
944 0,
949 nullptr,
950 nullptr,
951 nullptr,
952 },
953 {"d26",
954 nullptr,
955 8,
956 0,
961 nullptr,
962 nullptr,
963 nullptr,
964 },
965 {"d27",
966 nullptr,
967 8,
968 0,
973 nullptr,
974 nullptr,
975 nullptr,
976 },
977 {"d28",
978 nullptr,
979 8,
980 0,
985 nullptr,
986 nullptr,
987 nullptr,
988 },
989 {"d29",
990 nullptr,
991 8,
992 0,
997 nullptr,
998 nullptr,
999 nullptr,
1000 },
1001 {"d30",
1002 nullptr,
1003 8,
1004 0,
1009 nullptr,
1010 nullptr,
1011 nullptr,
1012 },
1013 {"d31",
1014 nullptr,
1015 8,
1016 0,
1021 nullptr,
1022 nullptr,
1023 nullptr,
1024 },
1025 {"r8_usr",
1026 nullptr,
1027 4,
1028 0,
1030 eFormatHex,
1033 nullptr,
1034 nullptr,
1035 nullptr,
1036 },
1037 {"r9_usr",
1038 nullptr,
1039 4,
1040 0,
1042 eFormatHex,
1045 nullptr,
1046 nullptr,
1047 nullptr,
1048 },
1049 {"r10_usr",
1050 nullptr,
1051 4,
1052 0,
1054 eFormatHex,
1057 nullptr,
1058 nullptr,
1059 nullptr,
1060 },
1061 {"r11_usr",
1062 nullptr,
1063 4,
1064 0,
1066 eFormatHex,
1069 nullptr,
1070 nullptr,
1071 nullptr,
1072 },
1073 {"r12_usr",
1074 nullptr,
1075 4,
1076 0,
1078 eFormatHex,
1081 nullptr,
1082 nullptr,
1083 nullptr,
1084 },
1085 {"r13_usr",
1086 "sp_usr",
1087 4,
1088 0,
1090 eFormatHex,
1093 nullptr,
1094 nullptr,
1095 nullptr,
1096 },
1097 {"r14_usr",
1098 "lr_usr",
1099 4,
1100 0,
1102 eFormatHex,
1105 nullptr,
1106 nullptr,
1107 nullptr,
1108 },
1109 {"r8_fiq",
1110 nullptr,
1111 4,
1112 0,
1114 eFormatHex,
1117 nullptr,
1118 nullptr,
1119 nullptr,
1120 },
1121 {"r9_fiq",
1122 nullptr,
1123 4,
1124 0,
1126 eFormatHex,
1129 nullptr,
1130 nullptr,
1131 nullptr,
1132 },
1133 {"r10_fiq",
1134 nullptr,
1135 4,
1136 0,
1138 eFormatHex,
1141 nullptr,
1142 nullptr,
1143 nullptr,
1144 },
1145 {"r11_fiq",
1146 nullptr,
1147 4,
1148 0,
1150 eFormatHex,
1153 nullptr,
1154 nullptr,
1155 nullptr,
1156 },
1157 {"r12_fiq",
1158 nullptr,
1159 4,
1160 0,
1162 eFormatHex,
1165 nullptr,
1166 nullptr,
1167 nullptr,
1168 },
1169 {"r13_fiq",
1170 "sp_fiq",
1171 4,
1172 0,
1174 eFormatHex,
1177 nullptr,
1178 nullptr,
1179 nullptr,
1180 },
1181 {"r14_fiq",
1182 "lr_fiq",
1183 4,
1184 0,
1186 eFormatHex,
1189 nullptr,
1190 nullptr,
1191 nullptr,
1192 },
1193 {"r13_irq",
1194 "sp_irq",
1195 4,
1196 0,
1198 eFormatHex,
1201 nullptr,
1202 nullptr,
1203 nullptr,
1204 },
1205 {"r14_irq",
1206 "lr_irq",
1207 4,
1208 0,
1210 eFormatHex,
1213 nullptr,
1214 nullptr,
1215 nullptr,
1216 },
1217 {"r13_abt",
1218 "sp_abt",
1219 4,
1220 0,
1222 eFormatHex,
1225 nullptr,
1226 nullptr,
1227 nullptr,
1228 },
1229 {"r14_abt",
1230 "lr_abt",
1231 4,
1232 0,
1234 eFormatHex,
1237 nullptr,
1238 nullptr,
1239 nullptr,
1240 },
1241 {"r13_und",
1242 "sp_und",
1243 4,
1244 0,
1246 eFormatHex,
1249 nullptr,
1250 nullptr,
1251 nullptr,
1252 },
1253 {"r14_und",
1254 "lr_und",
1255 4,
1256 0,
1258 eFormatHex,
1261 nullptr,
1262 nullptr,
1263 nullptr,
1264
1265 },
1266 {"r13_svc",
1267 "sp_svc",
1268 4,
1269 0,
1271 eFormatHex,
1274 nullptr,
1275 nullptr,
1276 nullptr,
1277 },
1278 {"r14_svc",
1279 "lr_svc",
1280 4,
1281 0,
1283 eFormatHex,
1286 nullptr,
1287 nullptr,
1288 nullptr,
1289 }};
1290
1291static const uint32_t k_num_register_infos = std::size(g_register_infos);
1292
1295 count = k_num_register_infos;
1296 return g_register_infos;
1297}
1298
1299size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
1300
1301// Static Functions
1302
1303ABISP
1305 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1306 const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1307
1308 if (vendor_type != llvm::Triple::Apple) {
1309 if ((arch_type == llvm::Triple::arm) ||
1310 (arch_type == llvm::Triple::thumb)) {
1311 return ABISP(
1312 new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1313 }
1314 }
1315
1316 return ABISP();
1317}
1318
1320 addr_t function_addr, addr_t return_addr,
1321 llvm::ArrayRef<addr_t> args) const {
1322 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1323 if (!reg_ctx)
1324 return false;
1325
1326 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1328 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1330 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1332
1333 RegisterValue reg_value;
1334
1335 const uint8_t reg_names[] = {
1338
1339 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1340
1341 for (size_t i = 0; i < std::size(reg_names); ++i) {
1342 if (ai == ae)
1343 break;
1344
1345 reg_value.SetUInt32(*ai);
1346 if (!reg_ctx->WriteRegister(
1347 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]),
1348 reg_value))
1349 return false;
1350
1351 ++ai;
1352 }
1353
1354 if (ai != ae) {
1355 // Spill onto the stack
1356 size_t num_stack_regs = ae - ai;
1357
1358 sp -= (num_stack_regs * 4);
1359 // Keep the stack 8 byte aligned, not that we need to
1360 sp &= ~(8ull - 1ull);
1361
1362 // just using arg1 to get the right size
1363 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1365
1366 addr_t arg_pos = sp;
1367
1368 for (; ai != ae; ++ai) {
1369 reg_value.SetUInt32(*ai);
1370 if (reg_ctx
1371 ->WriteRegisterValueToMemory(reg_info, arg_pos,
1372 reg_info->byte_size, reg_value)
1373 .Fail())
1374 return false;
1375 arg_pos += reg_info->byte_size;
1376 }
1377 }
1378
1379 TargetSP target_sp(thread.CalculateTarget());
1380 Address so_addr;
1381
1382 // Figure out if our return address is ARM or Thumb by using the
1383 // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1384 // thumb-ness and set the correct address bits for us.
1385 so_addr.SetLoadAddress(return_addr, target_sp.get());
1386 return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1387
1388 // Set "lr" to the return address
1389 if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
1390 return false;
1391
1392 // Set "sp" to the requested value
1393 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1394 return false;
1395
1396 // If bit zero or 1 is set, this must be a thumb function, no need to figure
1397 // this out from the symbols.
1398 so_addr.SetLoadAddress(function_addr, target_sp.get());
1399 function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1400
1401 const RegisterInfo *cpsr_reg_info =
1403 const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
1404
1405 // Make a new CPSR and mask out any Thumb IT (if/then) bits
1406 uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1407 // If bit zero or 1 is set, this must be thumb...
1408 if (function_addr & 1ull)
1409 new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1410 else
1411 new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1412
1413 if (new_cpsr != curr_cpsr) {
1414 if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1415 return false;
1416 }
1417
1418 function_addr &=
1419 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1420
1421 // Set "pc" to the address requested
1422 return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr);
1423}
1424
1426 uint32_t num_values = values.GetSize();
1427
1428 ExecutionContext exe_ctx(thread.shared_from_this());
1429 // For now, assume that the types in the AST values come from the Target's
1430 // scratch AST.
1431
1432 // Extract the register context so we can read arguments from registers
1433
1434 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1435
1436 if (!reg_ctx)
1437 return false;
1438
1439 addr_t sp = 0;
1440
1441 for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1442 // We currently only support extracting values with Clang QualTypes. Do we
1443 // care about others?
1444 Value *value = values.GetValueAtIndex(value_idx);
1445
1446 if (!value)
1447 return false;
1448
1449 CompilerType compiler_type = value->GetCompilerType();
1450 if (compiler_type) {
1451 bool is_signed = false;
1452 size_t bit_width = 0;
1453 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1454 compiler_type.IsPointerOrReferenceType()) {
1455 if (std::optional<uint64_t> size =
1456 llvm::expectedToOptional(compiler_type.GetBitSize(&thread)))
1457 bit_width = *size;
1458 } else {
1459 // We only handle integer, pointer and reference types currently...
1460 return false;
1461 }
1462
1463 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1464 if (value_idx < 4) {
1465 // Arguments 1-4 are in r0-r3...
1466 const RegisterInfo *arg_reg_info = nullptr;
1467 arg_reg_info = reg_ctx->GetRegisterInfo(
1469 if (arg_reg_info) {
1470 RegisterValue reg_value;
1471
1472 if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1473 if (is_signed)
1474 reg_value.SignExtend(bit_width);
1475 if (!reg_value.GetScalarValue(value->GetScalar()))
1476 return false;
1477 continue;
1478 }
1479 }
1480 return false;
1481 } else {
1482 if (sp == 0) {
1483 // Read the stack pointer if it already hasn't been read
1484 sp = reg_ctx->GetSP(0);
1485 if (sp == 0)
1486 return false;
1487 }
1488
1489 // Arguments 5 on up are on the stack
1490 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1491 Status error;
1493 sp, arg_byte_size, is_signed, value->GetScalar(), error))
1494 return false;
1495
1496 sp += arg_byte_size;
1497 }
1498 }
1499 }
1500 }
1501 return true;
1502}
1503
1505 RegisterContext *reg_ctx,
1506 size_t byte_size, Value &value) {
1507 Status error;
1508 DataBufferHeap buffer(byte_size, 0);
1509
1510 const RegisterInfo *r0_reg_info =
1512 uint32_t address =
1513 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1514 thread.GetProcess()->ReadMemory(address, buffer.GetBytes(),
1515 buffer.GetByteSize(), error);
1516
1517 if (error.Fail())
1518 return false;
1519
1520 value.SetBytes(buffer.GetBytes(), buffer.GetByteSize());
1521 return true;
1522}
1523
1525 ProcessSP process_sp(thread.GetProcess());
1526 if (process_sp) {
1527 const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1528
1529 return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
1530 }
1531
1532 return false;
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.SetContext (Value::eContextTypeClangType,
1544 // compiler_type.GetOpaqueQualType());
1545 value.SetCompilerType(compiler_type);
1546
1547 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1548 if (!reg_ctx)
1549 return return_valobj_sp;
1550
1551 bool is_signed;
1552 bool is_vfp_candidate = false;
1553 uint8_t vfp_count = 0;
1554 uint8_t vfp_byte_size = 0;
1555
1556 // Get the pointer to the first stack argument so we have a place to start
1557 // when reading data
1558
1559 const RegisterInfo *r0_reg_info =
1561 std::optional<uint64_t> bit_width =
1562 llvm::expectedToOptional(compiler_type.GetBitSize(&thread));
1563 std::optional<uint64_t> byte_size =
1564 llvm::expectedToOptional(compiler_type.GetByteSize(&thread));
1565 if (!bit_width || !byte_size)
1566 return return_valobj_sp;
1567
1568 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1569 switch (*bit_width) {
1570 default:
1571 return return_valobj_sp;
1572 case 64: {
1573 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1575 uint64_t raw_value;
1576 raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1577 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1578 UINT32_MAX))
1579 << 32;
1580 if (is_signed)
1581 value.GetScalar() = (int64_t)raw_value;
1582 else
1583 value.GetScalar() = (uint64_t)raw_value;
1584 } break;
1585 case 32:
1586 if (is_signed)
1587 value.GetScalar() = (int32_t)(
1588 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1589 else
1590 value.GetScalar() = (uint32_t)(
1591 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1592 break;
1593 case 16:
1594 if (is_signed)
1595 value.GetScalar() = (int16_t)(
1596 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1597 else
1598 value.GetScalar() = (uint16_t)(
1599 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1600 break;
1601 case 8:
1602 if (is_signed)
1603 value.GetScalar() = (int8_t)(
1604 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1605 else
1606 value.GetScalar() = (uint8_t)(
1607 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1608 break;
1609 }
1610 } else if (compiler_type.IsPointerType()) {
1611 uint32_t ptr =
1612 thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1613 UINT32_MAX;
1614 value.GetScalar() = ptr;
1615 } else if (compiler_type.IsVectorType()) {
1616 if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
1617 is_vfp_candidate = true;
1618 vfp_byte_size = 8;
1619 vfp_count = (*byte_size == 8 ? 1 : 2);
1620 } else if (*byte_size <= 16) {
1621 DataBufferHeap buffer(16, 0);
1622 uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes();
1623
1624 for (uint32_t i = 0; 4 * i < *byte_size; ++i) {
1625 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1627 buffer_ptr[i] =
1628 reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX;
1629 }
1630 value.SetBytes(buffer.GetBytes(), *byte_size);
1631 } else {
1632 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1633 return return_valobj_sp;
1634 }
1635 } else if (compiler_type.IsFloatingPointType()) {
1636 if (!compiler_type.IsCompleteType()) {
1637 switch (*bit_width) {
1638 default:
1639 return return_valobj_sp;
1640 case 64: {
1641 static_assert(sizeof(double) == sizeof(uint64_t));
1642
1643 if (IsArmHardFloat(thread)) {
1644 RegisterValue reg_value;
1645 const RegisterInfo *d0_reg_info =
1646 reg_ctx->GetRegisterInfoByName("d0", 0);
1647 reg_ctx->ReadRegister(d0_reg_info, reg_value);
1648 value.GetScalar() = reg_value.GetAsDouble();
1649 } else {
1650 uint64_t raw_value;
1651 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1653 raw_value =
1654 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1655 raw_value |=
1656 ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1657 UINT32_MAX))
1658 << 32;
1659 value.GetScalar() = *reinterpret_cast<double *>(&raw_value);
1660 }
1661 break;
1662 }
1663 case 16: // Half precision returned after a conversion to single precision
1664 case 32: {
1665 static_assert(sizeof(float) == sizeof(uint32_t));
1666
1667 if (IsArmHardFloat(thread)) {
1668 RegisterValue reg_value;
1669 const RegisterInfo *s0_reg_info =
1670 reg_ctx->GetRegisterInfoByName("s0", 0);
1671 reg_ctx->ReadRegister(s0_reg_info, reg_value);
1672 value.GetScalar() = reg_value.GetAsFloat();
1673 } else {
1674 uint32_t raw_value;
1675 raw_value =
1676 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1677 value.GetScalar() = *reinterpret_cast<float *>(&raw_value);
1678 }
1679 break;
1680 }
1681 }
1682 } else {
1683 if (IsArmHardFloat(thread)) {
1684 is_vfp_candidate = true;
1685 vfp_byte_size = *byte_size / 2;
1686 vfp_count = 2;
1687 } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8,
1688 value))
1689 return return_valobj_sp;
1690 }
1691 } else if (compiler_type.IsAggregateType()) {
1692 if (IsArmHardFloat(thread)) {
1693 CompilerType base_type;
1694 const uint32_t homogeneous_count =
1695 compiler_type.IsHomogeneousAggregate(&base_type);
1696
1697 if (homogeneous_count > 0 && homogeneous_count <= 4) {
1698 std::optional<uint64_t> base_byte_size =
1699 llvm::expectedToOptional(base_type.GetByteSize(&thread));
1700 if (base_type.IsVectorType()) {
1701 if (base_byte_size &&
1702 (*base_byte_size == 8 || *base_byte_size == 16)) {
1703 is_vfp_candidate = true;
1704 vfp_byte_size = 8;
1705 vfp_count = (*base_byte_size == 8 ? homogeneous_count
1706 : homogeneous_count * 2);
1707 }
1708 } else if (base_type.IsFloatingPointType()) {
1709 if (!base_type.IsComplexType()) {
1710 is_vfp_candidate = true;
1711 if (base_byte_size)
1712 vfp_byte_size = *base_byte_size;
1713 vfp_count = homogeneous_count;
1714 }
1715 }
1716 } else if (homogeneous_count == 0) {
1717 const uint32_t num_children = compiler_type.GetNumFields();
1718
1719 if (num_children > 0 && num_children <= 2) {
1720 uint32_t index = 0;
1721 for (index = 0; index < num_children; index++) {
1722 std::string name;
1723 base_type = compiler_type.GetFieldAtIndex(index, name, nullptr,
1724 nullptr, nullptr);
1725
1726 // TODO: is this correct for float vector types?
1727 if (base_type.GetTypeInfo() & eTypeIsFloat) {
1728 std::optional<uint64_t> base_byte_size =
1729 llvm::expectedToOptional(base_type.GetByteSize(&thread));
1730 if (base_type.IsComplexType()) {
1731 if (index != 0 && base_byte_size &&
1732 vfp_byte_size != *base_byte_size)
1733 break;
1734 else if (base_byte_size)
1735 vfp_byte_size = *base_byte_size;
1736 } else
1737 break;
1738 } else
1739 break;
1740 }
1741
1742 if (index == num_children) {
1743 is_vfp_candidate = true;
1744 vfp_byte_size = (vfp_byte_size >> 1);
1745 vfp_count = (num_children << 1);
1746 }
1747 }
1748 }
1749 }
1750
1751 if (*byte_size <= 4) {
1752 RegisterValue r0_reg_value;
1753 uint32_t raw_value =
1754 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1755 value.SetBytes(&raw_value, *byte_size);
1756 } else if (!is_vfp_candidate) {
1757 if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1758 return return_valobj_sp;
1759 }
1760 } else {
1761 // not handled yet
1762 return return_valobj_sp;
1763 }
1764
1765 if (is_vfp_candidate) {
1766 ProcessSP process_sp(thread.GetProcess());
1767 ByteOrder byte_order = process_sp->GetByteOrder();
1768
1769 WritableDataBufferSP data_sp(new DataBufferHeap(*byte_size, 0));
1770 uint32_t data_offset = 0;
1771
1772 for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) {
1773 uint32_t regnum = 0;
1774
1775 if (vfp_byte_size == 4)
1776 regnum = dwarf_s0 + reg_index;
1777 else if (vfp_byte_size == 8)
1778 regnum = dwarf_d0 + reg_index;
1779 else
1780 break;
1781
1782 const RegisterInfo *reg_info =
1783 reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum);
1784 if (reg_info == nullptr)
1785 break;
1786
1787 RegisterValue reg_value;
1788 if (!reg_ctx->ReadRegister(reg_info, reg_value))
1789 break;
1790
1791 // Make sure we have enough room in "data_sp"
1792 if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) {
1793 Status error;
1794 const size_t bytes_copied = reg_value.GetAsMemoryData(
1795 *reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size,
1796 byte_order, error);
1797 if (bytes_copied != vfp_byte_size)
1798 break;
1799
1800 data_offset += bytes_copied;
1801 }
1802 }
1803
1804 if (data_offset == *byte_size) {
1805 DataExtractor data;
1806 data.SetByteOrder(byte_order);
1807 data.SetAddressByteSize(process_sp->GetAddressByteSize());
1808 data.SetData(data_sp);
1809
1810 return ValueObjectConstResult::Create(&thread, compiler_type,
1811 ConstString(""), data);
1812 } else { // Some error occurred while getting values from registers
1813 return return_valobj_sp;
1814 }
1815 }
1816
1817 // If we get here, we have a valid Value, so make our ValueObject out of it:
1818
1819 return_valobj_sp = ValueObjectConstResult::Create(
1820 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1821 return return_valobj_sp;
1822}
1823
1825 lldb::ValueObjectSP &new_value_sp) {
1826 Status error;
1827 if (!new_value_sp) {
1828 error = Status::FromErrorString("Empty value object for return value.");
1829 return error;
1830 }
1831
1832 CompilerType compiler_type = new_value_sp->GetCompilerType();
1833 if (!compiler_type) {
1834 error = Status::FromErrorString("Null clang type for return value.");
1835 return error;
1836 }
1837
1838 Thread *thread = frame_sp->GetThread().get();
1839
1840 bool is_signed;
1841
1842 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1843
1844 bool set_it_simple = false;
1845 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1846 compiler_type.IsPointerType()) {
1847 DataExtractor data;
1848 Status data_error;
1849 size_t num_bytes = new_value_sp->GetData(data, data_error);
1850 if (data_error.Fail()) {
1852 "Couldn't convert return value to raw data: %s",
1853 data_error.AsCString());
1854 return error;
1855 }
1856 lldb::offset_t offset = 0;
1857 if (num_bytes <= 8) {
1858 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo(
1860 if (num_bytes <= 4) {
1861 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1862
1863 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1864 set_it_simple = true;
1865 } else {
1866 uint32_t raw_value = data.GetMaxU32(&offset, 4);
1867
1868 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1869 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo(
1871 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1872
1873 if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1874 set_it_simple = true;
1875 }
1876 }
1877 } else {
1879 "We don't support returning longer than 64 bit "
1880 "integer values at present.");
1881 }
1882 }
1883
1884 if (!set_it_simple)
1886 "We only support setting simple integer return types at present.");
1887
1888 return error;
1889}
1890
1892 uint32_t lr_reg_num = dwarf_lr;
1893 uint32_t sp_reg_num = dwarf_sp;
1894 uint32_t pc_reg_num = dwarf_pc;
1895
1896 UnwindPlan::Row row;
1897
1898 // Our Call Frame Address is the stack pointer value
1899 row.GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1900
1901 // The previous PC is in the LR, all other registers are the same.
1902 row.SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1903 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
1904 plan_sp->AppendRow(std::move(row));
1905 plan_sp->SetSourceName("arm at-func-entry default");
1906 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
1907 return plan_sp;
1908}
1909
1911 // TODO: Handle thumb
1912 // If we had a Target argument, could at least check
1913 // target.GetArchitecture().GetTriple().isArmMClass()
1914 // which is always thumb.
1915 // To handle thumb properly, we'd need to fetch the current
1916 // CPSR state at unwind time to tell if the processor is
1917 // in thumb mode in this stack frame. There's no way to
1918 // express something like that in an UnwindPlan today.
1919 uint32_t fp_reg_num = dwarf_r11;
1920 uint32_t pc_reg_num = dwarf_pc;
1921
1922 UnwindPlan::Row row;
1923 const int32_t ptr_size = 4;
1924
1925 row.GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1927
1928 row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1929 row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1930
1931 auto plan_sp = std::make_shared<UnwindPlan>(eRegisterKindDWARF);
1932 plan_sp->AppendRow(std::move(row));
1933 plan_sp->SetSourceName("arm default unwind plan");
1934 plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
1935 plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1936 plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
1937 return plan_sp;
1938}
1939
1940// cf. "ARMv6 Function Calling Conventions"
1941
1942// ARMv7 on GNU/Linux general purpose reg rules:
1943// r0-r3 not preserved (used for argument passing)
1944// r4-r11 preserved (v1-v8)
1945// r12 not presrved
1946// r13 preserved (stack pointer)
1947// r14 preserved (link register)
1948// r15 preserved (pc)
1949// cpsr not preserved (different rules for different bits)
1950
1951// ARMv7 VFP register rules:
1952// d0-d7 not preserved (aka s0-s15, q0-q3)
1953// d8-d15 preserved (aka s16-s31, q4-q7)
1954// d16-d31 not preserved (aka q8-q15)
1955
1957 if (reg_info) {
1958 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1959 const char *name = reg_info->name;
1960 if (name[0] == 'r') {
1961 switch (name[1]) {
1962 case '0':
1963 return name[2] == '\0'; // r0
1964 case '1':
1965 switch (name[2]) {
1966 case '\0':
1967 return true; // r1
1968 case '2':
1969 return name[3] == '\0'; // r12
1970 default:
1971 break;
1972 }
1973 break;
1974
1975 case '2':
1976 return name[2] == '\0'; // r2
1977 case '3':
1978 return name[2] == '\0'; // r3
1979 default:
1980 break;
1981 }
1982 } else if (name[0] == 'd') {
1983 switch (name[1]) {
1984 case '0':
1985 return name[2] == '\0'; // d0 is volatile
1986
1987 case '1':
1988 switch (name[2]) {
1989 case '\0':
1990 return true; // d1 is volatile
1991 case '6':
1992 case '7':
1993 case '8':
1994 case '9':
1995 return name[3] == '\0'; // d16 - d19 are volatile
1996 default:
1997 break;
1998 }
1999 break;
2000
2001 case '2':
2002 switch (name[2]) {
2003 case '\0':
2004 return true; // d2 is volatile
2005 case '0':
2006 case '1':
2007 case '2':
2008 case '3':
2009 case '4':
2010 case '5':
2011 case '6':
2012 case '7':
2013 case '8':
2014 case '9':
2015 return name[3] == '\0'; // d20 - d29 are volatile
2016 default:
2017 break;
2018 }
2019 break;
2020
2021 case '3':
2022 switch (name[2]) {
2023 case '\0':
2024 return true; // d3 is volatile
2025 case '0':
2026 case '1':
2027 return name[3] == '\0'; // d30 - d31 are volatile
2028 default:
2029 break;
2030 }
2031 break;
2032 case '4':
2033 case '5':
2034 case '6':
2035 case '7':
2036 return name[2] == '\0'; // d4 - d7 are volatile
2037
2038 default:
2039 break;
2040 }
2041 } else if (name[0] == 's') {
2042 switch (name[1]) {
2043 case '0':
2044 return name[2] == '\0'; // s0 is volatile
2045
2046 case '1':
2047 switch (name[2]) {
2048 case '\0':
2049 return true; // s1 is volatile
2050 case '0':
2051 case '1':
2052 case '2':
2053 case '3':
2054 case '4':
2055 case '5':
2056 return name[3] == '\0'; // s10 - s15 are volatile
2057 default:
2058 break;
2059 }
2060 break;
2061
2062 case '2':
2063 case '3':
2064 case '4':
2065 case '5':
2066 case '6':
2067 case '7':
2068 case '8':
2069 case '9':
2070 return name[2] == '\0'; // s2 - s9 are volatile
2071
2072 default:
2073 break;
2074 }
2075 } else if (name[0] == 'q') {
2076 switch (name[1]) {
2077 case '1':
2078 switch (name[2]) {
2079 case '\0':
2080 return true; // q1 is volatile
2081 case '0':
2082 case '1':
2083 case '2':
2084 case '3':
2085 case '4':
2086 case '5':
2087 return true; // q10-q15 are volatile
2088 default:
2089 return false;
2090 }
2091 break;
2092
2093 case '0':
2094 case '2':
2095 case '3':
2096 return name[2] == '\0'; // q0-q3 are volatile
2097 case '8':
2098 case '9':
2099 return name[2] == '\0'; // q8-q9 are volatile
2100 default:
2101 break;
2102 }
2103 } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2104 return true;
2105 }
2106 return false;
2107}
2108
2111 "SysV ABI for arm targets", CreateInstance);
2112}
2113
static const uint32_t k_num_register_infos
static const RegisterInfo g_register_infos[]
static bool GetReturnValuePassedInMemory(Thread &thread, RegisterContext *reg_ctx, size_t byte_size, Value &value)
@ 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_IT_MASK
Definition ARMDefines.h:175
#define MASK_CPSR_T
Definition ARMDefines.h:176
@ dwarf_s15
@ dwarf_s30
@ dwarf_s12
@ dwarf_r8_usr
@ dwarf_s18
@ dwarf_s27
@ dwarf_r14_abt
@ dwarf_s14
@ dwarf_r11_fiq
@ dwarf_r13_irq
@ dwarf_r14_svc
@ dwarf_r14_usr
@ dwarf_r11_usr
@ dwarf_s10
@ dwarf_s21
@ dwarf_r10_fiq
@ dwarf_s26
@ dwarf_s20
@ dwarf_r14_und
@ dwarf_r13_und
@ dwarf_s23
@ dwarf_s19
@ dwarf_s28
@ dwarf_s29
@ dwarf_r13_abt
@ dwarf_s17
@ dwarf_r9_fiq
@ dwarf_s13
@ dwarf_r9_usr
@ dwarf_r13_usr
@ dwarf_r14_fiq
@ dwarf_r14_irq
@ dwarf_r13_fiq
@ dwarf_r8_fiq
@ dwarf_s31
@ dwarf_cpsr
@ dwarf_s16
@ dwarf_s24
@ dwarf_r10_usr
@ dwarf_r13_svc
@ dwarf_s22
@ dwarf_r12_fiq
@ dwarf_s25
@ dwarf_r12_usr
@ dwarf_s11
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_PLUGIN_DEFINE(PluginName)
bool GetArgumentValues(lldb_private::Thread &thread, lldb_private::ValueList &values) const 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
lldb::UnwindPlanSP CreateDefaultUnwindPlan() 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:73
const lldb_private::RegisterInfo * GetRegisterInfoArray(uint32_t &count) override
lldb::UnwindPlanSP CreateFunctionEntryUnwindPlan() 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:225
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:326
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
Definition Address.cpp:1035
An architecture specification class.
Definition ArchSpec.h:32
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:457
uint32_t GetFlags() const
Definition ArchSpec.h:528
Generic representation of a type in a programming language.
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
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
uint32_t GetNumFields() const
bool IsIntegerOrEnumerationType(bool &is_signed) const
bool IsFloatingPointType() const
Returns true for floating point types (including complex floats).
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
llvm::Expected< 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.
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.
virtual 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:2469
uint32_t GetAddressByteSize() const
Definition Process.cpp:3725
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:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:194
void SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset)
Definition UnwindPlan.h:240
bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
const FAValue & GetCFAValue() const
Definition UnwindPlan.h:365
bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num, bool can_replace)
void SetUnspecifiedRegistersAreUndefined(bool unspec_is_undef)
Definition UnwindPlan.h:408
Value * GetValueAtIndex(size_t idx)
Definition Value.cpp:698
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
See comment on m_scalar to understand what GetScalar returns.
Definition Value.h:113
void SetCompilerType(const CompilerType &compiler_type)
Definition Value.cpp:276
const CompilerType & GetCompilerType()
Definition Value.cpp:247
void SetBytes(const void *bytes, int len)
Definition Value.cpp:90
uint8_t * GetBytes()
Get a pointer to the data.
Definition DataBuffer.h:108
#define LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_ARG4
#define LLDB_REGNUM_GENERIC_ARG3
#define LLDB_REGNUM_GENERIC_ARG1
#define LLDB_REGNUM_GENERIC_FLAGS
#define UINT32_MAX
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_ARG2
#define LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_FP
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
uint64_t offset_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::Process > ProcessSP
@ eEncodingIEEE754
float
@ eEncodingUint
unsigned integer
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
@ 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.