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