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