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 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 static bool g_register_info_names_constified = false;
1299 
1300 const lldb_private::RegisterInfo *
1301 ABISysV_arm::GetRegisterInfoArray(uint32_t &count) {
1302   // Make the C-string names and alt_names for the register infos into const
1303   // C-string values by having the ConstString unique the names in the global
1304   // constant C-string pool.
1305   if (!g_register_info_names_constified) {
1306     g_register_info_names_constified = true;
1307     for (uint32_t i = 0; i < k_num_register_infos; ++i) {
1308       if (g_register_infos[i].name)
1309         g_register_infos[i].name =
1310             ConstString(g_register_infos[i].name).GetCString();
1311       if (g_register_infos[i].alt_name)
1312         g_register_infos[i].alt_name =
1313             ConstString(g_register_infos[i].alt_name).GetCString();
1314     }
1315   }
1316   count = k_num_register_infos;
1317   return g_register_infos;
1318 }
1319 
1320 size_t ABISysV_arm::GetRedZoneSize() const { return 0; }
1321 
1322 // Static Functions
1323 
1324 ABISP
1325 ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1326   const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch();
1327   const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor();
1328 
1329   if (vendor_type != llvm::Triple::Apple) {
1330     if ((arch_type == llvm::Triple::arm) ||
1331         (arch_type == llvm::Triple::thumb)) {
1332       return ABISP(
1333           new ABISysV_arm(std::move(process_sp), MakeMCRegisterInfo(arch)));
1334     }
1335   }
1336 
1337   return ABISP();
1338 }
1339 
1340 bool ABISysV_arm::PrepareTrivialCall(Thread &thread, addr_t sp,
1341                                      addr_t function_addr, addr_t return_addr,
1342                                      llvm::ArrayRef<addr_t> args) const {
1343   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1344   if (!reg_ctx)
1345     return false;
1346 
1347   const uint32_t pc_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1348       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1349   const uint32_t sp_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1350       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1351   const uint32_t ra_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(
1352       eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
1353 
1354   RegisterValue reg_value;
1355 
1356   const uint8_t reg_names[] = {
1357       LLDB_REGNUM_GENERIC_ARG1, LLDB_REGNUM_GENERIC_ARG2,
1358       LLDB_REGNUM_GENERIC_ARG3, LLDB_REGNUM_GENERIC_ARG4};
1359 
1360   llvm::ArrayRef<addr_t>::iterator ai = args.begin(), ae = args.end();
1361 
1362   for (size_t i = 0; i < llvm::array_lengthof(reg_names); ++i) {
1363     if (ai == ae)
1364       break;
1365 
1366     reg_value.SetUInt32(*ai);
1367     if (!reg_ctx->WriteRegister(
1368             reg_ctx->GetRegisterInfo(eRegisterKindGeneric, reg_names[i]),
1369             reg_value))
1370       return false;
1371 
1372     ++ai;
1373   }
1374 
1375   if (ai != ae) {
1376     // Spill onto the stack
1377     size_t num_stack_regs = ae - ai;
1378 
1379     sp -= (num_stack_regs * 4);
1380     // Keep the stack 8 byte aligned, not that we need to
1381     sp &= ~(8ull - 1ull);
1382 
1383     // just using arg1 to get the right size
1384     const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1385         eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1386 
1387     addr_t arg_pos = sp;
1388 
1389     for (; ai != ae; ++ai) {
1390       reg_value.SetUInt32(*ai);
1391       if (reg_ctx
1392               ->WriteRegisterValueToMemory(reg_info, arg_pos,
1393                                            reg_info->byte_size, reg_value)
1394               .Fail())
1395         return false;
1396       arg_pos += reg_info->byte_size;
1397     }
1398   }
1399 
1400   TargetSP target_sp(thread.CalculateTarget());
1401   Address so_addr;
1402 
1403   // Figure out if our return address is ARM or Thumb by using the
1404   // Address::GetCallableLoadAddress(Target*) which will figure out the ARM
1405   // thumb-ness and set the correct address bits for us.
1406   so_addr.SetLoadAddress(return_addr, target_sp.get());
1407   return_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1408 
1409   // Set "lr" to the return address
1410   if (!reg_ctx->WriteRegisterFromUnsigned(ra_reg_num, return_addr))
1411     return false;
1412 
1413   // Set "sp" to the requested value
1414   if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_num, sp))
1415     return false;
1416 
1417   // If bit zero or 1 is set, this must be a thumb function, no need to figure
1418   // this out from the symbols.
1419   so_addr.SetLoadAddress(function_addr, target_sp.get());
1420   function_addr = so_addr.GetCallableLoadAddress(target_sp.get());
1421 
1422   const RegisterInfo *cpsr_reg_info =
1423       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
1424   const uint32_t curr_cpsr = reg_ctx->ReadRegisterAsUnsigned(cpsr_reg_info, 0);
1425 
1426   // Make a new CPSR and mask out any Thumb IT (if/then) bits
1427   uint32_t new_cpsr = curr_cpsr & ~MASK_CPSR_IT_MASK;
1428   // If bit zero or 1 is set, this must be thumb...
1429   if (function_addr & 1ull)
1430     new_cpsr |= MASK_CPSR_T; // Set T bit in CPSR
1431   else
1432     new_cpsr &= ~MASK_CPSR_T; // Clear T bit in CPSR
1433 
1434   if (new_cpsr != curr_cpsr) {
1435     if (!reg_ctx->WriteRegisterFromUnsigned(cpsr_reg_info, new_cpsr))
1436       return false;
1437   }
1438 
1439   function_addr &=
1440       ~1ull; // clear bit zero since the CPSR will take care of the mode for us
1441 
1442   // Set "pc" to the address requested
1443   return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr);
1444 }
1445 
1446 bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const {
1447   uint32_t num_values = values.GetSize();
1448 
1449   ExecutionContext exe_ctx(thread.shared_from_this());
1450   // For now, assume that the types in the AST values come from the Target's
1451   // scratch AST.
1452 
1453   // Extract the register context so we can read arguments from registers
1454 
1455   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1456 
1457   if (!reg_ctx)
1458     return false;
1459 
1460   addr_t sp = 0;
1461 
1462   for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx) {
1463     // We currently only support extracting values with Clang QualTypes. Do we
1464     // care about others?
1465     Value *value = values.GetValueAtIndex(value_idx);
1466 
1467     if (!value)
1468       return false;
1469 
1470     CompilerType compiler_type = value->GetCompilerType();
1471     if (compiler_type) {
1472       bool is_signed = false;
1473       size_t bit_width = 0;
1474       if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1475           compiler_type.IsPointerOrReferenceType()) {
1476         if (llvm::Optional<uint64_t> size = compiler_type.GetBitSize(&thread))
1477           bit_width = *size;
1478       } else {
1479         // We only handle integer, pointer and reference types currently...
1480         return false;
1481       }
1482 
1483       if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) {
1484         if (value_idx < 4) {
1485           // Arguments 1-4 are in r0-r3...
1486           const RegisterInfo *arg_reg_info = nullptr;
1487           arg_reg_info = reg_ctx->GetRegisterInfo(
1488               eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx);
1489           if (arg_reg_info) {
1490             RegisterValue reg_value;
1491 
1492             if (reg_ctx->ReadRegister(arg_reg_info, reg_value)) {
1493               if (is_signed)
1494                 reg_value.SignExtend(bit_width);
1495               if (!reg_value.GetScalarValue(value->GetScalar()))
1496                 return false;
1497               continue;
1498             }
1499           }
1500           return false;
1501         } else {
1502           if (sp == 0) {
1503             // Read the stack pointer if it already hasn't been read
1504             sp = reg_ctx->GetSP(0);
1505             if (sp == 0)
1506               return false;
1507           }
1508 
1509           // Arguments 5 on up are on the stack
1510           const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8;
1511           Status error;
1512           if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory(
1513                   sp, arg_byte_size, is_signed, value->GetScalar(), error))
1514             return false;
1515 
1516           sp += arg_byte_size;
1517         }
1518       }
1519     }
1520   }
1521   return true;
1522 }
1523 
1524 static bool GetReturnValuePassedInMemory(Thread &thread,
1525                                          RegisterContext *reg_ctx,
1526                                          size_t byte_size, Value &value) {
1527   Status error;
1528   DataBufferHeap buffer(byte_size, 0);
1529 
1530   const RegisterInfo *r0_reg_info =
1531       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1532   uint32_t address =
1533       reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1534   thread.GetProcess()->ReadMemory(address, buffer.GetBytes(),
1535                                   buffer.GetByteSize(), error);
1536 
1537   if (error.Fail())
1538     return false;
1539 
1540   value.SetBytes(buffer.GetBytes(), buffer.GetByteSize());
1541   return true;
1542 }
1543 
1544 bool ABISysV_arm::IsArmHardFloat(Thread &thread) const {
1545   ProcessSP process_sp(thread.GetProcess());
1546   if (process_sp) {
1547     const ArchSpec &arch(process_sp->GetTarget().GetArchitecture());
1548 
1549     return (arch.GetFlags() & ArchSpec::eARM_abi_hard_float) != 0;
1550   }
1551 
1552   return false;
1553 }
1554 
1555 ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl(
1556     Thread &thread, lldb_private::CompilerType &compiler_type) const {
1557   Value value;
1558   ValueObjectSP return_valobj_sp;
1559 
1560   if (!compiler_type)
1561     return return_valobj_sp;
1562 
1563   // value.SetContext (Value::eContextTypeClangType,
1564   // compiler_type.GetOpaqueQualType());
1565   value.SetCompilerType(compiler_type);
1566 
1567   RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1568   if (!reg_ctx)
1569     return return_valobj_sp;
1570 
1571   bool is_signed;
1572   bool is_complex;
1573   uint32_t float_count;
1574   bool is_vfp_candidate = false;
1575   uint8_t vfp_count = 0;
1576   uint8_t vfp_byte_size = 0;
1577 
1578   // Get the pointer to the first stack argument so we have a place to start
1579   // when reading data
1580 
1581   const RegisterInfo *r0_reg_info =
1582       reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1583   llvm::Optional<uint64_t> bit_width = compiler_type.GetBitSize(&thread);
1584   llvm::Optional<uint64_t> byte_size = compiler_type.GetByteSize(&thread);
1585   if (!bit_width || !byte_size)
1586     return return_valobj_sp;
1587 
1588   if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1589     switch (*bit_width) {
1590     default:
1591       return return_valobj_sp;
1592     case 64: {
1593       const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1594           eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1595       uint64_t raw_value;
1596       raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1597       raw_value |= ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1598                                UINT32_MAX))
1599                    << 32;
1600       if (is_signed)
1601         value.GetScalar() = (int64_t)raw_value;
1602       else
1603         value.GetScalar() = (uint64_t)raw_value;
1604     } break;
1605     case 32:
1606       if (is_signed)
1607         value.GetScalar() = (int32_t)(
1608             reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1609       else
1610         value.GetScalar() = (uint32_t)(
1611             reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX);
1612       break;
1613     case 16:
1614       if (is_signed)
1615         value.GetScalar() = (int16_t)(
1616             reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1617       else
1618         value.GetScalar() = (uint16_t)(
1619             reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT16_MAX);
1620       break;
1621     case 8:
1622       if (is_signed)
1623         value.GetScalar() = (int8_t)(
1624             reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1625       else
1626         value.GetScalar() = (uint8_t)(
1627             reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT8_MAX);
1628       break;
1629     }
1630   } else if (compiler_type.IsPointerType()) {
1631     uint32_t ptr =
1632         thread.GetRegisterContext()->ReadRegisterAsUnsigned(r0_reg_info, 0) &
1633         UINT32_MAX;
1634     value.GetScalar() = ptr;
1635   } else if (compiler_type.IsVectorType(nullptr, nullptr)) {
1636     if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) {
1637       is_vfp_candidate = true;
1638       vfp_byte_size = 8;
1639       vfp_count = (*byte_size == 8 ? 1 : 2);
1640     } else if (*byte_size <= 16) {
1641       DataBufferHeap buffer(16, 0);
1642       uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes();
1643 
1644       for (uint32_t i = 0; 4 * i < *byte_size; ++i) {
1645         const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo(
1646             eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i);
1647         buffer_ptr[i] =
1648             reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX;
1649       }
1650       value.SetBytes(buffer.GetBytes(), *byte_size);
1651     } else {
1652       if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1653         return return_valobj_sp;
1654     }
1655   } else if (compiler_type.IsFloatingPointType(float_count, is_complex)) {
1656     if (float_count == 1 && !is_complex) {
1657       switch (*bit_width) {
1658       default:
1659         return return_valobj_sp;
1660       case 64: {
1661         static_assert(sizeof(double) == sizeof(uint64_t), "");
1662 
1663         if (IsArmHardFloat(thread)) {
1664           RegisterValue reg_value;
1665           const RegisterInfo *d0_reg_info =
1666               reg_ctx->GetRegisterInfoByName("d0", 0);
1667           reg_ctx->ReadRegister(d0_reg_info, reg_value);
1668           value.GetScalar() = reg_value.GetAsDouble();
1669         } else {
1670           uint64_t raw_value;
1671           const RegisterInfo *r1_reg_info = reg_ctx->GetRegisterInfo(
1672               eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1673           raw_value =
1674               reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1675           raw_value |=
1676               ((uint64_t)(reg_ctx->ReadRegisterAsUnsigned(r1_reg_info, 0) &
1677                           UINT32_MAX))
1678               << 32;
1679           value.GetScalar() = *reinterpret_cast<double *>(&raw_value);
1680         }
1681         break;
1682       }
1683       case 16: // Half precision returned after a conversion to single precision
1684       case 32: {
1685         static_assert(sizeof(float) == sizeof(uint32_t), "");
1686 
1687         if (IsArmHardFloat(thread)) {
1688           RegisterValue reg_value;
1689           const RegisterInfo *s0_reg_info =
1690               reg_ctx->GetRegisterInfoByName("s0", 0);
1691           reg_ctx->ReadRegister(s0_reg_info, reg_value);
1692           value.GetScalar() = reg_value.GetAsFloat();
1693         } else {
1694           uint32_t raw_value;
1695           raw_value =
1696               reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1697           value.GetScalar() = *reinterpret_cast<float *>(&raw_value);
1698         }
1699         break;
1700       }
1701       }
1702     } else if (is_complex && float_count == 2) {
1703       if (IsArmHardFloat(thread)) {
1704         is_vfp_candidate = true;
1705         vfp_byte_size = *byte_size / 2;
1706         vfp_count = 2;
1707       } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8,
1708                                                value))
1709         return return_valobj_sp;
1710     } else
1711       // not handled yet
1712       return return_valobj_sp;
1713   } else if (compiler_type.IsAggregateType()) {
1714     if (IsArmHardFloat(thread)) {
1715       CompilerType base_type;
1716       const uint32_t homogeneous_count =
1717           compiler_type.IsHomogeneousAggregate(&base_type);
1718 
1719       if (homogeneous_count > 0 && homogeneous_count <= 4) {
1720         llvm::Optional<uint64_t> base_byte_size =
1721             base_type.GetByteSize(nullptr);
1722         if (base_type.IsVectorType(nullptr, nullptr)) {
1723           if (base_byte_size &&
1724               (*base_byte_size == 8 || *base_byte_size == 16)) {
1725             is_vfp_candidate = true;
1726             vfp_byte_size = 8;
1727             vfp_count = (*base_byte_size == 8 ? homogeneous_count
1728                                               : homogeneous_count * 2);
1729           }
1730         } else if (base_type.IsFloatingPointType(float_count, is_complex)) {
1731           if (float_count == 1 && !is_complex) {
1732             is_vfp_candidate = true;
1733             if (base_byte_size)
1734               vfp_byte_size = *base_byte_size;
1735             vfp_count = homogeneous_count;
1736           }
1737         }
1738       } else if (homogeneous_count == 0) {
1739         const uint32_t num_children = compiler_type.GetNumFields();
1740 
1741         if (num_children > 0 && num_children <= 2) {
1742           uint32_t index = 0;
1743           for (index = 0; index < num_children; index++) {
1744             std::string name;
1745             base_type = compiler_type.GetFieldAtIndex(index, name, nullptr,
1746                                                       nullptr, nullptr);
1747 
1748             if (base_type.IsFloatingPointType(float_count, is_complex)) {
1749               llvm::Optional<uint64_t> base_byte_size =
1750                   base_type.GetByteSize(nullptr);
1751               if (float_count == 2 && is_complex) {
1752                 if (index != 0 && base_byte_size &&
1753                     vfp_byte_size != *base_byte_size)
1754                   break;
1755                 else if (base_byte_size)
1756                   vfp_byte_size = *base_byte_size;
1757               } else
1758                 break;
1759             } else
1760               break;
1761           }
1762 
1763           if (index == num_children) {
1764             is_vfp_candidate = true;
1765             vfp_byte_size = (vfp_byte_size >> 1);
1766             vfp_count = (num_children << 1);
1767           }
1768         }
1769       }
1770     }
1771 
1772     if (*byte_size <= 4) {
1773       RegisterValue r0_reg_value;
1774       uint32_t raw_value =
1775           reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX;
1776       value.SetBytes(&raw_value, *byte_size);
1777     } else if (!is_vfp_candidate) {
1778       if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value))
1779         return return_valobj_sp;
1780     }
1781   } else {
1782     // not handled yet
1783     return return_valobj_sp;
1784   }
1785 
1786   if (is_vfp_candidate) {
1787     ProcessSP process_sp(thread.GetProcess());
1788     ByteOrder byte_order = process_sp->GetByteOrder();
1789 
1790     DataBufferSP data_sp(new DataBufferHeap(*byte_size, 0));
1791     uint32_t data_offset = 0;
1792 
1793     for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) {
1794       uint32_t regnum = 0;
1795 
1796       if (vfp_byte_size == 4)
1797         regnum = dwarf_s0 + reg_index;
1798       else if (vfp_byte_size == 8)
1799         regnum = dwarf_d0 + reg_index;
1800       else
1801         break;
1802 
1803       const RegisterInfo *reg_info =
1804           reg_ctx->GetRegisterInfo(eRegisterKindDWARF, regnum);
1805       if (reg_info == nullptr)
1806         break;
1807 
1808       RegisterValue reg_value;
1809       if (!reg_ctx->ReadRegister(reg_info, reg_value))
1810         break;
1811 
1812       // Make sure we have enough room in "data_sp"
1813       if ((data_offset + vfp_byte_size) <= data_sp->GetByteSize()) {
1814         Status error;
1815         const size_t bytes_copied = reg_value.GetAsMemoryData(
1816             reg_info, data_sp->GetBytes() + data_offset, vfp_byte_size,
1817             byte_order, error);
1818         if (bytes_copied != vfp_byte_size)
1819           break;
1820 
1821         data_offset += bytes_copied;
1822       }
1823     }
1824 
1825     if (data_offset == *byte_size) {
1826       DataExtractor data;
1827       data.SetByteOrder(byte_order);
1828       data.SetAddressByteSize(process_sp->GetAddressByteSize());
1829       data.SetData(data_sp);
1830 
1831       return ValueObjectConstResult::Create(&thread, compiler_type,
1832                                             ConstString(""), data);
1833     } else { // Some error occurred while getting values from registers
1834       return return_valobj_sp;
1835     }
1836   }
1837 
1838   // If we get here, we have a valid Value, so make our ValueObject out of it:
1839 
1840   return_valobj_sp = ValueObjectConstResult::Create(
1841       thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1842   return return_valobj_sp;
1843 }
1844 
1845 Status ABISysV_arm::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1846                                          lldb::ValueObjectSP &new_value_sp) {
1847   Status error;
1848   if (!new_value_sp) {
1849     error.SetErrorString("Empty value object for return value.");
1850     return error;
1851   }
1852 
1853   CompilerType compiler_type = new_value_sp->GetCompilerType();
1854   if (!compiler_type) {
1855     error.SetErrorString("Null clang type for return value.");
1856     return error;
1857   }
1858 
1859   Thread *thread = frame_sp->GetThread().get();
1860 
1861   bool is_signed;
1862   uint32_t count;
1863   bool is_complex;
1864 
1865   RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1866 
1867   bool set_it_simple = false;
1868   if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1869       compiler_type.IsPointerType()) {
1870     DataExtractor data;
1871     Status data_error;
1872     size_t num_bytes = new_value_sp->GetData(data, data_error);
1873     if (data_error.Fail()) {
1874       error.SetErrorStringWithFormat(
1875           "Couldn't convert return value to raw data: %s",
1876           data_error.AsCString());
1877       return error;
1878     }
1879     lldb::offset_t offset = 0;
1880     if (num_bytes <= 8) {
1881       const RegisterInfo *r0_info = reg_ctx->GetRegisterInfo(
1882           eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1);
1883       if (num_bytes <= 4) {
1884         uint32_t raw_value = data.GetMaxU32(&offset, num_bytes);
1885 
1886         if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value))
1887           set_it_simple = true;
1888       } else {
1889         uint32_t raw_value = data.GetMaxU32(&offset, 4);
1890 
1891         if (reg_ctx->WriteRegisterFromUnsigned(r0_info, raw_value)) {
1892           const RegisterInfo *r1_info = reg_ctx->GetRegisterInfo(
1893               eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2);
1894           uint32_t raw_value = data.GetMaxU32(&offset, num_bytes - offset);
1895 
1896           if (reg_ctx->WriteRegisterFromUnsigned(r1_info, raw_value))
1897             set_it_simple = true;
1898         }
1899       }
1900     } else {
1901       error.SetErrorString("We don't support returning longer than 64 bit "
1902                            "integer values at present.");
1903     }
1904   } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1905     if (is_complex)
1906       error.SetErrorString(
1907           "We don't support returning complex values at present");
1908     else
1909       error.SetErrorString(
1910           "We don't support returning float values at present");
1911   }
1912 
1913   if (!set_it_simple)
1914     error.SetErrorString(
1915         "We only support setting simple integer return types at present.");
1916 
1917   return error;
1918 }
1919 
1920 bool ABISysV_arm::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1921   unwind_plan.Clear();
1922   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1923 
1924   uint32_t lr_reg_num = dwarf_lr;
1925   uint32_t sp_reg_num = dwarf_sp;
1926   uint32_t pc_reg_num = dwarf_pc;
1927 
1928   UnwindPlan::RowSP row(new UnwindPlan::Row);
1929 
1930   // Our Call Frame Address is the stack pointer value
1931   row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 0);
1932 
1933   // The previous PC is in the LR
1934   row->SetRegisterLocationToRegister(pc_reg_num, lr_reg_num, true);
1935   unwind_plan.AppendRow(row);
1936 
1937   // All other registers are the same.
1938 
1939   unwind_plan.SetSourceName("arm at-func-entry default");
1940   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1941 
1942   return true;
1943 }
1944 
1945 bool ABISysV_arm::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1946   unwind_plan.Clear();
1947   unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1948 
1949   // TODO: Handle thumb
1950   uint32_t fp_reg_num = dwarf_r11;
1951   uint32_t pc_reg_num = dwarf_pc;
1952 
1953   UnwindPlan::RowSP row(new UnwindPlan::Row);
1954   const int32_t ptr_size = 4;
1955 
1956   row->GetCFAValue().SetIsRegisterPlusOffset(fp_reg_num, 2 * ptr_size);
1957   row->SetOffset(0);
1958 
1959   row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1960   row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1961 
1962   unwind_plan.AppendRow(row);
1963   unwind_plan.SetSourceName("arm default unwind plan");
1964   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1965   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1966   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1967 
1968   return true;
1969 }
1970 
1971 // cf. "ARMv6 Function Calling Conventions"
1972 
1973 // ARMv7 on GNU/Linux general purpose reg rules:
1974 //    r0-r3 not preserved  (used for argument passing)
1975 //    r4-r11 preserved (v1-v8)
1976 //    r12   not presrved
1977 //    r13   preserved (stack pointer)
1978 //    r14   preserved (link register)
1979 //    r15   preserved (pc)
1980 //    cpsr  not preserved (different rules for different bits)
1981 
1982 // ARMv7 VFP register rules:
1983 //    d0-d7   not preserved   (aka s0-s15, q0-q3)
1984 //    d8-d15  preserved       (aka s16-s31, q4-q7)
1985 //    d16-d31 not preserved   (aka q8-q15)
1986 
1987 bool ABISysV_arm::RegisterIsVolatile(const RegisterInfo *reg_info) {
1988   if (reg_info) {
1989     // Volatile registers are: r0, r1, r2, r3, r9, r12, r13 (aka sp)
1990     const char *name = reg_info->name;
1991     if (name[0] == 'r') {
1992       switch (name[1]) {
1993       case '0':
1994         return name[2] == '\0'; // r0
1995       case '1':
1996         switch (name[2]) {
1997         case '\0':
1998           return true; // r1
1999         case '2':
2000           return name[3] == '\0'; // r12
2001         default:
2002           break;
2003         }
2004         break;
2005 
2006       case '2':
2007         return name[2] == '\0'; // r2
2008       case '3':
2009         return name[2] == '\0'; // r3
2010       default:
2011         break;
2012       }
2013     } else if (name[0] == 'd') {
2014       switch (name[1]) {
2015       case '0':
2016         return name[2] == '\0'; // d0 is volatile
2017 
2018       case '1':
2019         switch (name[2]) {
2020         case '\0':
2021           return true; // d1 is volatile
2022         case '6':
2023         case '7':
2024         case '8':
2025         case '9':
2026           return name[3] == '\0'; // d16 - d19 are volatile
2027         default:
2028           break;
2029         }
2030         break;
2031 
2032       case '2':
2033         switch (name[2]) {
2034         case '\0':
2035           return true; // d2 is volatile
2036         case '0':
2037         case '1':
2038         case '2':
2039         case '3':
2040         case '4':
2041         case '5':
2042         case '6':
2043         case '7':
2044         case '8':
2045         case '9':
2046           return name[3] == '\0'; // d20 - d29 are volatile
2047         default:
2048           break;
2049         }
2050         break;
2051 
2052       case '3':
2053         switch (name[2]) {
2054         case '\0':
2055           return true; // d3 is volatile
2056         case '0':
2057         case '1':
2058           return name[3] == '\0'; // d30 - d31 are volatile
2059         default:
2060           break;
2061         }
2062         break;
2063       case '4':
2064       case '5':
2065       case '6':
2066       case '7':
2067         return name[2] == '\0'; // d4 - d7 are volatile
2068 
2069       default:
2070         break;
2071       }
2072     } else if (name[0] == 's') {
2073       switch (name[1]) {
2074       case '0':
2075         return name[2] == '\0'; // s0 is volatile
2076 
2077       case '1':
2078         switch (name[2]) {
2079         case '\0':
2080           return true; // s1 is volatile
2081         case '0':
2082         case '1':
2083         case '2':
2084         case '3':
2085         case '4':
2086         case '5':
2087           return name[3] == '\0'; // s10 - s15 are volatile
2088         default:
2089           break;
2090         }
2091         break;
2092 
2093       case '2':
2094       case '3':
2095       case '4':
2096       case '5':
2097       case '6':
2098       case '7':
2099       case '8':
2100       case '9':
2101         return name[2] == '\0'; // s2 - s9 are volatile
2102 
2103       default:
2104         break;
2105       }
2106     } else if (name[0] == 'q') {
2107       switch (name[1]) {
2108       case '1':
2109         switch (name[2]) {
2110         case '\0':
2111           return true; // q1 is volatile
2112         case '0':
2113         case '1':
2114         case '2':
2115         case '3':
2116         case '4':
2117         case '5':
2118           return true; // q10-q15 are volatile
2119         default:
2120           return false;
2121         }
2122         break;
2123 
2124       case '0':
2125       case '2':
2126       case '3':
2127         return name[2] == '\0'; // q0-q3 are volatile
2128       case '8':
2129       case '9':
2130         return name[2] == '\0'; // q8-q9 are volatile
2131       default:
2132         break;
2133       }
2134     } else if (name[0] == 's' && name[1] == 'p' && name[2] == '\0')
2135       return true;
2136   }
2137   return false;
2138 }
2139 
2140 void ABISysV_arm::Initialize() {
2141   PluginManager::RegisterPlugin(GetPluginNameStatic(),
2142                                 "SysV ABI for arm targets", CreateInstance);
2143 }
2144 
2145 void ABISysV_arm::Terminate() {
2146   PluginManager::UnregisterPlugin(CreateInstance);
2147 }
2148 
2149 lldb_private::ConstString ABISysV_arm::GetPluginNameStatic() {
2150   static ConstString g_name("SysV-arm");
2151   return g_name;
2152 }
2153 
2154 // PluginInterface protocol
2155 
2156 lldb_private::ConstString ABISysV_arm::GetPluginName() {
2157   return GetPluginNameStatic();
2158 }
2159 
2160 uint32_t ABISysV_arm::GetPluginVersion() { return 1; }
2161