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