xref: /llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp (revision 593be023615a456ca6ee0ef9bedc21301d73b73c)
1 //===-- RegisterContextDarwin_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 "RegisterContextDarwin_arm.h"
10 #include "RegisterContextDarwinConstants.h"
11 
12 #include "lldb/Utility/DataBufferHeap.h"
13 #include "lldb/Utility/DataExtractor.h"
14 #include "lldb/Utility/Endian.h"
15 #include "lldb/Utility/Log.h"
16 #include "lldb/Utility/RegisterValue.h"
17 #include "lldb/Utility/Scalar.h"
18 #include "llvm/Support/Compiler.h"
19 
20 #include "Plugins/Process/Utility/InstructionUtils.h"
21 
22 #include <memory>
23 
24 #include "Utility/ARM_DWARF_Registers.h"
25 #include "Utility/ARM_ehframe_Registers.h"
26 
27 #include "llvm/ADT/STLExtras.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 enum {
33   gpr_r0 = 0,
34   gpr_r1,
35   gpr_r2,
36   gpr_r3,
37   gpr_r4,
38   gpr_r5,
39   gpr_r6,
40   gpr_r7,
41   gpr_r8,
42   gpr_r9,
43   gpr_r10,
44   gpr_r11,
45   gpr_r12,
46   gpr_r13,
47   gpr_sp = gpr_r13,
48   gpr_r14,
49   gpr_lr = gpr_r14,
50   gpr_r15,
51   gpr_pc = gpr_r15,
52   gpr_cpsr,
53 
54   fpu_s0,
55   fpu_s1,
56   fpu_s2,
57   fpu_s3,
58   fpu_s4,
59   fpu_s5,
60   fpu_s6,
61   fpu_s7,
62   fpu_s8,
63   fpu_s9,
64   fpu_s10,
65   fpu_s11,
66   fpu_s12,
67   fpu_s13,
68   fpu_s14,
69   fpu_s15,
70   fpu_s16,
71   fpu_s17,
72   fpu_s18,
73   fpu_s19,
74   fpu_s20,
75   fpu_s21,
76   fpu_s22,
77   fpu_s23,
78   fpu_s24,
79   fpu_s25,
80   fpu_s26,
81   fpu_s27,
82   fpu_s28,
83   fpu_s29,
84   fpu_s30,
85   fpu_s31,
86   fpu_fpscr,
87 
88   exc_exception,
89   exc_fsr,
90   exc_far,
91 
92   dbg_bvr0,
93   dbg_bvr1,
94   dbg_bvr2,
95   dbg_bvr3,
96   dbg_bvr4,
97   dbg_bvr5,
98   dbg_bvr6,
99   dbg_bvr7,
100   dbg_bvr8,
101   dbg_bvr9,
102   dbg_bvr10,
103   dbg_bvr11,
104   dbg_bvr12,
105   dbg_bvr13,
106   dbg_bvr14,
107   dbg_bvr15,
108 
109   dbg_bcr0,
110   dbg_bcr1,
111   dbg_bcr2,
112   dbg_bcr3,
113   dbg_bcr4,
114   dbg_bcr5,
115   dbg_bcr6,
116   dbg_bcr7,
117   dbg_bcr8,
118   dbg_bcr9,
119   dbg_bcr10,
120   dbg_bcr11,
121   dbg_bcr12,
122   dbg_bcr13,
123   dbg_bcr14,
124   dbg_bcr15,
125 
126   dbg_wvr0,
127   dbg_wvr1,
128   dbg_wvr2,
129   dbg_wvr3,
130   dbg_wvr4,
131   dbg_wvr5,
132   dbg_wvr6,
133   dbg_wvr7,
134   dbg_wvr8,
135   dbg_wvr9,
136   dbg_wvr10,
137   dbg_wvr11,
138   dbg_wvr12,
139   dbg_wvr13,
140   dbg_wvr14,
141   dbg_wvr15,
142 
143   dbg_wcr0,
144   dbg_wcr1,
145   dbg_wcr2,
146   dbg_wcr3,
147   dbg_wcr4,
148   dbg_wcr5,
149   dbg_wcr6,
150   dbg_wcr7,
151   dbg_wcr8,
152   dbg_wcr9,
153   dbg_wcr10,
154   dbg_wcr11,
155   dbg_wcr12,
156   dbg_wcr13,
157   dbg_wcr14,
158   dbg_wcr15,
159 
160   k_num_registers
161 };
162 
163 #define GPR_OFFSET(idx) ((idx)*4)
164 #define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR))
165 #define EXC_OFFSET(idx)                                                        \
166   ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR) +                          \
167    sizeof(RegisterContextDarwin_arm::FPU))
168 #define DBG_OFFSET(reg)                                                        \
169   ((LLVM_EXTENSION offsetof(RegisterContextDarwin_arm::DBG, reg) +             \
170     sizeof(RegisterContextDarwin_arm::GPR) +                                   \
171     sizeof(RegisterContextDarwin_arm::FPU) +                                   \
172     sizeof(RegisterContextDarwin_arm::EXC)))
173 
174 #define DEFINE_DBG(reg, i)                                                     \
175   #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *) NULL)->reg[i]),       \
176                       DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex,           \
177                                  {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    \
178                                   LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    \
179                                   LLDB_INVALID_REGNUM },                       \
180                                   nullptr, nullptr, nullptr,
181 #define REG_CONTEXT_SIZE                                                       \
182   (sizeof(RegisterContextDarwin_arm::GPR) +                                    \
183    sizeof(RegisterContextDarwin_arm::FPU) +                                    \
184    sizeof(RegisterContextDarwin_arm::EXC))
185 
186 static RegisterInfo g_register_infos[] = {
187     {"r0",
188      nullptr,
189      4,
190      GPR_OFFSET(0),
191      eEncodingUint,
192      eFormatHex,
193      {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0},
194      nullptr,
195      nullptr,
196      nullptr,
197     },
198     {"r1",
199      nullptr,
200      4,
201      GPR_OFFSET(1),
202      eEncodingUint,
203      eFormatHex,
204      {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1},
205      nullptr,
206      nullptr,
207      nullptr,
208     },
209     {"r2",
210      nullptr,
211      4,
212      GPR_OFFSET(2),
213      eEncodingUint,
214      eFormatHex,
215      {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2},
216      nullptr,
217      nullptr,
218      nullptr,
219     },
220     {"r3",
221      nullptr,
222      4,
223      GPR_OFFSET(3),
224      eEncodingUint,
225      eFormatHex,
226      {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3},
227      nullptr,
228      nullptr,
229      nullptr,
230     },
231     {"r4",
232      nullptr,
233      4,
234      GPR_OFFSET(4),
235      eEncodingUint,
236      eFormatHex,
237      {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},
238      nullptr,
239      nullptr,
240      nullptr,
241     },
242     {"r5",
243      nullptr,
244      4,
245      GPR_OFFSET(5),
246      eEncodingUint,
247      eFormatHex,
248      {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},
249      nullptr,
250      nullptr,
251      nullptr,
252     },
253     {"r6",
254      nullptr,
255      4,
256      GPR_OFFSET(6),
257      eEncodingUint,
258      eFormatHex,
259      {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},
260      nullptr,
261      nullptr,
262      nullptr,
263     },
264     {"r7",
265      nullptr,
266      4,
267      GPR_OFFSET(7),
268      eEncodingUint,
269      eFormatHex,
270      {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
271       gpr_r7},
272      nullptr,
273      nullptr,
274      nullptr,
275     },
276     {"r8",
277      nullptr,
278      4,
279      GPR_OFFSET(8),
280      eEncodingUint,
281      eFormatHex,
282      {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},
283      nullptr,
284      nullptr,
285      nullptr,
286     },
287     {"r9",
288      nullptr,
289      4,
290      GPR_OFFSET(9),
291      eEncodingUint,
292      eFormatHex,
293      {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},
294      nullptr,
295      nullptr,
296      nullptr,
297     },
298     {"r10",
299      nullptr,
300      4,
301      GPR_OFFSET(10),
302      eEncodingUint,
303      eFormatHex,
304      {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
305       gpr_r10},
306      nullptr,
307      nullptr,
308      nullptr,
309     },
310     {"r11",
311      nullptr,
312      4,
313      GPR_OFFSET(11),
314      eEncodingUint,
315      eFormatHex,
316      {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
317       gpr_r11},
318      nullptr,
319      nullptr,
320      nullptr,
321     },
322     {"r12",
323      nullptr,
324      4,
325      GPR_OFFSET(12),
326      eEncodingUint,
327      eFormatHex,
328      {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
329       gpr_r12},
330      nullptr,
331      nullptr,
332      nullptr,
333     },
334     {"sp",
335      "r13",
336      4,
337      GPR_OFFSET(13),
338      eEncodingUint,
339      eFormatHex,
340      {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
341       gpr_sp},
342      nullptr,
343      nullptr,
344      nullptr,
345     },
346     {"lr",
347      "r14",
348      4,
349      GPR_OFFSET(14),
350      eEncodingUint,
351      eFormatHex,
352      {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
353       gpr_lr},
354      nullptr,
355      nullptr,
356      nullptr,
357     },
358     {"pc",
359      "r15",
360      4,
361      GPR_OFFSET(15),
362      eEncodingUint,
363      eFormatHex,
364      {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
365       gpr_pc},
366      nullptr,
367      nullptr,
368      nullptr,
369     },
370     {"cpsr",
371      "psr",
372      4,
373      GPR_OFFSET(16),
374      eEncodingUint,
375      eFormatHex,
376      {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
377       gpr_cpsr},
378      nullptr,
379      nullptr,
380      nullptr,
381     },
382 
383     {"s0",
384      nullptr,
385      4,
386      FPU_OFFSET(0),
387      eEncodingIEEE754,
388      eFormatFloat,
389      {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
390       fpu_s0},
391      nullptr,
392      nullptr,
393      nullptr,
394     },
395     {"s1",
396      nullptr,
397      4,
398      FPU_OFFSET(1),
399      eEncodingIEEE754,
400      eFormatFloat,
401      {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
402       fpu_s1},
403      nullptr,
404      nullptr,
405      nullptr,
406     },
407     {"s2",
408      nullptr,
409      4,
410      FPU_OFFSET(2),
411      eEncodingIEEE754,
412      eFormatFloat,
413      {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
414       fpu_s2},
415      nullptr,
416      nullptr,
417      nullptr,
418     },
419     {"s3",
420      nullptr,
421      4,
422      FPU_OFFSET(3),
423      eEncodingIEEE754,
424      eFormatFloat,
425      {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
426       fpu_s3},
427      nullptr,
428      nullptr,
429      nullptr,
430     },
431     {"s4",
432      nullptr,
433      4,
434      FPU_OFFSET(4),
435      eEncodingIEEE754,
436      eFormatFloat,
437      {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
438       fpu_s4},
439      nullptr,
440      nullptr,
441      nullptr,
442     },
443     {"s5",
444      nullptr,
445      4,
446      FPU_OFFSET(5),
447      eEncodingIEEE754,
448      eFormatFloat,
449      {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
450       fpu_s5},
451      nullptr,
452      nullptr,
453      nullptr,
454     },
455     {"s6",
456      nullptr,
457      4,
458      FPU_OFFSET(6),
459      eEncodingIEEE754,
460      eFormatFloat,
461      {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
462       fpu_s6},
463      nullptr,
464      nullptr,
465      nullptr,
466     },
467     {"s7",
468      nullptr,
469      4,
470      FPU_OFFSET(7),
471      eEncodingIEEE754,
472      eFormatFloat,
473      {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
474       fpu_s7},
475      nullptr,
476      nullptr,
477      nullptr,
478     },
479     {"s8",
480      nullptr,
481      4,
482      FPU_OFFSET(8),
483      eEncodingIEEE754,
484      eFormatFloat,
485      {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
486       fpu_s8},
487      nullptr,
488      nullptr,
489      nullptr,
490     },
491     {"s9",
492      nullptr,
493      4,
494      FPU_OFFSET(9),
495      eEncodingIEEE754,
496      eFormatFloat,
497      {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
498       fpu_s9},
499      nullptr,
500      nullptr,
501      nullptr,
502     },
503     {"s10",
504      nullptr,
505      4,
506      FPU_OFFSET(10),
507      eEncodingIEEE754,
508      eFormatFloat,
509      {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
510       fpu_s10},
511      nullptr,
512      nullptr,
513      nullptr,
514     },
515     {"s11",
516      nullptr,
517      4,
518      FPU_OFFSET(11),
519      eEncodingIEEE754,
520      eFormatFloat,
521      {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
522       fpu_s11},
523      nullptr,
524      nullptr,
525      nullptr,
526     },
527     {"s12",
528      nullptr,
529      4,
530      FPU_OFFSET(12),
531      eEncodingIEEE754,
532      eFormatFloat,
533      {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
534       fpu_s12},
535      nullptr,
536      nullptr,
537      nullptr,
538     },
539     {"s13",
540      nullptr,
541      4,
542      FPU_OFFSET(13),
543      eEncodingIEEE754,
544      eFormatFloat,
545      {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
546       fpu_s13},
547      nullptr,
548      nullptr,
549      nullptr,
550     },
551     {"s14",
552      nullptr,
553      4,
554      FPU_OFFSET(14),
555      eEncodingIEEE754,
556      eFormatFloat,
557      {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
558       fpu_s14},
559      nullptr,
560      nullptr,
561      nullptr,
562     },
563     {"s15",
564      nullptr,
565      4,
566      FPU_OFFSET(15),
567      eEncodingIEEE754,
568      eFormatFloat,
569      {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
570       fpu_s15},
571      nullptr,
572      nullptr,
573      nullptr,
574     },
575     {"s16",
576      nullptr,
577      4,
578      FPU_OFFSET(16),
579      eEncodingIEEE754,
580      eFormatFloat,
581      {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
582       fpu_s16},
583      nullptr,
584      nullptr,
585      nullptr,
586     },
587     {"s17",
588      nullptr,
589      4,
590      FPU_OFFSET(17),
591      eEncodingIEEE754,
592      eFormatFloat,
593      {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
594       fpu_s17},
595      nullptr,
596      nullptr,
597      nullptr,
598     },
599     {"s18",
600      nullptr,
601      4,
602      FPU_OFFSET(18),
603      eEncodingIEEE754,
604      eFormatFloat,
605      {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
606       fpu_s18},
607      nullptr,
608      nullptr,
609      nullptr,
610     },
611     {"s19",
612      nullptr,
613      4,
614      FPU_OFFSET(19),
615      eEncodingIEEE754,
616      eFormatFloat,
617      {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
618       fpu_s19},
619      nullptr,
620      nullptr,
621      nullptr,
622     },
623     {"s20",
624      nullptr,
625      4,
626      FPU_OFFSET(20),
627      eEncodingIEEE754,
628      eFormatFloat,
629      {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
630       fpu_s20},
631      nullptr,
632      nullptr,
633      nullptr,
634     },
635     {"s21",
636      nullptr,
637      4,
638      FPU_OFFSET(21),
639      eEncodingIEEE754,
640      eFormatFloat,
641      {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
642       fpu_s21},
643      nullptr,
644      nullptr,
645      nullptr,
646     },
647     {"s22",
648      nullptr,
649      4,
650      FPU_OFFSET(22),
651      eEncodingIEEE754,
652      eFormatFloat,
653      {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
654       fpu_s22},
655      nullptr,
656      nullptr,
657      nullptr,
658     },
659     {"s23",
660      nullptr,
661      4,
662      FPU_OFFSET(23),
663      eEncodingIEEE754,
664      eFormatFloat,
665      {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
666       fpu_s23},
667      nullptr,
668      nullptr,
669      nullptr,
670     },
671     {"s24",
672      nullptr,
673      4,
674      FPU_OFFSET(24),
675      eEncodingIEEE754,
676      eFormatFloat,
677      {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
678       fpu_s24},
679      nullptr,
680      nullptr,
681      nullptr,
682     },
683     {"s25",
684      nullptr,
685      4,
686      FPU_OFFSET(25),
687      eEncodingIEEE754,
688      eFormatFloat,
689      {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
690       fpu_s25},
691      nullptr,
692      nullptr,
693      nullptr,
694     },
695     {"s26",
696      nullptr,
697      4,
698      FPU_OFFSET(26),
699      eEncodingIEEE754,
700      eFormatFloat,
701      {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
702       fpu_s26},
703      nullptr,
704      nullptr,
705      nullptr,
706     },
707     {"s27",
708      nullptr,
709      4,
710      FPU_OFFSET(27),
711      eEncodingIEEE754,
712      eFormatFloat,
713      {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
714       fpu_s27},
715      nullptr,
716      nullptr,
717      nullptr,
718     },
719     {"s28",
720      nullptr,
721      4,
722      FPU_OFFSET(28),
723      eEncodingIEEE754,
724      eFormatFloat,
725      {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
726       fpu_s28},
727      nullptr,
728      nullptr,
729      nullptr,
730     },
731     {"s29",
732      nullptr,
733      4,
734      FPU_OFFSET(29),
735      eEncodingIEEE754,
736      eFormatFloat,
737      {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
738       fpu_s29},
739      nullptr,
740      nullptr,
741      nullptr,
742     },
743     {"s30",
744      nullptr,
745      4,
746      FPU_OFFSET(30),
747      eEncodingIEEE754,
748      eFormatFloat,
749      {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
750       fpu_s30},
751      nullptr,
752      nullptr,
753      nullptr,
754     },
755     {"s31",
756      nullptr,
757      4,
758      FPU_OFFSET(31),
759      eEncodingIEEE754,
760      eFormatFloat,
761      {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
762       fpu_s31},
763      nullptr,
764      nullptr,
765      nullptr,
766     },
767     {"fpscr",
768      nullptr,
769      4,
770      FPU_OFFSET(32),
771      eEncodingUint,
772      eFormatHex,
773      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
774       LLDB_INVALID_REGNUM, fpu_fpscr},
775      nullptr,
776      nullptr,
777      nullptr,
778     },
779 
780     {"exception",
781      nullptr,
782      4,
783      EXC_OFFSET(0),
784      eEncodingUint,
785      eFormatHex,
786      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
787       LLDB_INVALID_REGNUM, exc_exception},
788      nullptr,
789      nullptr,
790      nullptr,
791     },
792     {"fsr",
793      nullptr,
794      4,
795      EXC_OFFSET(1),
796      eEncodingUint,
797      eFormatHex,
798      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
799       LLDB_INVALID_REGNUM, exc_fsr},
800      nullptr,
801      nullptr,
802      nullptr,
803     },
804     {"far",
805      nullptr,
806      4,
807      EXC_OFFSET(2),
808      eEncodingUint,
809      eFormatHex,
810      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
811       LLDB_INVALID_REGNUM, exc_far},
812      nullptr,
813      nullptr,
814      nullptr,
815     },
816 
817     {DEFINE_DBG(bvr, 0)},
818     {DEFINE_DBG(bvr, 1)},
819     {DEFINE_DBG(bvr, 2)},
820     {DEFINE_DBG(bvr, 3)},
821     {DEFINE_DBG(bvr, 4)},
822     {DEFINE_DBG(bvr, 5)},
823     {DEFINE_DBG(bvr, 6)},
824     {DEFINE_DBG(bvr, 7)},
825     {DEFINE_DBG(bvr, 8)},
826     {DEFINE_DBG(bvr, 9)},
827     {DEFINE_DBG(bvr, 10)},
828     {DEFINE_DBG(bvr, 11)},
829     {DEFINE_DBG(bvr, 12)},
830     {DEFINE_DBG(bvr, 13)},
831     {DEFINE_DBG(bvr, 14)},
832     {DEFINE_DBG(bvr, 15)},
833 
834     {DEFINE_DBG(bcr, 0)},
835     {DEFINE_DBG(bcr, 1)},
836     {DEFINE_DBG(bcr, 2)},
837     {DEFINE_DBG(bcr, 3)},
838     {DEFINE_DBG(bcr, 4)},
839     {DEFINE_DBG(bcr, 5)},
840     {DEFINE_DBG(bcr, 6)},
841     {DEFINE_DBG(bcr, 7)},
842     {DEFINE_DBG(bcr, 8)},
843     {DEFINE_DBG(bcr, 9)},
844     {DEFINE_DBG(bcr, 10)},
845     {DEFINE_DBG(bcr, 11)},
846     {DEFINE_DBG(bcr, 12)},
847     {DEFINE_DBG(bcr, 13)},
848     {DEFINE_DBG(bcr, 14)},
849     {DEFINE_DBG(bcr, 15)},
850 
851     {DEFINE_DBG(wvr, 0)},
852     {DEFINE_DBG(wvr, 1)},
853     {DEFINE_DBG(wvr, 2)},
854     {DEFINE_DBG(wvr, 3)},
855     {DEFINE_DBG(wvr, 4)},
856     {DEFINE_DBG(wvr, 5)},
857     {DEFINE_DBG(wvr, 6)},
858     {DEFINE_DBG(wvr, 7)},
859     {DEFINE_DBG(wvr, 8)},
860     {DEFINE_DBG(wvr, 9)},
861     {DEFINE_DBG(wvr, 10)},
862     {DEFINE_DBG(wvr, 11)},
863     {DEFINE_DBG(wvr, 12)},
864     {DEFINE_DBG(wvr, 13)},
865     {DEFINE_DBG(wvr, 14)},
866     {DEFINE_DBG(wvr, 15)},
867 
868     {DEFINE_DBG(wcr, 0)},
869     {DEFINE_DBG(wcr, 1)},
870     {DEFINE_DBG(wcr, 2)},
871     {DEFINE_DBG(wcr, 3)},
872     {DEFINE_DBG(wcr, 4)},
873     {DEFINE_DBG(wcr, 5)},
874     {DEFINE_DBG(wcr, 6)},
875     {DEFINE_DBG(wcr, 7)},
876     {DEFINE_DBG(wcr, 8)},
877     {DEFINE_DBG(wcr, 9)},
878     {DEFINE_DBG(wcr, 10)},
879     {DEFINE_DBG(wcr, 11)},
880     {DEFINE_DBG(wcr, 12)},
881     {DEFINE_DBG(wcr, 13)},
882     {DEFINE_DBG(wcr, 14)},
883     {DEFINE_DBG(wcr, 15)}};
884 
885 // General purpose registers
886 static uint32_t g_gpr_regnums[] = {
887     gpr_r0, gpr_r1,  gpr_r2,  gpr_r3,  gpr_r4, gpr_r5, gpr_r6, gpr_r7,  gpr_r8,
888     gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr};
889 
890 // Floating point registers
891 static uint32_t g_fpu_regnums[] = {
892     fpu_s0,  fpu_s1,  fpu_s2,  fpu_s3,  fpu_s4,    fpu_s5,  fpu_s6,
893     fpu_s7,  fpu_s8,  fpu_s9,  fpu_s10, fpu_s11,   fpu_s12, fpu_s13,
894     fpu_s14, fpu_s15, fpu_s16, fpu_s17, fpu_s18,   fpu_s19, fpu_s20,
895     fpu_s21, fpu_s22, fpu_s23, fpu_s24, fpu_s25,   fpu_s26, fpu_s27,
896     fpu_s28, fpu_s29, fpu_s30, fpu_s31, fpu_fpscr,
897 };
898 
899 // Exception registers
900 
901 static uint32_t g_exc_regnums[] = {
902     exc_exception, exc_fsr, exc_far,
903 };
904 
905 static size_t k_num_register_infos = std::size(g_register_infos);
906 
907 RegisterContextDarwin_arm::RegisterContextDarwin_arm(
908     Thread &thread, uint32_t concrete_frame_idx)
909     : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
910   uint32_t i;
911   for (i = 0; i < kNumErrors; i++) {
912     gpr_errs[i] = -1;
913     fpu_errs[i] = -1;
914     exc_errs[i] = -1;
915   }
916 }
917 
918 RegisterContextDarwin_arm::~RegisterContextDarwin_arm() = default;
919 
920 void RegisterContextDarwin_arm::InvalidateAllRegisters() {
921   InvalidateAllRegisterStates();
922 }
923 
924 size_t RegisterContextDarwin_arm::GetRegisterCount() {
925   assert(k_num_register_infos == k_num_registers);
926   return k_num_registers;
927 }
928 
929 const RegisterInfo *
930 RegisterContextDarwin_arm::GetRegisterInfoAtIndex(size_t reg) {
931   assert(k_num_register_infos == k_num_registers);
932   if (reg < k_num_registers)
933     return &g_register_infos[reg];
934   return nullptr;
935 }
936 
937 size_t RegisterContextDarwin_arm::GetRegisterInfosCount() {
938   return k_num_register_infos;
939 }
940 
941 const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() {
942   return g_register_infos;
943 }
944 
945 // Number of registers in each register set
946 const size_t k_num_gpr_registers = std::size(g_gpr_regnums);
947 const size_t k_num_fpu_registers = std::size(g_fpu_regnums);
948 const size_t k_num_exc_registers = std::size(g_exc_regnums);
949 
950 // Register set definitions. The first definitions at register set index of
951 // zero is for all registers, followed by other registers sets. The register
952 // information for the all register set need not be filled in.
953 static const RegisterSet g_reg_sets[] = {
954     {
955         "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
956     },
957     {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
958     {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
959 
960 const size_t k_num_regsets = std::size(g_reg_sets);
961 
962 size_t RegisterContextDarwin_arm::GetRegisterSetCount() {
963   return k_num_regsets;
964 }
965 
966 const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) {
967   if (reg_set < k_num_regsets)
968     return &g_reg_sets[reg_set];
969   return nullptr;
970 }
971 
972 // Register information definitions for 32 bit i386.
973 int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) {
974   if (reg < fpu_s0)
975     return GPRRegSet;
976   else if (reg < exc_exception)
977     return FPURegSet;
978   else if (reg < k_num_registers)
979     return EXCRegSet;
980   return -1;
981 }
982 
983 int RegisterContextDarwin_arm::ReadGPR(bool force) {
984   int set = GPRRegSet;
985   if (force || !RegisterSetIsCached(set)) {
986     SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
987   }
988   return GetError(GPRRegSet, Read);
989 }
990 
991 int RegisterContextDarwin_arm::ReadFPU(bool force) {
992   int set = FPURegSet;
993   if (force || !RegisterSetIsCached(set)) {
994     SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
995   }
996   return GetError(FPURegSet, Read);
997 }
998 
999 int RegisterContextDarwin_arm::ReadEXC(bool force) {
1000   int set = EXCRegSet;
1001   if (force || !RegisterSetIsCached(set)) {
1002     SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
1003   }
1004   return GetError(EXCRegSet, Read);
1005 }
1006 
1007 int RegisterContextDarwin_arm::ReadDBG(bool force) {
1008   int set = DBGRegSet;
1009   if (force || !RegisterSetIsCached(set)) {
1010     SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
1011   }
1012   return GetError(DBGRegSet, Read);
1013 }
1014 
1015 int RegisterContextDarwin_arm::WriteGPR() {
1016   int set = GPRRegSet;
1017   if (!RegisterSetIsCached(set)) {
1018     SetError(set, Write, -1);
1019     return KERN_INVALID_ARGUMENT;
1020   }
1021   SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
1022   SetError(set, Read, -1);
1023   return GetError(GPRRegSet, Write);
1024 }
1025 
1026 int RegisterContextDarwin_arm::WriteFPU() {
1027   int set = FPURegSet;
1028   if (!RegisterSetIsCached(set)) {
1029     SetError(set, Write, -1);
1030     return KERN_INVALID_ARGUMENT;
1031   }
1032   SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
1033   SetError(set, Read, -1);
1034   return GetError(FPURegSet, Write);
1035 }
1036 
1037 int RegisterContextDarwin_arm::WriteEXC() {
1038   int set = EXCRegSet;
1039   if (!RegisterSetIsCached(set)) {
1040     SetError(set, Write, -1);
1041     return KERN_INVALID_ARGUMENT;
1042   }
1043   SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
1044   SetError(set, Read, -1);
1045   return GetError(EXCRegSet, Write);
1046 }
1047 
1048 int RegisterContextDarwin_arm::WriteDBG() {
1049   int set = DBGRegSet;
1050   if (!RegisterSetIsCached(set)) {
1051     SetError(set, Write, -1);
1052     return KERN_INVALID_ARGUMENT;
1053   }
1054   SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));
1055   SetError(set, Read, -1);
1056   return GetError(DBGRegSet, Write);
1057 }
1058 
1059 int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) {
1060   switch (set) {
1061   case GPRRegSet:
1062     return ReadGPR(force);
1063   case GPRAltRegSet:
1064     return ReadGPR(force);
1065   case FPURegSet:
1066     return ReadFPU(force);
1067   case EXCRegSet:
1068     return ReadEXC(force);
1069   case DBGRegSet:
1070     return ReadDBG(force);
1071   default:
1072     break;
1073   }
1074   return KERN_INVALID_ARGUMENT;
1075 }
1076 
1077 int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {
1078   // Make sure we have a valid context to set.
1079   if (RegisterSetIsCached(set)) {
1080     switch (set) {
1081     case GPRRegSet:
1082       return WriteGPR();
1083     case GPRAltRegSet:
1084       return WriteGPR();
1085     case FPURegSet:
1086       return WriteFPU();
1087     case EXCRegSet:
1088       return WriteEXC();
1089     case DBGRegSet:
1090       return WriteDBG();
1091     default:
1092       break;
1093     }
1094   }
1095   return KERN_INVALID_ARGUMENT;
1096 }
1097 
1098 void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {
1099   if (log) {
1100     for (uint32_t i = 0; i < 16; i++)
1101       LLDB_LOGF(log,
1102                 "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
1103                 "0x%8.8x, 0x%8.8x }",
1104                 i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
1105   }
1106 }
1107 
1108 bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info,
1109                                              RegisterValue &value) {
1110   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1111   int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg);
1112 
1113   if (set == -1)
1114     return false;
1115 
1116   if (ReadRegisterSet(set, false) != KERN_SUCCESS)
1117     return false;
1118 
1119   switch (reg) {
1120   case gpr_r0:
1121   case gpr_r1:
1122   case gpr_r2:
1123   case gpr_r3:
1124   case gpr_r4:
1125   case gpr_r5:
1126   case gpr_r6:
1127   case gpr_r7:
1128   case gpr_r8:
1129   case gpr_r9:
1130   case gpr_r10:
1131   case gpr_r11:
1132   case gpr_r12:
1133   case gpr_sp:
1134   case gpr_lr:
1135   case gpr_pc:
1136     value.SetUInt32(gpr.r[reg - gpr_r0]);
1137     break;
1138   case gpr_cpsr:
1139     value.SetUInt32(gpr.cpsr);
1140     break;
1141   case fpu_s0:
1142   case fpu_s1:
1143   case fpu_s2:
1144   case fpu_s3:
1145   case fpu_s4:
1146   case fpu_s5:
1147   case fpu_s6:
1148   case fpu_s7:
1149   case fpu_s8:
1150   case fpu_s9:
1151   case fpu_s10:
1152   case fpu_s11:
1153   case fpu_s12:
1154   case fpu_s13:
1155   case fpu_s14:
1156   case fpu_s15:
1157   case fpu_s16:
1158   case fpu_s17:
1159   case fpu_s18:
1160   case fpu_s19:
1161   case fpu_s20:
1162   case fpu_s21:
1163   case fpu_s22:
1164   case fpu_s23:
1165   case fpu_s24:
1166   case fpu_s25:
1167   case fpu_s26:
1168   case fpu_s27:
1169   case fpu_s28:
1170   case fpu_s29:
1171   case fpu_s30:
1172   case fpu_s31:
1173     value.SetUInt32(fpu.floats.s[reg], RegisterValue::eTypeFloat);
1174     break;
1175 
1176   case fpu_fpscr:
1177     value.SetUInt32(fpu.fpscr);
1178     break;
1179 
1180   case exc_exception:
1181     value.SetUInt32(exc.exception);
1182     break;
1183   case exc_fsr:
1184     value.SetUInt32(exc.fsr);
1185     break;
1186   case exc_far:
1187     value.SetUInt32(exc.far);
1188     break;
1189 
1190   default:
1191     value.SetValueToInvalid();
1192     return false;
1193   }
1194   return true;
1195 }
1196 
1197 bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info,
1198                                               const RegisterValue &value) {
1199   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1200   int set = GetSetForNativeRegNum(reg);
1201 
1202   if (set == -1)
1203     return false;
1204 
1205   if (ReadRegisterSet(set, false) != KERN_SUCCESS)
1206     return false;
1207 
1208   switch (reg) {
1209   case gpr_r0:
1210   case gpr_r1:
1211   case gpr_r2:
1212   case gpr_r3:
1213   case gpr_r4:
1214   case gpr_r5:
1215   case gpr_r6:
1216   case gpr_r7:
1217   case gpr_r8:
1218   case gpr_r9:
1219   case gpr_r10:
1220   case gpr_r11:
1221   case gpr_r12:
1222   case gpr_sp:
1223   case gpr_lr:
1224   case gpr_pc:
1225   case gpr_cpsr:
1226     gpr.r[reg - gpr_r0] = value.GetAsUInt32();
1227     break;
1228 
1229   case fpu_s0:
1230   case fpu_s1:
1231   case fpu_s2:
1232   case fpu_s3:
1233   case fpu_s4:
1234   case fpu_s5:
1235   case fpu_s6:
1236   case fpu_s7:
1237   case fpu_s8:
1238   case fpu_s9:
1239   case fpu_s10:
1240   case fpu_s11:
1241   case fpu_s12:
1242   case fpu_s13:
1243   case fpu_s14:
1244   case fpu_s15:
1245   case fpu_s16:
1246   case fpu_s17:
1247   case fpu_s18:
1248   case fpu_s19:
1249   case fpu_s20:
1250   case fpu_s21:
1251   case fpu_s22:
1252   case fpu_s23:
1253   case fpu_s24:
1254   case fpu_s25:
1255   case fpu_s26:
1256   case fpu_s27:
1257   case fpu_s28:
1258   case fpu_s29:
1259   case fpu_s30:
1260   case fpu_s31:
1261     fpu.floats.s[reg] = value.GetAsUInt32();
1262     break;
1263 
1264   case fpu_fpscr:
1265     fpu.fpscr = value.GetAsUInt32();
1266     break;
1267 
1268   case exc_exception:
1269     exc.exception = value.GetAsUInt32();
1270     break;
1271   case exc_fsr:
1272     exc.fsr = value.GetAsUInt32();
1273     break;
1274   case exc_far:
1275     exc.far = value.GetAsUInt32();
1276     break;
1277 
1278   default:
1279     return false;
1280   }
1281   return WriteRegisterSet(set) == KERN_SUCCESS;
1282 }
1283 
1284 bool RegisterContextDarwin_arm::ReadAllRegisterValues(
1285     lldb::WritableDataBufferSP &data_sp) {
1286   data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);
1287   if (data_sp && ReadGPR(false) == KERN_SUCCESS &&
1288       ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {
1289     uint8_t *dst = data_sp->GetBytes();
1290     ::memcpy(dst, &gpr, sizeof(gpr));
1291     dst += sizeof(gpr);
1292 
1293     ::memcpy(dst, &fpu, sizeof(fpu));
1294     dst += sizeof(gpr);
1295 
1296     ::memcpy(dst, &exc, sizeof(exc));
1297     return true;
1298   }
1299   return false;
1300 }
1301 
1302 bool RegisterContextDarwin_arm::WriteAllRegisterValues(
1303     const lldb::DataBufferSP &data_sp) {
1304   if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
1305     const uint8_t *src = data_sp->GetBytes();
1306     ::memcpy(&gpr, src, sizeof(gpr));
1307     src += sizeof(gpr);
1308 
1309     ::memcpy(&fpu, src, sizeof(fpu));
1310     src += sizeof(gpr);
1311 
1312     ::memcpy(&exc, src, sizeof(exc));
1313     uint32_t success_count = 0;
1314     if (WriteGPR() == KERN_SUCCESS)
1315       ++success_count;
1316     if (WriteFPU() == KERN_SUCCESS)
1317       ++success_count;
1318     if (WriteEXC() == KERN_SUCCESS)
1319       ++success_count;
1320     return success_count == 3;
1321   }
1322   return false;
1323 }
1324 
1325 uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(
1326     lldb::RegisterKind kind, uint32_t reg) {
1327   if (kind == eRegisterKindGeneric) {
1328     switch (reg) {
1329     case LLDB_REGNUM_GENERIC_PC:
1330       return gpr_pc;
1331     case LLDB_REGNUM_GENERIC_SP:
1332       return gpr_sp;
1333     case LLDB_REGNUM_GENERIC_FP:
1334       return gpr_r7;
1335     case LLDB_REGNUM_GENERIC_RA:
1336       return gpr_lr;
1337     case LLDB_REGNUM_GENERIC_FLAGS:
1338       return gpr_cpsr;
1339     default:
1340       break;
1341     }
1342   } else if (kind == eRegisterKindDWARF) {
1343     switch (reg) {
1344     case dwarf_r0:
1345       return gpr_r0;
1346     case dwarf_r1:
1347       return gpr_r1;
1348     case dwarf_r2:
1349       return gpr_r2;
1350     case dwarf_r3:
1351       return gpr_r3;
1352     case dwarf_r4:
1353       return gpr_r4;
1354     case dwarf_r5:
1355       return gpr_r5;
1356     case dwarf_r6:
1357       return gpr_r6;
1358     case dwarf_r7:
1359       return gpr_r7;
1360     case dwarf_r8:
1361       return gpr_r8;
1362     case dwarf_r9:
1363       return gpr_r9;
1364     case dwarf_r10:
1365       return gpr_r10;
1366     case dwarf_r11:
1367       return gpr_r11;
1368     case dwarf_r12:
1369       return gpr_r12;
1370     case dwarf_sp:
1371       return gpr_sp;
1372     case dwarf_lr:
1373       return gpr_lr;
1374     case dwarf_pc:
1375       return gpr_pc;
1376     case dwarf_spsr:
1377       return gpr_cpsr;
1378 
1379     case dwarf_s0:
1380       return fpu_s0;
1381     case dwarf_s1:
1382       return fpu_s1;
1383     case dwarf_s2:
1384       return fpu_s2;
1385     case dwarf_s3:
1386       return fpu_s3;
1387     case dwarf_s4:
1388       return fpu_s4;
1389     case dwarf_s5:
1390       return fpu_s5;
1391     case dwarf_s6:
1392       return fpu_s6;
1393     case dwarf_s7:
1394       return fpu_s7;
1395     case dwarf_s8:
1396       return fpu_s8;
1397     case dwarf_s9:
1398       return fpu_s9;
1399     case dwarf_s10:
1400       return fpu_s10;
1401     case dwarf_s11:
1402       return fpu_s11;
1403     case dwarf_s12:
1404       return fpu_s12;
1405     case dwarf_s13:
1406       return fpu_s13;
1407     case dwarf_s14:
1408       return fpu_s14;
1409     case dwarf_s15:
1410       return fpu_s15;
1411     case dwarf_s16:
1412       return fpu_s16;
1413     case dwarf_s17:
1414       return fpu_s17;
1415     case dwarf_s18:
1416       return fpu_s18;
1417     case dwarf_s19:
1418       return fpu_s19;
1419     case dwarf_s20:
1420       return fpu_s20;
1421     case dwarf_s21:
1422       return fpu_s21;
1423     case dwarf_s22:
1424       return fpu_s22;
1425     case dwarf_s23:
1426       return fpu_s23;
1427     case dwarf_s24:
1428       return fpu_s24;
1429     case dwarf_s25:
1430       return fpu_s25;
1431     case dwarf_s26:
1432       return fpu_s26;
1433     case dwarf_s27:
1434       return fpu_s27;
1435     case dwarf_s28:
1436       return fpu_s28;
1437     case dwarf_s29:
1438       return fpu_s29;
1439     case dwarf_s30:
1440       return fpu_s30;
1441     case dwarf_s31:
1442       return fpu_s31;
1443 
1444     default:
1445       break;
1446     }
1447   } else if (kind == eRegisterKindEHFrame) {
1448     switch (reg) {
1449     case ehframe_r0:
1450       return gpr_r0;
1451     case ehframe_r1:
1452       return gpr_r1;
1453     case ehframe_r2:
1454       return gpr_r2;
1455     case ehframe_r3:
1456       return gpr_r3;
1457     case ehframe_r4:
1458       return gpr_r4;
1459     case ehframe_r5:
1460       return gpr_r5;
1461     case ehframe_r6:
1462       return gpr_r6;
1463     case ehframe_r7:
1464       return gpr_r7;
1465     case ehframe_r8:
1466       return gpr_r8;
1467     case ehframe_r9:
1468       return gpr_r9;
1469     case ehframe_r10:
1470       return gpr_r10;
1471     case ehframe_r11:
1472       return gpr_r11;
1473     case ehframe_r12:
1474       return gpr_r12;
1475     case ehframe_sp:
1476       return gpr_sp;
1477     case ehframe_lr:
1478       return gpr_lr;
1479     case ehframe_pc:
1480       return gpr_pc;
1481     case ehframe_cpsr:
1482       return gpr_cpsr;
1483     }
1484   } else if (kind == eRegisterKindLLDB) {
1485     return reg;
1486   }
1487   return LLDB_INVALID_REGNUM;
1488 }
1489 
1490 uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
1491 #if defined(__APPLE__) && defined(__arm__)
1492   // Set the init value to something that will let us know that we need to
1493   // autodetect how many breakpoints are supported dynamically...
1494   static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
1495   if (g_num_supported_hw_breakpoints == UINT32_MAX) {
1496     // Set this to zero in case we can't tell if there are any HW breakpoints
1497     g_num_supported_hw_breakpoints = 0;
1498 
1499     uint32_t register_DBGDIDR;
1500 
1501     asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1502     g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24);
1503     // Zero is reserved for the BRP count, so don't increment it if it is zero
1504     if (g_num_supported_hw_breakpoints > 0)
1505       g_num_supported_hw_breakpoints++;
1506   }
1507   return g_num_supported_hw_breakpoints;
1508 #else
1509   // TODO: figure out remote case here!
1510   return 6;
1511 #endif
1512 }
1513 
1514 uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr,
1515                                                           size_t size) {
1516   // Make sure our address isn't bogus
1517   if (addr & 1)
1518     return LLDB_INVALID_INDEX32;
1519 
1520   int kret = ReadDBG(false);
1521 
1522   if (kret == KERN_SUCCESS) {
1523     const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
1524     uint32_t i;
1525     for (i = 0; i < num_hw_breakpoints; ++i) {
1526       if ((dbg.bcr[i] & BCR_ENABLE) == 0)
1527         break; // We found an available hw breakpoint slot (in i)
1528     }
1529 
1530     // See if we found an available hw breakpoint slot above
1531     if (i < num_hw_breakpoints) {
1532       // Make sure bits 1:0 are clear in our address
1533       dbg.bvr[i] = addr & ~((lldb::addr_t)3);
1534 
1535       if (size == 2 || addr & 2) {
1536         uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
1537 
1538         // We have a thumb breakpoint
1539         // We have an ARM breakpoint
1540         dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address match
1541                      byte_addr_select | // Set the correct byte address select
1542                                         // so we only trigger on the correct
1543                                         // opcode
1544                      S_USER |    // Which modes should this breakpoint stop in?
1545                      BCR_ENABLE; // Enable this hardware breakpoint
1546                                  //                if (log) log->Printf
1547         //                ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1548         //                addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1549         //                0x%8.8x (Thumb)",
1550         //                        addr,
1551         //                        size,
1552         //                        i,
1553         //                        i,
1554         //                        dbg.bvr[i],
1555         //                        dbg.bcr[i]);
1556       } else if (size == 4) {
1557         // We have an ARM breakpoint
1558         dbg.bcr[i] =
1559             BCR_M_IMVA_MATCH | // Stop on address match
1560             BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
1561             S_USER |       // Which modes should this breakpoint stop in?
1562             BCR_ENABLE;    // Enable this hardware breakpoint
1563                            //                if (log) log->Printf
1564         //                ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1565         //                addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1566         //                0x%8.8x (ARM)",
1567         //                        addr,
1568         //                        size,
1569         //                        i,
1570         //                        i,
1571         //                        dbg.bvr[i],
1572         //                        dbg.bcr[i]);
1573       }
1574 
1575       kret = WriteDBG();
1576       //            if (log) log->Printf
1577       //            ("RegisterContextDarwin_arm::EnableHardwareBreakpoint()
1578       //            WriteDBG() => 0x%8.8x.", kret);
1579 
1580       if (kret == KERN_SUCCESS)
1581         return i;
1582     }
1583     //        else
1584     //        {
1585     //            if (log) log->Printf
1586     //            ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr =
1587     //            %8.8p, size = %u) => all hardware breakpoint resources are
1588     //            being used.", addr, size);
1589     //        }
1590   }
1591 
1592   return LLDB_INVALID_INDEX32;
1593 }
1594 
1595 bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {
1596   int kret = ReadDBG(false);
1597 
1598   const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
1599   if (kret == KERN_SUCCESS) {
1600     if (hw_index < num_hw_points) {
1601       dbg.bcr[hw_index] = 0;
1602       //            if (log) log->Printf
1603       //            ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) -
1604       //            BVR%u = 0x%8.8x  BCR%u = 0x%8.8x",
1605       //                    hw_index,
1606       //                    hw_index,
1607       //                    dbg.bvr[hw_index],
1608       //                    hw_index,
1609       //                    dbg.bcr[hw_index]);
1610 
1611       kret = WriteDBG();
1612 
1613       if (kret == KERN_SUCCESS)
1614         return true;
1615     }
1616   }
1617   return false;
1618 }
1619 
1620 uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
1621 #if defined(__APPLE__) && defined(__arm__)
1622   // Set the init value to something that will let us know that we need to
1623   // autodetect how many watchpoints are supported dynamically...
1624   static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
1625   if (g_num_supported_hw_watchpoints == UINT32_MAX) {
1626     // Set this to zero in case we can't tell if there are any HW breakpoints
1627     g_num_supported_hw_watchpoints = 0;
1628 
1629     uint32_t register_DBGDIDR;
1630     asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1631     g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;
1632   }
1633   return g_num_supported_hw_watchpoints;
1634 #else
1635   // TODO: figure out remote case here!
1636   return 2;
1637 #endif
1638 }
1639 
1640 uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
1641                                                           size_t size,
1642                                                           bool read,
1643                                                           bool write) {
1644   const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1645 
1646   // Can't watch zero bytes
1647   if (size == 0)
1648     return LLDB_INVALID_INDEX32;
1649 
1650   // We must watch for either read or write
1651   if (!read && !write)
1652     return LLDB_INVALID_INDEX32;
1653 
1654   // Can't watch more than 4 bytes per WVR/WCR pair
1655   if (size > 4)
1656     return LLDB_INVALID_INDEX32;
1657 
1658   // We can only watch up to four bytes that follow a 4 byte aligned address
1659   // per watchpoint register pair. Since we have at most so we can only watch
1660   // until the next 4 byte boundary and we need to make sure we can properly
1661   // encode this.
1662   uint32_t addr_word_offset = addr % 4;
1663   //    if (log) log->Printf
1664   //    ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() -
1665   //    addr_word_offset = 0x%8.8x", addr_word_offset);
1666 
1667   uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
1668   //    if (log) log->Printf
1669   //    ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask =
1670   //    0x%8.8x", byte_mask);
1671   if (byte_mask > 0xfu)
1672     return LLDB_INVALID_INDEX32;
1673 
1674   // Read the debug state
1675   int kret = ReadDBG(false);
1676 
1677   if (kret == KERN_SUCCESS) {
1678     // Check to make sure we have the needed hardware support
1679     uint32_t i = 0;
1680 
1681     for (i = 0; i < num_hw_watchpoints; ++i) {
1682       if ((dbg.wcr[i] & WCR_ENABLE) == 0)
1683         break; // We found an available hw breakpoint slot (in i)
1684     }
1685 
1686     // See if we found an available hw breakpoint slot above
1687     if (i < num_hw_watchpoints) {
1688       // Make the byte_mask into a valid Byte Address Select mask
1689       uint32_t byte_address_select = byte_mask << 5;
1690       // Make sure bits 1:0 are clear in our address
1691       dbg.wvr[i] = addr & ~((lldb::addr_t)3);
1692       dbg.wcr[i] = byte_address_select |     // Which bytes that follow the IMVA
1693                                              // that we will watch
1694                    S_USER |                  // Stop only in user mode
1695                    (read ? WCR_LOAD : 0) |   // Stop on read access?
1696                    (write ? WCR_STORE : 0) | // Stop on write access?
1697                    WCR_ENABLE;               // Enable this watchpoint;
1698 
1699       kret = WriteDBG();
1700       //            if (log) log->Printf
1701       //            ("RegisterContextDarwin_arm::EnableHardwareWatchpoint()
1702       //            WriteDBG() => 0x%8.8x.", kret);
1703 
1704       if (kret == KERN_SUCCESS)
1705         return i;
1706     } else {
1707       //            if (log) log->Printf
1708       //            ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All
1709       //            hardware resources (%u) are in use.", num_hw_watchpoints);
1710     }
1711   }
1712   return LLDB_INVALID_INDEX32;
1713 }
1714 
1715 bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {
1716   int kret = ReadDBG(false);
1717 
1718   const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
1719   if (kret == KERN_SUCCESS) {
1720     if (hw_index < num_hw_points) {
1721       dbg.wcr[hw_index] = 0;
1722       //            if (log) log->Printf
1723       //            ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) -
1724       //            WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
1725       //                    hw_index,
1726       //                    hw_index,
1727       //                    dbg.wvr[hw_index],
1728       //                    hw_index,
1729       //                    dbg.wcr[hw_index]);
1730 
1731       kret = WriteDBG();
1732 
1733       if (kret == KERN_SUCCESS)
1734         return true;
1735     }
1736   }
1737   return false;
1738 }
1739