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