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"
18 #include "lldb/Core/PluginManager.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObjectConstResult.h"
21 #include "lldb/Symbol/UnwindPlan.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Target/Thread.h"
26 #include "lldb/Utility/ConstString.h"
27 #include "lldb/Utility/RegisterValue.h"
28 #include "lldb/Utility/Scalar.h"
29 #include "lldb/Utility/Status.h"
30
31 #include "Plugins/Process/Utility/ARMDefines.h"
32 #include "Utility/ARM_DWARF_Registers.h"
33 #include "Utility/ARM_ehframe_Registers.h"
34
35 using namespace lldb;
36 using namespace lldb_private;
37
38 static const RegisterInfo g_register_infos[] = {
39 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
40 // DWARF GENERIC PROCESS PLUGIN
41 // LLDB NATIVE
42 // ========== ======= == === ============= ============
43 // ======================= =================== ===========================
44 // ======================= ======================
45 {"r0",
46 nullptr,
47 4,
48 0,
49 eEncodingUint,
50 eFormatHex,
51 {ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
52 LLDB_INVALID_REGNUM},
53 nullptr,
54 nullptr,
55 nullptr,
56 },
57 {"r1",
58 nullptr,
59 4,
60 0,
61 eEncodingUint,
62 eFormatHex,
63 {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
64 LLDB_INVALID_REGNUM},
65 nullptr,
66 nullptr,
67 nullptr,
68 },
69 {"r2",
70 nullptr,
71 4,
72 0,
73 eEncodingUint,
74 eFormatHex,
75 {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
76 LLDB_INVALID_REGNUM},
77 nullptr,
78 nullptr,
79 nullptr,
80 },
81 {"r3",
82 nullptr,
83 4,
84 0,
85 eEncodingUint,
86 eFormatHex,
87 {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
88 LLDB_INVALID_REGNUM},
89 nullptr,
90 nullptr,
91 nullptr,
92 },
93 {"r4",
94 nullptr,
95 4,
96 0,
97 eEncodingUint,
98 eFormatHex,
99 {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
100 LLDB_INVALID_REGNUM},
101 nullptr,
102 nullptr,
103 nullptr,
104 },
105 {"r5",
106 nullptr,
107 4,
108 0,
109 eEncodingUint,
110 eFormatHex,
111 {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
112 LLDB_INVALID_REGNUM},
113 nullptr,
114 nullptr,
115 nullptr,
116 },
117 {"r6",
118 nullptr,
119 4,
120 0,
121 eEncodingUint,
122 eFormatHex,
123 {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
124 LLDB_INVALID_REGNUM},
125 nullptr,
126 nullptr,
127 nullptr,
128 },
129 {"r7",
130 nullptr,
131 4,
132 0,
133 eEncodingUint,
134 eFormatHex,
135 {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
136 LLDB_INVALID_REGNUM},
137 nullptr,
138 nullptr,
139 nullptr,
140 },
141 {"r8",
142 nullptr,
143 4,
144 0,
145 eEncodingUint,
146 eFormatHex,
147 {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
148 LLDB_INVALID_REGNUM},
149 nullptr,
150 nullptr,
151 nullptr,
152 },
153 {"r9",
154 nullptr,
155 4,
156 0,
157 eEncodingUint,
158 eFormatHex,
159 {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
160 LLDB_INVALID_REGNUM},
161 nullptr,
162 nullptr,
163 nullptr,
164 },
165 {"r10",
166 nullptr,
167 4,
168 0,
169 eEncodingUint,
170 eFormatHex,
171 {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
172 LLDB_INVALID_REGNUM},
173 nullptr,
174 nullptr,
175 nullptr,
176 },
177 {"r11",
178 nullptr,
179 4,
180 0,
181 eEncodingUint,
182 eFormatHex,
183 {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
184 LLDB_INVALID_REGNUM},
185 nullptr,
186 nullptr,
187 nullptr,
188 },
189 {"r12",
190 nullptr,
191 4,
192 0,
193 eEncodingUint,
194 eFormatHex,
195 {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
196 LLDB_INVALID_REGNUM},
197 nullptr,
198 nullptr,
199 nullptr,
200 },
201 {"sp",
202 "r13",
203 4,
204 0,
205 eEncodingUint,
206 eFormatHex,
207 {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
208 LLDB_INVALID_REGNUM},
209 nullptr,
210 nullptr,
211 nullptr,
212 },
213 {"lr",
214 "r14",
215 4,
216 0,
217 eEncodingUint,
218 eFormatHex,
219 {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
220 LLDB_INVALID_REGNUM},
221 nullptr,
222 nullptr,
223 nullptr,
224 },
225 {"pc",
226 "r15",
227 4,
228 0,
229 eEncodingUint,
230 eFormatHex,
231 {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
232 LLDB_INVALID_REGNUM},
233 nullptr,
234 nullptr,
235 nullptr,
236 },
237 {"cpsr",
238 "psr",
239 4,
240 0,
241 eEncodingUint,
242 eFormatHex,
243 {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
244 LLDB_INVALID_REGNUM},
245 nullptr,
246 nullptr,
247 nullptr,
248 },
249 {"s0",
250 nullptr,
251 4,
252 0,
253 eEncodingIEEE754,
254 eFormatFloat,
255 {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
256 LLDB_INVALID_REGNUM},
257 nullptr,
258 nullptr,
259 nullptr,
260 },
261 {"s1",
262 nullptr,
263 4,
264 0,
265 eEncodingIEEE754,
266 eFormatFloat,
267 {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
268 LLDB_INVALID_REGNUM},
269 nullptr,
270 nullptr,
271 nullptr,
272 },
273 {"s2",
274 nullptr,
275 4,
276 0,
277 eEncodingIEEE754,
278 eFormatFloat,
279 {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
280 LLDB_INVALID_REGNUM},
281 nullptr,
282 nullptr,
283 nullptr,
284 },
285 {"s3",
286 nullptr,
287 4,
288 0,
289 eEncodingIEEE754,
290 eFormatFloat,
291 {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
292 LLDB_INVALID_REGNUM},
293 nullptr,
294 nullptr,
295 nullptr,
296 },
297 {"s4",
298 nullptr,
299 4,
300 0,
301 eEncodingIEEE754,
302 eFormatFloat,
303 {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
304 LLDB_INVALID_REGNUM},
305 nullptr,
306 nullptr,
307 nullptr,
308 },
309 {"s5",
310 nullptr,
311 4,
312 0,
313 eEncodingIEEE754,
314 eFormatFloat,
315 {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
316 LLDB_INVALID_REGNUM},
317 nullptr,
318 nullptr,
319 nullptr,
320 },
321 {"s6",
322 nullptr,
323 4,
324 0,
325 eEncodingIEEE754,
326 eFormatFloat,
327 {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
328 LLDB_INVALID_REGNUM},
329 nullptr,
330 nullptr,
331 nullptr,
332 },
333 {"s7",
334 nullptr,
335 4,
336 0,
337 eEncodingIEEE754,
338 eFormatFloat,
339 {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
340 LLDB_INVALID_REGNUM},
341 nullptr,
342 nullptr,
343 nullptr,
344 },
345 {"s8",
346 nullptr,
347 4,
348 0,
349 eEncodingIEEE754,
350 eFormatFloat,
351 {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
352 LLDB_INVALID_REGNUM},
353 nullptr,
354 nullptr,
355 nullptr,
356 },
357 {"s9",
358 nullptr,
359 4,
360 0,
361 eEncodingIEEE754,
362 eFormatFloat,
363 {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
364 LLDB_INVALID_REGNUM},
365 nullptr,
366 nullptr,
367 nullptr,
368 },
369 {"s10",
370 nullptr,
371 4,
372 0,
373 eEncodingIEEE754,
374 eFormatFloat,
375 {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
376 LLDB_INVALID_REGNUM},
377 nullptr,
378 nullptr,
379 nullptr,
380 },
381 {"s11",
382 nullptr,
383 4,
384 0,
385 eEncodingIEEE754,
386 eFormatFloat,
387 {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
388 LLDB_INVALID_REGNUM},
389 nullptr,
390 nullptr,
391 nullptr,
392 },
393 {"s12",
394 nullptr,
395 4,
396 0,
397 eEncodingIEEE754,
398 eFormatFloat,
399 {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
400 LLDB_INVALID_REGNUM},
401 nullptr,
402 nullptr,
403 nullptr,
404 },
405 {"s13",
406 nullptr,
407 4,
408 0,
409 eEncodingIEEE754,
410 eFormatFloat,
411 {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
412 LLDB_INVALID_REGNUM},
413 nullptr,
414 nullptr,
415 nullptr,
416 },
417 {"s14",
418 nullptr,
419 4,
420 0,
421 eEncodingIEEE754,
422 eFormatFloat,
423 {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
424 LLDB_INVALID_REGNUM},
425 nullptr,
426 nullptr,
427 nullptr,
428 },
429 {"s15",
430 nullptr,
431 4,
432 0,
433 eEncodingIEEE754,
434 eFormatFloat,
435 {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
436 LLDB_INVALID_REGNUM},
437 nullptr,
438 nullptr,
439 nullptr,
440 },
441 {"s16",
442 nullptr,
443 4,
444 0,
445 eEncodingIEEE754,
446 eFormatFloat,
447 {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
448 LLDB_INVALID_REGNUM},
449 nullptr,
450 nullptr,
451 nullptr,
452 },
453 {"s17",
454 nullptr,
455 4,
456 0,
457 eEncodingIEEE754,
458 eFormatFloat,
459 {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
460 LLDB_INVALID_REGNUM},
461 nullptr,
462 nullptr,
463 nullptr,
464 },
465 {"s18",
466 nullptr,
467 4,
468 0,
469 eEncodingIEEE754,
470 eFormatFloat,
471 {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
472 LLDB_INVALID_REGNUM},
473 nullptr,
474 nullptr,
475 nullptr,
476 },
477 {"s19",
478 nullptr,
479 4,
480 0,
481 eEncodingIEEE754,
482 eFormatFloat,
483 {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
484 LLDB_INVALID_REGNUM},
485 nullptr,
486 nullptr,
487 nullptr,
488 },
489 {"s20",
490 nullptr,
491 4,
492 0,
493 eEncodingIEEE754,
494 eFormatFloat,
495 {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
496 LLDB_INVALID_REGNUM},
497 nullptr,
498 nullptr,
499 nullptr,
500 },
501 {"s21",
502 nullptr,
503 4,
504 0,
505 eEncodingIEEE754,
506 eFormatFloat,
507 {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
508 LLDB_INVALID_REGNUM},
509 nullptr,
510 nullptr,
511 nullptr,
512 },
513 {"s22",
514 nullptr,
515 4,
516 0,
517 eEncodingIEEE754,
518 eFormatFloat,
519 {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
520 LLDB_INVALID_REGNUM},
521 nullptr,
522 nullptr,
523 nullptr,
524 },
525 {"s23",
526 nullptr,
527 4,
528 0,
529 eEncodingIEEE754,
530 eFormatFloat,
531 {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
532 LLDB_INVALID_REGNUM},
533 nullptr,
534 nullptr,
535 nullptr,
536 },
537 {"s24",
538 nullptr,
539 4,
540 0,
541 eEncodingIEEE754,
542 eFormatFloat,
543 {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
544 LLDB_INVALID_REGNUM},
545 nullptr,
546 nullptr,
547 nullptr,
548 },
549 {"s25",
550 nullptr,
551 4,
552 0,
553 eEncodingIEEE754,
554 eFormatFloat,
555 {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
556 LLDB_INVALID_REGNUM},
557 nullptr,
558 nullptr,
559 nullptr,
560 },
561 {"s26",
562 nullptr,
563 4,
564 0,
565 eEncodingIEEE754,
566 eFormatFloat,
567 {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
568 LLDB_INVALID_REGNUM},
569 nullptr,
570 nullptr,
571 nullptr,
572 },
573 {"s27",
574 nullptr,
575 4,
576 0,
577 eEncodingIEEE754,
578 eFormatFloat,
579 {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
580 LLDB_INVALID_REGNUM},
581 nullptr,
582 nullptr,
583 nullptr,
584 },
585 {"s28",
586 nullptr,
587 4,
588 0,
589 eEncodingIEEE754,
590 eFormatFloat,
591 {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
592 LLDB_INVALID_REGNUM},
593 nullptr,
594 nullptr,
595 nullptr,
596 },
597 {"s29",
598 nullptr,
599 4,
600 0,
601 eEncodingIEEE754,
602 eFormatFloat,
603 {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
604 LLDB_INVALID_REGNUM},
605 nullptr,
606 nullptr,
607 nullptr,
608 },
609 {"s30",
610 nullptr,
611 4,
612 0,
613 eEncodingIEEE754,
614 eFormatFloat,
615 {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
616 LLDB_INVALID_REGNUM},
617 nullptr,
618 nullptr,
619 nullptr,
620 },
621 {"s31",
622 nullptr,
623 4,
624 0,
625 eEncodingIEEE754,
626 eFormatFloat,
627 {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
628 LLDB_INVALID_REGNUM},
629 nullptr,
630 nullptr,
631 nullptr,
632 },
633 {"fpscr",
634 nullptr,
635 4,
636 0,
637 eEncodingUint,
638 eFormatHex,
639 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
640 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
641 nullptr,
642 nullptr,
643 nullptr,
644 },
645 {"d0",
646 nullptr,
647 8,
648 0,
649 eEncodingIEEE754,
650 eFormatFloat,
651 {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
652 LLDB_INVALID_REGNUM},
653 nullptr,
654 nullptr,
655 nullptr,
656 },
657 {"d1",
658 nullptr,
659 8,
660 0,
661 eEncodingIEEE754,
662 eFormatFloat,
663 {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
664 LLDB_INVALID_REGNUM},
665 nullptr,
666 nullptr,
667 nullptr,
668 },
669 {"d2",
670 nullptr,
671 8,
672 0,
673 eEncodingIEEE754,
674 eFormatFloat,
675 {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
676 LLDB_INVALID_REGNUM},
677 nullptr,
678 nullptr,
679 nullptr,
680 },
681 {"d3",
682 nullptr,
683 8,
684 0,
685 eEncodingIEEE754,
686 eFormatFloat,
687 {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
688 LLDB_INVALID_REGNUM},
689 nullptr,
690 nullptr,
691 nullptr,
692 },
693 {"d4",
694 nullptr,
695 8,
696 0,
697 eEncodingIEEE754,
698 eFormatFloat,
699 {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
700 LLDB_INVALID_REGNUM},
701 nullptr,
702 nullptr,
703 nullptr,
704 },
705 {"d5",
706 nullptr,
707 8,
708 0,
709 eEncodingIEEE754,
710 eFormatFloat,
711 {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
712 LLDB_INVALID_REGNUM},
713 nullptr,
714 nullptr,
715 nullptr,
716 },
717 {"d6",
718 nullptr,
719 8,
720 0,
721 eEncodingIEEE754,
722 eFormatFloat,
723 {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
724 LLDB_INVALID_REGNUM},
725 nullptr,
726 nullptr,
727 nullptr,
728 },
729 {"d7",
730 nullptr,
731 8,
732 0,
733 eEncodingIEEE754,
734 eFormatFloat,
735 {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
736 LLDB_INVALID_REGNUM},
737 nullptr,
738 nullptr,
739 nullptr,
740 },
741 {"d8",
742 nullptr,
743 8,
744 0,
745 eEncodingIEEE754,
746 eFormatFloat,
747 {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
748 LLDB_INVALID_REGNUM},
749 nullptr,
750 nullptr,
751 nullptr,
752 },
753 {"d9",
754 nullptr,
755 8,
756 0,
757 eEncodingIEEE754,
758 eFormatFloat,
759 {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
760 LLDB_INVALID_REGNUM},
761 nullptr,
762 nullptr,
763 nullptr,
764 },
765 {"d10",
766 nullptr,
767 8,
768 0,
769 eEncodingIEEE754,
770 eFormatFloat,
771 {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
772 LLDB_INVALID_REGNUM},
773 nullptr,
774 nullptr,
775 nullptr,
776 },
777 {"d11",
778 nullptr,
779 8,
780 0,
781 eEncodingIEEE754,
782 eFormatFloat,
783 {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
784 LLDB_INVALID_REGNUM},
785 nullptr,
786 nullptr,
787 nullptr,
788 },
789 {"d12",
790 nullptr,
791 8,
792 0,
793 eEncodingIEEE754,
794 eFormatFloat,
795 {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
796 LLDB_INVALID_REGNUM},
797 nullptr,
798 nullptr,
799 nullptr,
800 },
801 {"d13",
802 nullptr,
803 8,
804 0,
805 eEncodingIEEE754,
806 eFormatFloat,
807 {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
808 LLDB_INVALID_REGNUM},
809 nullptr,
810 nullptr,
811 nullptr,
812 },
813 {"d14",
814 nullptr,
815 8,
816 0,
817 eEncodingIEEE754,
818 eFormatFloat,
819 {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
820 LLDB_INVALID_REGNUM},
821 nullptr,
822 nullptr,
823 nullptr,
824 },
825 {"d15",
826 nullptr,
827 8,
828 0,
829 eEncodingIEEE754,
830 eFormatFloat,
831 {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
832 LLDB_INVALID_REGNUM},
833 nullptr,
834 nullptr,
835 nullptr,
836 },
837 {"d16",
838 nullptr,
839 8,
840 0,
841 eEncodingIEEE754,
842 eFormatFloat,
843 {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
844 LLDB_INVALID_REGNUM},
845 nullptr,
846 nullptr,
847 nullptr,
848 },
849 {"d17",
850 nullptr,
851 8,
852 0,
853 eEncodingIEEE754,
854 eFormatFloat,
855 {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
856 LLDB_INVALID_REGNUM},
857 nullptr,
858 nullptr,
859 nullptr,
860 },
861 {"d18",
862 nullptr,
863 8,
864 0,
865 eEncodingIEEE754,
866 eFormatFloat,
867 {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
868 LLDB_INVALID_REGNUM},
869 nullptr,
870 nullptr,
871 nullptr,
872 },
873 {"d19",
874 nullptr,
875 8,
876 0,
877 eEncodingIEEE754,
878 eFormatFloat,
879 {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
880 LLDB_INVALID_REGNUM},
881 nullptr,
882 nullptr,
883 nullptr,
884 },
885 {"d20",
886 nullptr,
887 8,
888 0,
889 eEncodingIEEE754,
890 eFormatFloat,
891 {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
892 LLDB_INVALID_REGNUM},
893 nullptr,
894 nullptr,
895 nullptr,
896 },
897 {"d21",
898 nullptr,
899 8,
900 0,
901 eEncodingIEEE754,
902 eFormatFloat,
903 {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
904 LLDB_INVALID_REGNUM},
905 nullptr,
906 nullptr,
907 nullptr,
908 },
909 {"d22",
910 nullptr,
911 8,
912 0,
913 eEncodingIEEE754,
914 eFormatFloat,
915 {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
916 LLDB_INVALID_REGNUM},
917 nullptr,
918 nullptr,
919 nullptr,
920 },
921 {"d23",
922 nullptr,
923 8,
924 0,
925 eEncodingIEEE754,
926 eFormatFloat,
927 {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
928 LLDB_INVALID_REGNUM},
929 nullptr,
930 nullptr,
931 nullptr,
932 },
933 {"d24",
934 nullptr,
935 8,
936 0,
937 eEncodingIEEE754,
938 eFormatFloat,
939 {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
940 LLDB_INVALID_REGNUM},
941 nullptr,
942 nullptr,
943 nullptr,
944 },
945 {"d25",
946 nullptr,
947 8,
948 0,
949 eEncodingIEEE754,
950 eFormatFloat,
951 {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
952 LLDB_INVALID_REGNUM},
953 nullptr,
954 nullptr,
955 nullptr,
956 },
957 {"d26",
958 nullptr,
959 8,
960 0,
961 eEncodingIEEE754,
962 eFormatFloat,
963 {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
964 LLDB_INVALID_REGNUM},
965 nullptr,
966 nullptr,
967 nullptr,
968 },
969 {"d27",
970 nullptr,
971 8,
972 0,
973 eEncodingIEEE754,
974 eFormatFloat,
975 {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
976 LLDB_INVALID_REGNUM},
977 nullptr,
978 nullptr,
979 nullptr,
980 },
981 {"d28",
982 nullptr,
983 8,
984 0,
985 eEncodingIEEE754,
986 eFormatFloat,
987 {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
988 LLDB_INVALID_REGNUM},
989 nullptr,
990 nullptr,
991 nullptr,
992 },
993 {"d29",
994 nullptr,
995 8,
996 0,
997 eEncodingIEEE754,
998 eFormatFloat,
999 {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1000 LLDB_INVALID_REGNUM},
1001 nullptr,
1002 nullptr,
1003 nullptr,
1004 },
1005 {"d30",
1006 nullptr,
1007 8,
1008 0,
1009 eEncodingIEEE754,
1010 eFormatFloat,
1011 {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1012 LLDB_INVALID_REGNUM},
1013 nullptr,
1014 nullptr,
1015 nullptr,
1016 },
1017 {"d31",
1018 nullptr,
1019 8,
1020 0,
1021 eEncodingIEEE754,
1022 eFormatFloat,
1023 {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1024 LLDB_INVALID_REGNUM},
1025 nullptr,
1026 nullptr,
1027 nullptr,
1028 },
1029 {"r8_usr",
1030 nullptr,
1031 4,
1032 0,
1033 eEncodingUint,
1034 eFormatHex,
1035 {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM,
1036 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1037 nullptr,
1038 nullptr,
1039 nullptr,
1040 },
1041 {"r9_usr",
1042 nullptr,
1043 4,
1044 0,
1045 eEncodingUint,
1046 eFormatHex,
1047 {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM,
1048 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1049 nullptr,
1050 nullptr,
1051 nullptr,
1052 },
1053 {"r10_usr",
1054 nullptr,
1055 4,
1056 0,
1057 eEncodingUint,
1058 eFormatHex,
1059 {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM,
1060 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1061 nullptr,
1062 nullptr,
1063 nullptr,
1064 },
1065 {"r11_usr",
1066 nullptr,
1067 4,
1068 0,
1069 eEncodingUint,
1070 eFormatHex,
1071 {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM,
1072 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1073 nullptr,
1074 nullptr,
1075 nullptr,
1076 },
1077 {"r12_usr",
1078 nullptr,
1079 4,
1080 0,
1081 eEncodingUint,
1082 eFormatHex,
1083 {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM,
1084 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1085 nullptr,
1086 nullptr,
1087 nullptr,
1088 },
1089 {"r13_usr",
1090 "sp_usr",
1091 4,
1092 0,
1093 eEncodingUint,
1094 eFormatHex,
1095 {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM,
1096 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1097 nullptr,
1098 nullptr,
1099 nullptr,
1100 },
1101 {"r14_usr",
1102 "lr_usr",
1103 4,
1104 0,
1105 eEncodingUint,
1106 eFormatHex,
1107 {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM,
1108 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1109 nullptr,
1110 nullptr,
1111 nullptr,
1112 },
1113 {"r8_fiq",
1114 nullptr,
1115 4,
1116 0,
1117 eEncodingUint,
1118 eFormatHex,
1119 {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM,
1120 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1121 nullptr,
1122 nullptr,
1123 nullptr,
1124 },
1125 {"r9_fiq",
1126 nullptr,
1127 4,
1128 0,
1129 eEncodingUint,
1130 eFormatHex,
1131 {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM,
1132 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1133 nullptr,
1134 nullptr,
1135 nullptr,
1136 },
1137 {"r10_fiq",
1138 nullptr,
1139 4,
1140 0,
1141 eEncodingUint,
1142 eFormatHex,
1143 {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM,
1144 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1145 nullptr,
1146 nullptr,
1147 nullptr,
1148 },
1149 {"r11_fiq",
1150 nullptr,
1151 4,
1152 0,
1153 eEncodingUint,
1154 eFormatHex,
1155 {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM,
1156 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1157 nullptr,
1158 nullptr,
1159 nullptr,
1160 },
1161 {"r12_fiq",
1162 nullptr,
1163 4,
1164 0,
1165 eEncodingUint,
1166 eFormatHex,
1167 {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM,
1168 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1169 nullptr,
1170 nullptr,
1171 nullptr,
1172 },
1173 {"r13_fiq",
1174 "sp_fiq",
1175 4,
1176 0,
1177 eEncodingUint,
1178 eFormatHex,
1179 {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM,
1180 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1181 nullptr,
1182 nullptr,
1183 nullptr,
1184 },
1185 {"r14_fiq",
1186 "lr_fiq",
1187 4,
1188 0,
1189 eEncodingUint,
1190 eFormatHex,
1191 {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM,
1192 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1193 nullptr,
1194 nullptr,
1195 nullptr,
1196 },
1197 {"r13_irq",
1198 "sp_irq",
1199 4,
1200 0,
1201 eEncodingUint,
1202 eFormatHex,
1203 {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM,
1204 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1205 nullptr,
1206 nullptr,
1207 nullptr,
1208 },
1209 {"r14_irq",
1210 "lr_irq",
1211 4,
1212 0,
1213 eEncodingUint,
1214 eFormatHex,
1215 {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM,
1216 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1217 nullptr,
1218 nullptr,
1219 nullptr,
1220 },
1221 {"r13_abt",
1222 "sp_abt",
1223 4,
1224 0,
1225 eEncodingUint,
1226 eFormatHex,
1227 {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM,
1228 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1229 nullptr,
1230 nullptr,
1231 nullptr,
1232 },
1233 {"r14_abt",
1234 "lr_abt",
1235 4,
1236 0,
1237 eEncodingUint,
1238 eFormatHex,
1239 {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM,
1240 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1241 nullptr,
1242 nullptr,
1243 nullptr,
1244 },
1245 {"r13_und",
1246 "sp_und",
1247 4,
1248 0,
1249 eEncodingUint,
1250 eFormatHex,
1251 {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM,
1252 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1253 nullptr,
1254 nullptr,
1255 nullptr,
1256 },
1257 {"r14_und",
1258 "lr_und",
1259 4,
1260 0,
1261 eEncodingUint,
1262 eFormatHex,
1263 {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM,
1264 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1265 nullptr,
1266 nullptr,
1267 nullptr,
1268 },
1269 {"r13_svc",
1270 "sp_svc",
1271 4,
1272 0,
1273 eEncodingUint,
1274 eFormatHex,
1275 {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM,
1276 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1277 nullptr,
1278 nullptr,
1279 nullptr,
1280 },
1281 {"r14_svc",
1282 "lr_svc",
1283 4,
1284 0,
1285 eEncodingUint,
1286 eFormatHex,
1287 {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM,
1288 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1289 nullptr,
1290 nullptr,
1291 nullptr,
1292 }};
1293
1294 static const uint32_t k_num_register_infos = std::size(g_register_infos);
1295
1296 const lldb_private::RegisterInfo *
GetRegisterInfoArray(uint32_t & count)1297 ABIMacOSX_arm::GetRegisterInfoArray(uint32_t &count) {
1298 count = k_num_register_infos;
1299 return g_register_infos;
1300 }
1301
GetRedZoneSize() const1302 size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; }
1303
1304 // Static Functions
1305
1306 ABISP
CreateInstance(ProcessSP process_sp,const ArchSpec & arch)1307 ABIMacOSX_arm::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) {
1308 const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1309 const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1310
1311 if (vendor_type == llvm::Triple::Apple) {
1312 if ((arch_type == llvm::Triple::arm) ||
1313 (arch_type == llvm::Triple::thumb)) {
1314 return ABISP(
1315 new ABIMacOSX_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1316 }
1317 }
1318
1319 return ABISP();
1320 }
1321
PrepareTrivialCall(Thread & thread,addr_t sp,addr_t function_addr,addr_t return_addr,llvm::ArrayRef<addr_t> args) const1322 bool ABIMacOSX_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
1323 addr_t function_addr, addr_t return_addr,
1324 llvm::ArrayRef<addr_t> args) const {
1325 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1326 if (!reg_ctx)
1327 return false;
1328
1329 const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1330 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1331 const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1332 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1333 const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1334 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1335
1336 RegisterValue reg_value;
1337
1338 const char *reg_names[] = {"r0", "r1", "r2", "r3"};
1339
1340 llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1341
1342 for (size_t i = 0; i < std::size(reg_names); ++i) {
1343 if (ai == ae)
1344 break;
1345
1346 reg_value.SetUInt32(*ai);
1347 if (!reg_ctx->WriteRegister(reg_ctx->GetRegisterInfoByName(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 16 byte aligned
1360 sp &= ~(16ull - 1ull);
1361
1362 // just using arg1 to get the right size
1363 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1364 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
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 // If bit zero or 1 is set, this must be a thumb function, no need to figure
1393 // this out from the symbols.
1394 so_addr.SetLoadAddress(function_addr, target_sp.get());
1395 function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1396
1397 const RegisterInfo *cpsr_reg_info = reg_ctx->GetRegisterInfoByName("cpsr");
1398 const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
1399
1400 // Make a new CPSR and mask out any Thumb IT (if/then) bits
1401 uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1402 // If bit zero or 1 is set, this must be thumb...
1403 if (function_addr & 1ull)
1404 new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1405 else
1406 new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1407
1408 if (new_cpsr != curr_cpsr) {
1409 if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1410 return false;
1411 }
1412
1413 function_addr &=
1414 ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1415
1416 // Update the sp - stack pointer - to be aligned to 16-bytes
1417 sp &= ~(0xfull);
1418 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1419 return false;
1420
1421 // Set "pc" to the address requested
1422 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr))
1423 return false;
1424
1425 return true;
1426 }
1427
GetArgumentValues(Thread & thread,ValueList & values) const1428 bool ABIMacOSX_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
1429 uint32_t num_values = values.GetSize();
1430
1431 ExecutionContext exe_ctx(thread.shared_from_this());
1432 // For now, assume that the types in the AST values come from the Target's
1433 // scratch AST.
1434
1435 // Extract the register context so we can read arguments from registers
1436
1437 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1438
1439 if (!reg_ctx)
1440 return false;
1441
1442 addr_t sp = 0;
1443
1444 for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1445 // We currently only support extracting values with Clang QualTypes. Do we
1446 // care about others?
1447 Value *value = values.GetValueAtIndex(value_idx);
1448
1449 if (!value)
1450 return false;
1451
1452 CompilerType compiler_type = value->GetCompilerType();
1453 if (compiler_type) {
1454 bool is_signed = false;
1455 size_t bit_width = 0;
1456 std::optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
1457 if (!bit_size)
1458 return false;
1459 if (compiler_type.IsIntegerOrEnumerationType(is_signed))
1460 bit_width = *bit_size;
1461 else if (compiler_type.IsPointerOrReferenceType())
1462 bit_width = *bit_size;
1463 else
1464 // We only handle integer, pointer and reference types currently...
1465 return false;
1466
1467 if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1468 if (value_idx < 4) {
1469 // Arguments 1-4 are in r0-r3...
1470 const RegisterInfo *arg_reg_info = nullptr;
1471 // Search by generic ID first, then fall back to by name
1472 uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1473 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
1474 if (arg_reg_num != LLDB_INVALID_REGNUM) {
1475 arg_reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num);
1476 } else {
1477 switch (value_idx) {
1478 case 0:
1479 arg_reg_info = reg_ctx->GetRegisterInfoByName("r0");
1480 break;
1481 case 1:
1482 arg_reg_info = reg_ctx->GetRegisterInfoByName("r1");
1483 break;
1484 case 2:
1485 arg_reg_info = reg_ctx->GetRegisterInfoByName("r2");
1486 break;
1487 case 3:
1488 arg_reg_info = reg_ctx->GetRegisterInfoByName("r3");
1489 break;
1490 }
1491 }
1492
1493 if (arg_reg_info) {
1494 RegisterValue reg_value;
1495
1496 if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1497 if (is_signed)
1498 reg_value.SignExtend(bit_width);
1499 if (!reg_value.GetScalarValue(value->GetScalar()))
1500 return false;
1501 continue;
1502 }
1503 }
1504 return false;
1505 } else {
1506 if (sp == 0) {
1507 // Read the stack pointer if it already hasn't been read
1508 sp = reg_ctx->GetSP(0);
1509 if (sp == 0)
1510 return false;
1511 }
1512
1513 // Arguments 5 on up are on the stack
1514 const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1515 Status error;
1516 if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
1517 sp, arg_byte_size, is_signed, value->GetScalar(), error))
1518 return false;
1519
1520 sp += arg_byte_size;
1521 }
1522 }
1523 }
1524 }
1525 return true;
1526 }
1527
IsArmv7kProcess() const1528 bool ABIMacOSX_arm::IsArmv7kProcess() const {
1529 bool is_armv7k = false;
1530 ProcessSP process_sp(GetProcessSP());
1531 if (process_sp) {
1532 const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1533 const ArchSpec::Core system_core = arch.GetCore();
1534 if (system_core == ArchSpec::eCore_arm_armv7k) {
1535 is_armv7k = true;
1536 }
1537 }
1538 return is_armv7k;
1539 }
1540
GetReturnValueObjectImpl(Thread & thread,lldb_private::CompilerType & compiler_type) const1541 ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl(
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.SetCompilerType(compiler_type);
1550
1551 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1552 if (!reg_ctx)
1553 return return_valobj_sp;
1554
1555 bool is_signed;
1556
1557 // Get the pointer to the first stack argument so we have a place to start
1558 // when reading data
1559
1560 const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0);
1561 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1562 std::optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
1563 if (!bit_width)
1564 return return_valobj_sp;
1565
1566 switch (*bit_width) {
1567 default:
1568 return return_valobj_sp;
1569 case 128:
1570 if (IsArmv7kProcess()) {
1571 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1572 // format is as if the result had been stored in memory at a word-
1573 // aligned address and then loaded into r0-r3 with an ldm instruction"
1574 {
1575 const RegisterInfo *r1_reg_info =
1576 reg_ctx->GetRegisterInfoByName("r1", 0);
1577 const RegisterInfo *r2_reg_info =
1578 reg_ctx->GetRegisterInfoByName("r2", 0);
1579 const RegisterInfo *r3_reg_info =
1580 reg_ctx->GetRegisterInfoByName("r3", 0);
1581 if (r1_reg_info && r2_reg_info && r3_reg_info) {
1582 std::optional<uint64_t> byte_size =
1583 compiler_type.GetByteSize(&thread);
1584 if (!byte_size)
1585 return return_valobj_sp;
1586 ProcessSP process_sp(thread.GetProcess());
1587 if (*byte_size <= r0_reg_info->byte_size + r1_reg_info->byte_size +
1588 r2_reg_info->byte_size +
1589 r3_reg_info->byte_size &&
1590 process_sp) {
1591 std::unique_ptr<DataBufferHeap> heap_data_up(
1592 new DataBufferHeap(*byte_size, 0));
1593 const ByteOrder byte_order = process_sp->GetByteOrder();
1594 RegisterValue r0_reg_value;
1595 RegisterValue r1_reg_value;
1596 RegisterValue r2_reg_value;
1597 RegisterValue r3_reg_value;
1598 if (reg_ctx->ReadRegister(r0_reg_info, r0_reg_value) &&
1599 reg_ctx->ReadRegister(r1_reg_info, r1_reg_value) &&
1600 reg_ctx->ReadRegister(r2_reg_info, r2_reg_value) &&
1601 reg_ctx->ReadRegister(r3_reg_info, r3_reg_value)) {
1602 Status error;
1603 if (r0_reg_value.GetAsMemoryData(*r0_reg_info,
1604 heap_data_up->GetBytes() + 0,
1605 4, byte_order, error) &&
1606 r1_reg_value.GetAsMemoryData(*r1_reg_info,
1607 heap_data_up->GetBytes() + 4,
1608 4, byte_order, error) &&
1609 r2_reg_value.GetAsMemoryData(*r2_reg_info,
1610 heap_data_up->GetBytes() + 8,
1611 4, byte_order, error) &&
1612 r3_reg_value.GetAsMemoryData(*r3_reg_info,
1613 heap_data_up->GetBytes() + 12,
1614 4, byte_order, error)) {
1615 DataExtractor data(DataBufferSP(heap_data_up.release()),
1616 byte_order,
1617 process_sp->GetAddressByteSize());
1618
1619 return_valobj_sp = ValueObjectConstResult::Create(
1620 &thread, compiler_type, ConstString(""), data);
1621 return return_valobj_sp;
1622 }
1623 }
1624 }
1625 }
1626 }
1627 } else {
1628 return return_valobj_sp;
1629 }
1630 break;
1631 case 64: {
1632 const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfoByName("r1", 0);
1633 uint64_t raw_value;
1634 raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1635 raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1636 UINT32_MAX))
1637 << 32;
1638 if (is_signed)
1639 value.GetScalar() = (int64_t)raw_value;
1640 else
1641 value.GetScalar() = (uint64_t)raw_value;
1642 } break;
1643 case 32:
1644 if (is_signed)
1645 value.GetScalar() = (int32_t)(
1646 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1647 else
1648 value.GetScalar() = (uint32_t)(
1649 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1650 break;
1651 case 16:
1652 if (is_signed)
1653 value.GetScalar() = (int16_t)(
1654 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1655 else
1656 value.GetScalar() = (uint16_t)(
1657 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1658 break;
1659 case 8:
1660 if (is_signed)
1661 value.GetScalar() = (int8_t)(
1662 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1663 else
1664 value.GetScalar() = (uint8_t)(
1665 reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1666 break;
1667 }
1668 } else if (compiler_type.IsPointerType()) {
1669 uint32_t ptr =
1670 thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1671 UINT32_MAX;
1672 value.GetScalar() = ptr;
1673 } else {
1674 // not handled yet
1675 return return_valobj_sp;
1676 }
1677
1678 // If we get here, we have a valid Value, so make our ValueObject out of it:
1679
1680 return_valobj_sp = ValueObjectConstResult::Create(
1681 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1682 return return_valobj_sp;
1683 }
1684
SetReturnValueObject(lldb::StackFrameSP & frame_sp,lldb::ValueObjectSP & new_value_sp)1685 Status ABIMacOSX_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1686 lldb::ValueObjectSP &new_value_sp) {
1687 Status error;
1688 if (!new_value_sp) {
1689 error.SetErrorString("Empty value object for return value.");
1690 return error;
1691 }
1692
1693 CompilerType compiler_type = new_value_sp->GetCompilerType();
1694 if (!compiler_type) {
1695 error.SetErrorString("Null clang type for return value.");
1696 return error;
1697 }
1698
1699 Thread *thread = frame_sp->GetThread().get();
1700
1701 bool is_signed;
1702 uint32_t count;
1703 bool is_complex;
1704
1705 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1706
1707 bool set_it_simple = false;
1708 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1709 compiler_type.IsPointerType()) {
1710 DataExtractor data;
1711 Status data_error;
1712 size_t num_bytes = new_value_sp->GetData(data, data_error);
1713 if (data_error.Fail()) {
1714 error.SetErrorStringWithFormat(
1715 "Couldn't convert return value to raw data: %s",
1716 data_error.AsCString());
1717 return error;
1718 }
1719 lldb::offset_t offset = 0;
1720 if (num_bytes <= 8) {
1721 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
1722 if (num_bytes <= 4) {
1723 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1724
1725 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1726 set_it_simple = true;
1727 } else {
1728 uint32_t raw_value = data.GetMaxU32(&offset, 4);
1729
1730 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1731 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
1732 uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1733
1734 if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1735 set_it_simple = true;
1736 }
1737 }
1738 } else if (num_bytes <= 16 && IsArmv7kProcess()) {
1739 // "A composite type not larger than 16 bytes is returned in r0-r3. The
1740 // format is as if the result had been stored in memory at a word-aligned
1741 // address and then loaded into r0-r3 with an ldm instruction"
1742
1743 const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
1744 const RegisterInfo *r1_info = reg_ctx->GetRegisterInfoByName("r1", 0);
1745 const RegisterInfo *r2_info = reg_ctx->GetRegisterInfoByName("r2", 0);
1746 const RegisterInfo *r3_info = reg_ctx->GetRegisterInfoByName("r3", 0);
1747 lldb::offset_t offset = 0;
1748 uint32_t bytes_written = 4;
1749 uint32_t raw_value = data.GetMaxU64(&offset, 4);
1750 if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value) &&
1751 bytes_written <= num_bytes) {
1752 bytes_written += 4;
1753 raw_value = data.GetMaxU64(&offset, 4);
1754 if (bytes_written <= num_bytes &&
1755 reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value)) {
1756 bytes_written += 4;
1757 raw_value = data.GetMaxU64(&offset, 4);
1758 if (bytes_written <= num_bytes &&
1759 reg_ctx->WriteRegisterFromUnsigned(r2_info, raw_value)) {
1760 bytes_written += 4;
1761 raw_value = data.GetMaxU64(&offset, 4);
1762 if (bytes_written <= num_bytes &&
1763 reg_ctx->WriteRegisterFromUnsigned(r3_info, raw_value)) {
1764 set_it_simple = true;
1765 }
1766 }
1767 }
1768 }
1769 } else {
1770 error.SetErrorString("We don't support returning longer than 64 bit "
1771 "integer values at present.");
1772 }
1773 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1774 if (is_complex)
1775 error.SetErrorString(
1776 "We don't support returning complex values at present");
1777 else
1778 error.SetErrorString(
1779 "We don't support returning float values at present");
1780 }
1781
1782 if (!set_it_simple)
1783 error.SetErrorString(
1784 "We only support setting simple integer return types at present.");
1785
1786 return error;
1787 }
1788
CreateFunctionEntryUnwindPlan(UnwindPlan & unwind_plan)1789 bool ABIMacOSX_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1790 unwind_plan.Clear();
1791 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1792
1793 uint32_t lr_reg_num = dwarf_lr;
1794 uint32_t sp_reg_num = dwarf_sp;
1795 uint32_t pc_reg_num = dwarf_pc;
1796
1797 UnwindPlan::RowSP row(new UnwindPlan::Row);
1798
1799 // Our Call Frame Address is the stack pointer value
1800 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1801
1802 // The previous PC is in the LR
1803 row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1804 unwind_plan.AppendRow(row);
1805
1806 // All other registers are the same.
1807
1808 unwind_plan.SetSourceName("arm at-func-entry default");
1809 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1810
1811 return true;
1812 }
1813
CreateDefaultUnwindPlan(UnwindPlan & unwind_plan)1814 bool ABIMacOSX_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1815 unwind_plan.Clear();
1816 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1817
1818 uint32_t fp_reg_num =
1819 dwarf_r7; // apple uses r7 for all frames. Normal arm uses r11
1820 uint32_t pc_reg_num = dwarf_pc;
1821
1822 UnwindPlan::RowSP row(new UnwindPlan::Row);
1823 const int32_t ptr_size = 4;
1824
1825 row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1826 row->SetOffset(0);
1827 row->SetUnspecifiedRegistersAreUndefined(true);
1828
1829 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1830 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1831
1832 unwind_plan.AppendRow(row);
1833 unwind_plan.SetSourceName("arm-apple-ios default unwind plan");
1834 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1835 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1836 unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1837
1838 return true;
1839 }
1840
1841 // cf. "ARMv6 Function Calling Conventions"
1842 // https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html
1843 // and "ARMv7 Function Calling Conventions"
1844 // https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARMv7FunctionCallingConventions.html
1845
1846 // ARMv7 on iOS general purpose reg rules:
1847 // r0-r3 not preserved (used for argument passing)
1848 // r4-r6 preserved
1849 // r7 preserved (frame pointer)
1850 // r8 preserved
1851 // r9 not preserved (usable as volatile scratch register with iOS 3.x and
1852 // later)
1853 // r10-r11 preserved
1854 // r12 not presrved
1855 // r13 preserved (stack pointer)
1856 // r14 not preserved (link register)
1857 // r15 preserved (pc)
1858 // cpsr not preserved (different rules for different bits)
1859
1860 // ARMv7 on iOS floating point rules:
1861 // d0-d7 not preserved (aka s0-s15, q0-q3)
1862 // d8-d15 preserved (aka s16-s31, q4-q7)
1863 // d16-d31 not preserved (aka q8-q15)
1864
RegisterIsVolatile(const RegisterInfo * reg_info)1865 bool ABIMacOSX_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
1866 if (reg_info) {
1867 // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1868 const char *name = reg_info->name;
1869 if (name[0] == 'r') {
1870 switch (name[1]) {
1871 case '0':
1872 return name[2] == '\0'; // r0
1873 case '1':
1874 switch (name[2]) {
1875 case '\0':
1876 return true; // r1
1877 case '2':
1878 case '3':
1879 return name[3] == '\0'; // r12, r13 (sp)
1880 default:
1881 break;
1882 }
1883 break;
1884
1885 case '2':
1886 return name[2] == '\0'; // r2
1887 case '3':
1888 return name[2] == '\0'; // r3
1889 case '9':
1890 return name[2] == '\0'; // r9 (apple-ios only...)
1891
1892 break;
1893 }
1894 } else if (name[0] == 'd') {
1895 switch (name[1]) {
1896 case '0':
1897 return name[2] == '\0'; // d0 is volatile
1898
1899 case '1':
1900 switch (name[2]) {
1901 case '\0':
1902 return true; // d1 is volatile
1903 case '6':
1904 case '7':
1905 case '8':
1906 case '9':
1907 return name[3] == '\0'; // d16 - d19 are volatile
1908 default:
1909 break;
1910 }
1911 break;
1912
1913 case '2':
1914 switch (name[2]) {
1915 case '\0':
1916 return true; // d2 is volatile
1917 case '0':
1918 case '1':
1919 case '2':
1920 case '3':
1921 case '4':
1922 case '5':
1923 case '6':
1924 case '7':
1925 case '8':
1926 case '9':
1927 return name[3] == '\0'; // d20 - d29 are volatile
1928 default:
1929 break;
1930 }
1931 break;
1932
1933 case '3':
1934 switch (name[2]) {
1935 case '\0':
1936 return true; // d3 is volatile
1937 case '0':
1938 case '1':
1939 return name[3] == '\0'; // d30 - d31 are volatile
1940 default:
1941 break;
1942 }
1943 break;
1944 case '4':
1945 case '5':
1946 case '6':
1947 case '7':
1948 return name[2] == '\0'; // d4 - d7 are volatile
1949
1950 default:
1951 break;
1952 }
1953 } else if (name[0] == 's') {
1954 switch (name[1]) {
1955 case '0':
1956 return name[2] == '\0'; // s0 is volatile
1957
1958 case '1':
1959 switch (name[2]) {
1960 case '\0':
1961 return true; // s1 is volatile
1962 case '0':
1963 case '1':
1964 case '2':
1965 case '3':
1966 case '4':
1967 case '5':
1968 return name[3] == '\0'; // s10 - s15 are volatile
1969 default:
1970 break;
1971 }
1972 break;
1973
1974 case '2':
1975 case '3':
1976 case '4':
1977 case '5':
1978 case '6':
1979 case '7':
1980 case '8':
1981 case '9':
1982 return name[2] == '\0'; // s2 - s9 are volatile
1983
1984 default:
1985 break;
1986 }
1987 } else if (name[0] == 'q') {
1988 switch (name[1]) {
1989 case '1':
1990 switch (name[2]) {
1991 case '\0':
1992 return true; // q1 is volatile
1993 case '0':
1994 case '1':
1995 case '2':
1996 case '3':
1997 case '4':
1998 case '5':
1999 return true; // q10-q15 are volatile
2000 default:
2001 break;
2002 };
2003 break;
2004 case '0':
2005 case '2':
2006 case '3':
2007 return name[2] == '\0'; // q0-q3 are volatile
2008 case '8':
2009 case '9':
2010 return name[2] == '\0'; // q8-q9 are volatile
2011 default:
2012 break;
2013 }
2014 } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2015 return true;
2016 }
2017 return false;
2018 }
2019
Initialize()2020 void ABIMacOSX_arm::Initialize() {
2021 PluginManager::RegisterPlugin(GetPluginNameStatic(),
2022 "Mac OS X ABI for arm targets", CreateInstance);
2023 }
2024
Terminate()2025 void ABIMacOSX_arm::Terminate() {
2026 PluginManager::UnregisterPlugin(CreateInstance);
2027 }
2028