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