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