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