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/ADT/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     },
56     {"r1",
57      nullptr,
58      4,
59      0,
60      eEncodingUint,
61      eFormatHex,
62      {ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
63       LLDB_INVALID_REGNUM},
64      nullptr,
65      nullptr,
66     },
67     {"r2",
68      nullptr,
69      4,
70      0,
71      eEncodingUint,
72      eFormatHex,
73      {ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
74       LLDB_INVALID_REGNUM},
75      nullptr,
76      nullptr,
77     },
78     {"r3",
79      nullptr,
80      4,
81      0,
82      eEncodingUint,
83      eFormatHex,
84      {ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
85       LLDB_INVALID_REGNUM},
86      nullptr,
87      nullptr,
88     },
89     {"r4",
90      nullptr,
91      4,
92      0,
93      eEncodingUint,
94      eFormatHex,
95      {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
96       LLDB_INVALID_REGNUM},
97      nullptr,
98      nullptr,
99     },
100     {"r5",
101      nullptr,
102      4,
103      0,
104      eEncodingUint,
105      eFormatHex,
106      {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
107       LLDB_INVALID_REGNUM},
108      nullptr,
109      nullptr,
110     },
111     {"r6",
112      nullptr,
113      4,
114      0,
115      eEncodingUint,
116      eFormatHex,
117      {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
118       LLDB_INVALID_REGNUM},
119      nullptr,
120      nullptr,
121     },
122     {"r7",
123      nullptr,
124      4,
125      0,
126      eEncodingUint,
127      eFormatHex,
128      {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
129       LLDB_INVALID_REGNUM},
130      nullptr,
131      nullptr,
132     },
133     {"r8",
134      nullptr,
135      4,
136      0,
137      eEncodingUint,
138      eFormatHex,
139      {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
140       LLDB_INVALID_REGNUM},
141      nullptr,
142      nullptr,
143     },
144     {"r9",
145      nullptr,
146      4,
147      0,
148      eEncodingUint,
149      eFormatHex,
150      {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
151       LLDB_INVALID_REGNUM},
152      nullptr,
153      nullptr,
154     },
155     {"r10",
156      nullptr,
157      4,
158      0,
159      eEncodingUint,
160      eFormatHex,
161      {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
162       LLDB_INVALID_REGNUM},
163      nullptr,
164      nullptr,
165     },
166     {"r11",
167      nullptr,
168      4,
169      0,
170      eEncodingUint,
171      eFormatHex,
172      {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
173       LLDB_INVALID_REGNUM},
174      nullptr,
175      nullptr,
176     },
177     {"r12",
178      nullptr,
179      4,
180      0,
181      eEncodingUint,
182      eFormatHex,
183      {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
184       LLDB_INVALID_REGNUM},
185      nullptr,
186      nullptr,
187     },
188     {"sp",
189      "r13",
190      4,
191      0,
192      eEncodingUint,
193      eFormatHex,
194      {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
195       LLDB_INVALID_REGNUM},
196      nullptr,
197      nullptr,
198     },
199     {"lr",
200      "r14",
201      4,
202      0,
203      eEncodingUint,
204      eFormatHex,
205      {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
206       LLDB_INVALID_REGNUM},
207      nullptr,
208      nullptr,
209     },
210     {"pc",
211      "r15",
212      4,
213      0,
214      eEncodingUint,
215      eFormatHex,
216      {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
217       LLDB_INVALID_REGNUM},
218      nullptr,
219      nullptr,
220     },
221     {"cpsr",
222      "psr",
223      4,
224      0,
225      eEncodingUint,
226      eFormatHex,
227      {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
228       LLDB_INVALID_REGNUM},
229      nullptr,
230      nullptr,
231     },
232     {"s0",
233      nullptr,
234      4,
235      0,
236      eEncodingIEEE754,
237      eFormatFloat,
238      {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
239       LLDB_INVALID_REGNUM},
240      nullptr,
241      nullptr,
242     },
243     {"s1",
244      nullptr,
245      4,
246      0,
247      eEncodingIEEE754,
248      eFormatFloat,
249      {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
250       LLDB_INVALID_REGNUM},
251      nullptr,
252      nullptr,
253     },
254     {"s2",
255      nullptr,
256      4,
257      0,
258      eEncodingIEEE754,
259      eFormatFloat,
260      {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
261       LLDB_INVALID_REGNUM},
262      nullptr,
263      nullptr,
264     },
265     {"s3",
266      nullptr,
267      4,
268      0,
269      eEncodingIEEE754,
270      eFormatFloat,
271      {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
272       LLDB_INVALID_REGNUM},
273      nullptr,
274      nullptr,
275     },
276     {"s4",
277      nullptr,
278      4,
279      0,
280      eEncodingIEEE754,
281      eFormatFloat,
282      {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
283       LLDB_INVALID_REGNUM},
284      nullptr,
285      nullptr,
286     },
287     {"s5",
288      nullptr,
289      4,
290      0,
291      eEncodingIEEE754,
292      eFormatFloat,
293      {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
294       LLDB_INVALID_REGNUM},
295      nullptr,
296      nullptr,
297     },
298     {"s6",
299      nullptr,
300      4,
301      0,
302      eEncodingIEEE754,
303      eFormatFloat,
304      {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
305       LLDB_INVALID_REGNUM},
306      nullptr,
307      nullptr,
308     },
309     {"s7",
310      nullptr,
311      4,
312      0,
313      eEncodingIEEE754,
314      eFormatFloat,
315      {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
316       LLDB_INVALID_REGNUM},
317      nullptr,
318      nullptr,
319     },
320     {"s8",
321      nullptr,
322      4,
323      0,
324      eEncodingIEEE754,
325      eFormatFloat,
326      {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
327       LLDB_INVALID_REGNUM},
328      nullptr,
329      nullptr,
330     },
331     {"s9",
332      nullptr,
333      4,
334      0,
335      eEncodingIEEE754,
336      eFormatFloat,
337      {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
338       LLDB_INVALID_REGNUM},
339      nullptr,
340      nullptr,
341     },
342     {"s10",
343      nullptr,
344      4,
345      0,
346      eEncodingIEEE754,
347      eFormatFloat,
348      {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
349       LLDB_INVALID_REGNUM},
350      nullptr,
351      nullptr,
352     },
353     {"s11",
354      nullptr,
355      4,
356      0,
357      eEncodingIEEE754,
358      eFormatFloat,
359      {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
360       LLDB_INVALID_REGNUM},
361      nullptr,
362      nullptr,
363     },
364     {"s12",
365      nullptr,
366      4,
367      0,
368      eEncodingIEEE754,
369      eFormatFloat,
370      {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
371       LLDB_INVALID_REGNUM},
372      nullptr,
373      nullptr,
374     },
375     {"s13",
376      nullptr,
377      4,
378      0,
379      eEncodingIEEE754,
380      eFormatFloat,
381      {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
382       LLDB_INVALID_REGNUM},
383      nullptr,
384      nullptr,
385     },
386     {"s14",
387      nullptr,
388      4,
389      0,
390      eEncodingIEEE754,
391      eFormatFloat,
392      {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
393       LLDB_INVALID_REGNUM},
394      nullptr,
395      nullptr,
396     },
397     {"s15",
398      nullptr,
399      4,
400      0,
401      eEncodingIEEE754,
402      eFormatFloat,
403      {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
404       LLDB_INVALID_REGNUM},
405      nullptr,
406      nullptr,
407     },
408     {"s16",
409      nullptr,
410      4,
411      0,
412      eEncodingIEEE754,
413      eFormatFloat,
414      {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
415       LLDB_INVALID_REGNUM},
416      nullptr,
417      nullptr,
418     },
419     {"s17",
420      nullptr,
421      4,
422      0,
423      eEncodingIEEE754,
424      eFormatFloat,
425      {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
426       LLDB_INVALID_REGNUM},
427      nullptr,
428      nullptr,
429     },
430     {"s18",
431      nullptr,
432      4,
433      0,
434      eEncodingIEEE754,
435      eFormatFloat,
436      {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
437       LLDB_INVALID_REGNUM},
438      nullptr,
439      nullptr,
440     },
441     {"s19",
442      nullptr,
443      4,
444      0,
445      eEncodingIEEE754,
446      eFormatFloat,
447      {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
448       LLDB_INVALID_REGNUM},
449      nullptr,
450      nullptr,
451     },
452     {"s20",
453      nullptr,
454      4,
455      0,
456      eEncodingIEEE754,
457      eFormatFloat,
458      {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
459       LLDB_INVALID_REGNUM},
460      nullptr,
461      nullptr,
462     },
463     {"s21",
464      nullptr,
465      4,
466      0,
467      eEncodingIEEE754,
468      eFormatFloat,
469      {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
470       LLDB_INVALID_REGNUM},
471      nullptr,
472      nullptr,
473     },
474     {"s22",
475      nullptr,
476      4,
477      0,
478      eEncodingIEEE754,
479      eFormatFloat,
480      {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
481       LLDB_INVALID_REGNUM},
482      nullptr,
483      nullptr,
484     },
485     {"s23",
486      nullptr,
487      4,
488      0,
489      eEncodingIEEE754,
490      eFormatFloat,
491      {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
492       LLDB_INVALID_REGNUM},
493      nullptr,
494      nullptr,
495     },
496     {"s24",
497      nullptr,
498      4,
499      0,
500      eEncodingIEEE754,
501      eFormatFloat,
502      {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
503       LLDB_INVALID_REGNUM},
504      nullptr,
505      nullptr,
506     },
507     {"s25",
508      nullptr,
509      4,
510      0,
511      eEncodingIEEE754,
512      eFormatFloat,
513      {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
514       LLDB_INVALID_REGNUM},
515      nullptr,
516      nullptr,
517     },
518     {"s26",
519      nullptr,
520      4,
521      0,
522      eEncodingIEEE754,
523      eFormatFloat,
524      {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
525       LLDB_INVALID_REGNUM},
526      nullptr,
527      nullptr,
528     },
529     {"s27",
530      nullptr,
531      4,
532      0,
533      eEncodingIEEE754,
534      eFormatFloat,
535      {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
536       LLDB_INVALID_REGNUM},
537      nullptr,
538      nullptr,
539     },
540     {"s28",
541      nullptr,
542      4,
543      0,
544      eEncodingIEEE754,
545      eFormatFloat,
546      {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
547       LLDB_INVALID_REGNUM},
548      nullptr,
549      nullptr,
550     },
551     {"s29",
552      nullptr,
553      4,
554      0,
555      eEncodingIEEE754,
556      eFormatFloat,
557      {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
558       LLDB_INVALID_REGNUM},
559      nullptr,
560      nullptr,
561     },
562     {"s30",
563      nullptr,
564      4,
565      0,
566      eEncodingIEEE754,
567      eFormatFloat,
568      {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
569       LLDB_INVALID_REGNUM},
570      nullptr,
571      nullptr,
572     },
573     {"s31",
574      nullptr,
575      4,
576      0,
577      eEncodingIEEE754,
578      eFormatFloat,
579      {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
580       LLDB_INVALID_REGNUM},
581      nullptr,
582      nullptr,
583     },
584     {"fpscr",
585      nullptr,
586      4,
587      0,
588      eEncodingUint,
589      eFormatHex,
590      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
591       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
592      nullptr,
593      nullptr,
594     },
595     {"d0",
596      nullptr,
597      8,
598      0,
599      eEncodingIEEE754,
600      eFormatFloat,
601      {LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
602       LLDB_INVALID_REGNUM},
603      nullptr,
604      nullptr,
605     },
606     {"d1",
607      nullptr,
608      8,
609      0,
610      eEncodingIEEE754,
611      eFormatFloat,
612      {LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
613       LLDB_INVALID_REGNUM},
614      nullptr,
615      nullptr,
616     },
617     {"d2",
618      nullptr,
619      8,
620      0,
621      eEncodingIEEE754,
622      eFormatFloat,
623      {LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
624       LLDB_INVALID_REGNUM},
625      nullptr,
626      nullptr,
627     },
628     {"d3",
629      nullptr,
630      8,
631      0,
632      eEncodingIEEE754,
633      eFormatFloat,
634      {LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
635       LLDB_INVALID_REGNUM},
636      nullptr,
637      nullptr,
638     },
639     {"d4",
640      nullptr,
641      8,
642      0,
643      eEncodingIEEE754,
644      eFormatFloat,
645      {LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
646       LLDB_INVALID_REGNUM},
647      nullptr,
648      nullptr,
649     },
650     {"d5",
651      nullptr,
652      8,
653      0,
654      eEncodingIEEE754,
655      eFormatFloat,
656      {LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
657       LLDB_INVALID_REGNUM},
658      nullptr,
659      nullptr,
660     },
661     {"d6",
662      nullptr,
663      8,
664      0,
665      eEncodingIEEE754,
666      eFormatFloat,
667      {LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
668       LLDB_INVALID_REGNUM},
669      nullptr,
670      nullptr,
671     },
672     {"d7",
673      nullptr,
674      8,
675      0,
676      eEncodingIEEE754,
677      eFormatFloat,
678      {LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
679       LLDB_INVALID_REGNUM},
680      nullptr,
681      nullptr,
682     },
683     {"d8",
684      nullptr,
685      8,
686      0,
687      eEncodingIEEE754,
688      eFormatFloat,
689      {LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
690       LLDB_INVALID_REGNUM},
691      nullptr,
692      nullptr,
693     },
694     {"d9",
695      nullptr,
696      8,
697      0,
698      eEncodingIEEE754,
699      eFormatFloat,
700      {LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
701       LLDB_INVALID_REGNUM},
702      nullptr,
703      nullptr,
704     },
705     {"d10",
706      nullptr,
707      8,
708      0,
709      eEncodingIEEE754,
710      eFormatFloat,
711      {LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
712       LLDB_INVALID_REGNUM},
713      nullptr,
714      nullptr,
715     },
716     {"d11",
717      nullptr,
718      8,
719      0,
720      eEncodingIEEE754,
721      eFormatFloat,
722      {LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
723       LLDB_INVALID_REGNUM},
724      nullptr,
725      nullptr,
726     },
727     {"d12",
728      nullptr,
729      8,
730      0,
731      eEncodingIEEE754,
732      eFormatFloat,
733      {LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
734       LLDB_INVALID_REGNUM},
735      nullptr,
736      nullptr,
737     },
738     {"d13",
739      nullptr,
740      8,
741      0,
742      eEncodingIEEE754,
743      eFormatFloat,
744      {LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
745       LLDB_INVALID_REGNUM},
746      nullptr,
747      nullptr,
748     },
749     {"d14",
750      nullptr,
751      8,
752      0,
753      eEncodingIEEE754,
754      eFormatFloat,
755      {LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
756       LLDB_INVALID_REGNUM},
757      nullptr,
758      nullptr,
759     },
760     {"d15",
761      nullptr,
762      8,
763      0,
764      eEncodingIEEE754,
765      eFormatFloat,
766      {LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
767       LLDB_INVALID_REGNUM},
768      nullptr,
769      nullptr,
770     },
771     {"d16",
772      nullptr,
773      8,
774      0,
775      eEncodingIEEE754,
776      eFormatFloat,
777      {LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
778       LLDB_INVALID_REGNUM},
779      nullptr,
780      nullptr,
781     },
782     {"d17",
783      nullptr,
784      8,
785      0,
786      eEncodingIEEE754,
787      eFormatFloat,
788      {LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
789       LLDB_INVALID_REGNUM},
790      nullptr,
791      nullptr,
792     },
793     {"d18",
794      nullptr,
795      8,
796      0,
797      eEncodingIEEE754,
798      eFormatFloat,
799      {LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
800       LLDB_INVALID_REGNUM},
801      nullptr,
802      nullptr,
803     },
804     {"d19",
805      nullptr,
806      8,
807      0,
808      eEncodingIEEE754,
809      eFormatFloat,
810      {LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
811       LLDB_INVALID_REGNUM},
812      nullptr,
813      nullptr,
814     },
815     {"d20",
816      nullptr,
817      8,
818      0,
819      eEncodingIEEE754,
820      eFormatFloat,
821      {LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
822       LLDB_INVALID_REGNUM},
823      nullptr,
824      nullptr,
825     },
826     {"d21",
827      nullptr,
828      8,
829      0,
830      eEncodingIEEE754,
831      eFormatFloat,
832      {LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
833       LLDB_INVALID_REGNUM},
834      nullptr,
835      nullptr,
836     },
837     {"d22",
838      nullptr,
839      8,
840      0,
841      eEncodingIEEE754,
842      eFormatFloat,
843      {LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
844       LLDB_INVALID_REGNUM},
845      nullptr,
846      nullptr,
847     },
848     {"d23",
849      nullptr,
850      8,
851      0,
852      eEncodingIEEE754,
853      eFormatFloat,
854      {LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
855       LLDB_INVALID_REGNUM},
856      nullptr,
857      nullptr,
858     },
859     {"d24",
860      nullptr,
861      8,
862      0,
863      eEncodingIEEE754,
864      eFormatFloat,
865      {LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
866       LLDB_INVALID_REGNUM},
867      nullptr,
868      nullptr,
869     },
870     {"d25",
871      nullptr,
872      8,
873      0,
874      eEncodingIEEE754,
875      eFormatFloat,
876      {LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
877       LLDB_INVALID_REGNUM},
878      nullptr,
879      nullptr,
880     },
881     {"d26",
882      nullptr,
883      8,
884      0,
885      eEncodingIEEE754,
886      eFormatFloat,
887      {LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
888       LLDB_INVALID_REGNUM},
889      nullptr,
890      nullptr,
891     },
892     {"d27",
893      nullptr,
894      8,
895      0,
896      eEncodingIEEE754,
897      eFormatFloat,
898      {LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
899       LLDB_INVALID_REGNUM},
900      nullptr,
901      nullptr,
902     },
903     {"d28",
904      nullptr,
905      8,
906      0,
907      eEncodingIEEE754,
908      eFormatFloat,
909      {LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
910       LLDB_INVALID_REGNUM},
911      nullptr,
912      nullptr,
913     },
914     {"d29",
915      nullptr,
916      8,
917      0,
918      eEncodingIEEE754,
919      eFormatFloat,
920      {LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
921       LLDB_INVALID_REGNUM},
922      nullptr,
923      nullptr,
924     },
925     {"d30",
926      nullptr,
927      8,
928      0,
929      eEncodingIEEE754,
930      eFormatFloat,
931      {LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
932       LLDB_INVALID_REGNUM},
933      nullptr,
934      nullptr,
935     },
936     {"d31",
937      nullptr,
938      8,
939      0,
940      eEncodingIEEE754,
941      eFormatFloat,
942      {LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
943       LLDB_INVALID_REGNUM},
944      nullptr,
945      nullptr,
946     },
947     {"r8_usr",
948      nullptr,
949      4,
950      0,
951      eEncodingUint,
952      eFormatHex,
953      {LLDB_INVALID_REGNUM, dwarf_r8_usr, LLDB_INVALID_REGNUM,
954       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
955      nullptr,
956      nullptr,
957     },
958     {"r9_usr",
959      nullptr,
960      4,
961      0,
962      eEncodingUint,
963      eFormatHex,
964      {LLDB_INVALID_REGNUM, dwarf_r9_usr, LLDB_INVALID_REGNUM,
965       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
966      nullptr,
967      nullptr,
968     },
969     {"r10_usr",
970      nullptr,
971      4,
972      0,
973      eEncodingUint,
974      eFormatHex,
975      {LLDB_INVALID_REGNUM, dwarf_r10_usr, LLDB_INVALID_REGNUM,
976       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
977      nullptr,
978      nullptr,
979     },
980     {"r11_usr",
981      nullptr,
982      4,
983      0,
984      eEncodingUint,
985      eFormatHex,
986      {LLDB_INVALID_REGNUM, dwarf_r11_usr, LLDB_INVALID_REGNUM,
987       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
988      nullptr,
989      nullptr,
990     },
991     {"r12_usr",
992      nullptr,
993      4,
994      0,
995      eEncodingUint,
996      eFormatHex,
997      {LLDB_INVALID_REGNUM, dwarf_r12_usr, LLDB_INVALID_REGNUM,
998       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
999      nullptr,
1000      nullptr,
1001     },
1002     {"r13_usr",
1003      "sp_usr",
1004      4,
1005      0,
1006      eEncodingUint,
1007      eFormatHex,
1008      {LLDB_INVALID_REGNUM, dwarf_r13_usr, LLDB_INVALID_REGNUM,
1009       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1010      nullptr,
1011      nullptr,
1012     },
1013     {"r14_usr",
1014      "lr_usr",
1015      4,
1016      0,
1017      eEncodingUint,
1018      eFormatHex,
1019      {LLDB_INVALID_REGNUM, dwarf_r14_usr, LLDB_INVALID_REGNUM,
1020       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1021      nullptr,
1022      nullptr,
1023     },
1024     {"r8_fiq",
1025      nullptr,
1026      4,
1027      0,
1028      eEncodingUint,
1029      eFormatHex,
1030      {LLDB_INVALID_REGNUM, dwarf_r8_fiq, LLDB_INVALID_REGNUM,
1031       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1032      nullptr,
1033      nullptr,
1034     },
1035     {"r9_fiq",
1036      nullptr,
1037      4,
1038      0,
1039      eEncodingUint,
1040      eFormatHex,
1041      {LLDB_INVALID_REGNUM, dwarf_r9_fiq, LLDB_INVALID_REGNUM,
1042       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1043      nullptr,
1044      nullptr,
1045     },
1046     {"r10_fiq",
1047      nullptr,
1048      4,
1049      0,
1050      eEncodingUint,
1051      eFormatHex,
1052      {LLDB_INVALID_REGNUM, dwarf_r10_fiq, LLDB_INVALID_REGNUM,
1053       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1054      nullptr,
1055      nullptr,
1056     },
1057     {"r11_fiq",
1058      nullptr,
1059      4,
1060      0,
1061      eEncodingUint,
1062      eFormatHex,
1063      {LLDB_INVALID_REGNUM, dwarf_r11_fiq, LLDB_INVALID_REGNUM,
1064       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1065      nullptr,
1066      nullptr,
1067     },
1068     {"r12_fiq",
1069      nullptr,
1070      4,
1071      0,
1072      eEncodingUint,
1073      eFormatHex,
1074      {LLDB_INVALID_REGNUM, dwarf_r12_fiq, LLDB_INVALID_REGNUM,
1075       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1076      nullptr,
1077      nullptr,
1078     },
1079     {"r13_fiq",
1080      "sp_fiq",
1081      4,
1082      0,
1083      eEncodingUint,
1084      eFormatHex,
1085      {LLDB_INVALID_REGNUM, dwarf_r13_fiq, LLDB_INVALID_REGNUM,
1086       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1087      nullptr,
1088      nullptr,
1089     },
1090     {"r14_fiq",
1091      "lr_fiq",
1092      4,
1093      0,
1094      eEncodingUint,
1095      eFormatHex,
1096      {LLDB_INVALID_REGNUM, dwarf_r14_fiq, LLDB_INVALID_REGNUM,
1097       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1098      nullptr,
1099      nullptr,
1100     },
1101     {"r13_irq",
1102      "sp_irq",
1103      4,
1104      0,
1105      eEncodingUint,
1106      eFormatHex,
1107      {LLDB_INVALID_REGNUM, dwarf_r13_irq, LLDB_INVALID_REGNUM,
1108       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1109      nullptr,
1110      nullptr,
1111     },
1112     {"r14_irq",
1113      "lr_irq",
1114      4,
1115      0,
1116      eEncodingUint,
1117      eFormatHex,
1118      {LLDB_INVALID_REGNUM, dwarf_r14_irq, LLDB_INVALID_REGNUM,
1119       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1120      nullptr,
1121      nullptr,
1122     },
1123     {"r13_abt",
1124      "sp_abt",
1125      4,
1126      0,
1127      eEncodingUint,
1128      eFormatHex,
1129      {LLDB_INVALID_REGNUM, dwarf_r13_abt, LLDB_INVALID_REGNUM,
1130       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1131      nullptr,
1132      nullptr,
1133     },
1134     {"r14_abt",
1135      "lr_abt",
1136      4,
1137      0,
1138      eEncodingUint,
1139      eFormatHex,
1140      {LLDB_INVALID_REGNUM, dwarf_r14_abt, LLDB_INVALID_REGNUM,
1141       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1142      nullptr,
1143      nullptr,
1144     },
1145     {"r13_und",
1146      "sp_und",
1147      4,
1148      0,
1149      eEncodingUint,
1150      eFormatHex,
1151      {LLDB_INVALID_REGNUM, dwarf_r13_und, LLDB_INVALID_REGNUM,
1152       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1153      nullptr,
1154      nullptr,
1155     },
1156     {"r14_und",
1157      "lr_und",
1158      4,
1159      0,
1160      eEncodingUint,
1161      eFormatHex,
1162      {LLDB_INVALID_REGNUM, dwarf_r14_und, LLDB_INVALID_REGNUM,
1163       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1164      nullptr,
1165      nullptr,
1166     },
1167     {"r13_svc",
1168      "sp_svc",
1169      4,
1170      0,
1171      eEncodingUint,
1172      eFormatHex,
1173      {LLDB_INVALID_REGNUM, dwarf_r13_svc, LLDB_INVALID_REGNUM,
1174       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1175      nullptr,
1176      nullptr,
1177     },
1178     {"r14_svc",
1179      "lr_svc",
1180      4,
1181      0,
1182      eEncodingUint,
1183      eFormatHex,
1184      {LLDB_INVALID_REGNUM, dwarf_r14_svc, LLDB_INVALID_REGNUM,
1185       LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1186      nullptr,
1187      nullptr,
1188      }};
1189 
1190 static const uint32_t k_num_register_infos = std::size(g_register_infos);
1191 
1192 const lldb_private::RegisterInfo *
1193 ABIMacOSX_arm::GetRegisterInfoArray(uint32_t &count) {
1194   count = k_num_register_infos;
1195   return g_register_infos;
1196 }
1197 
1198 size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; }
1199 
1200 // Static Functions
1201 
1202 ABISP
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 
1218 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 < std::size(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 
1324 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       std::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 
1424 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 
1437 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     std::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             std::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 
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 
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 
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 
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 
1916 void ABIMacOSX_arm::Initialize() {
1917   PluginManager::RegisterPlugin(GetPluginNameStatic(),
1918                                 "Mac OS X ABI for arm targets", CreateInstance);
1919 }
1920 
1921 void ABIMacOSX_arm::Terminate() {
1922   PluginManager::UnregisterPlugin(CreateInstance);
1923 }
1924