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