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