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