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