RegisterContextDarwin_arm.cpp revision 360660
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
35using namespace lldb;
36using namespace lldb_private;
37
38enum {
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
192static 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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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     nullptr,
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
899static 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
904static 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
914static uint32_t g_exc_regnums[] = {
915    exc_exception, exc_fsr, exc_far,
916};
917
918static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
919
920RegisterContextDarwin_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
931RegisterContextDarwin_arm::~RegisterContextDarwin_arm() {}
932
933void RegisterContextDarwin_arm::InvalidateAllRegisters() {
934  InvalidateAllRegisterStates();
935}
936
937size_t RegisterContextDarwin_arm::GetRegisterCount() {
938  assert(k_num_register_infos == k_num_registers);
939  return k_num_registers;
940}
941
942const RegisterInfo *
943RegisterContextDarwin_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 nullptr;
948}
949
950size_t RegisterContextDarwin_arm::GetRegisterInfosCount() {
951  return k_num_register_infos;
952}
953
954const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() {
955  return g_register_infos;
956}
957
958// Number of registers in each register set
959const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
960const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
961const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
962
963// Register set definitions. The first definitions at register set index of
964// zero is for all registers, followed by other registers sets. The register
965// information for the all register set need not be filled in.
966static const RegisterSet g_reg_sets[] = {
967    {
968        "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
969    },
970    {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
971    {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
972
973const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
974
975size_t RegisterContextDarwin_arm::GetRegisterSetCount() {
976  return k_num_regsets;
977}
978
979const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) {
980  if (reg_set < k_num_regsets)
981    return &g_reg_sets[reg_set];
982  return nullptr;
983}
984
985// Register information definitions for 32 bit i386.
986int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) {
987  if (reg < fpu_s0)
988    return GPRRegSet;
989  else if (reg < exc_exception)
990    return FPURegSet;
991  else if (reg < k_num_registers)
992    return EXCRegSet;
993  return -1;
994}
995
996int RegisterContextDarwin_arm::ReadGPR(bool force) {
997  int set = GPRRegSet;
998  if (force || !RegisterSetIsCached(set)) {
999    SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
1000  }
1001  return GetError(GPRRegSet, Read);
1002}
1003
1004int RegisterContextDarwin_arm::ReadFPU(bool force) {
1005  int set = FPURegSet;
1006  if (force || !RegisterSetIsCached(set)) {
1007    SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
1008  }
1009  return GetError(FPURegSet, Read);
1010}
1011
1012int RegisterContextDarwin_arm::ReadEXC(bool force) {
1013  int set = EXCRegSet;
1014  if (force || !RegisterSetIsCached(set)) {
1015    SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
1016  }
1017  return GetError(EXCRegSet, Read);
1018}
1019
1020int RegisterContextDarwin_arm::ReadDBG(bool force) {
1021  int set = DBGRegSet;
1022  if (force || !RegisterSetIsCached(set)) {
1023    SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
1024  }
1025  return GetError(DBGRegSet, Read);
1026}
1027
1028int RegisterContextDarwin_arm::WriteGPR() {
1029  int set = GPRRegSet;
1030  if (!RegisterSetIsCached(set)) {
1031    SetError(set, Write, -1);
1032    return KERN_INVALID_ARGUMENT;
1033  }
1034  SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
1035  SetError(set, Read, -1);
1036  return GetError(GPRRegSet, Write);
1037}
1038
1039int RegisterContextDarwin_arm::WriteFPU() {
1040  int set = FPURegSet;
1041  if (!RegisterSetIsCached(set)) {
1042    SetError(set, Write, -1);
1043    return KERN_INVALID_ARGUMENT;
1044  }
1045  SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
1046  SetError(set, Read, -1);
1047  return GetError(FPURegSet, Write);
1048}
1049
1050int RegisterContextDarwin_arm::WriteEXC() {
1051  int set = EXCRegSet;
1052  if (!RegisterSetIsCached(set)) {
1053    SetError(set, Write, -1);
1054    return KERN_INVALID_ARGUMENT;
1055  }
1056  SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
1057  SetError(set, Read, -1);
1058  return GetError(EXCRegSet, Write);
1059}
1060
1061int RegisterContextDarwin_arm::WriteDBG() {
1062  int set = DBGRegSet;
1063  if (!RegisterSetIsCached(set)) {
1064    SetError(set, Write, -1);
1065    return KERN_INVALID_ARGUMENT;
1066  }
1067  SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));
1068  SetError(set, Read, -1);
1069  return GetError(DBGRegSet, Write);
1070}
1071
1072int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) {
1073  switch (set) {
1074  case GPRRegSet:
1075    return ReadGPR(force);
1076  case GPRAltRegSet:
1077    return ReadGPR(force);
1078  case FPURegSet:
1079    return ReadFPU(force);
1080  case EXCRegSet:
1081    return ReadEXC(force);
1082  case DBGRegSet:
1083    return ReadDBG(force);
1084  default:
1085    break;
1086  }
1087  return KERN_INVALID_ARGUMENT;
1088}
1089
1090int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {
1091  // Make sure we have a valid context to set.
1092  if (RegisterSetIsCached(set)) {
1093    switch (set) {
1094    case GPRRegSet:
1095      return WriteGPR();
1096    case GPRAltRegSet:
1097      return WriteGPR();
1098    case FPURegSet:
1099      return WriteFPU();
1100    case EXCRegSet:
1101      return WriteEXC();
1102    case DBGRegSet:
1103      return WriteDBG();
1104    default:
1105      break;
1106    }
1107  }
1108  return KERN_INVALID_ARGUMENT;
1109}
1110
1111void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {
1112  if (log) {
1113    for (uint32_t i = 0; i < 16; i++)
1114      log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
1115                  "0x%8.8x, 0x%8.8x }",
1116                  i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
1117  }
1118}
1119
1120bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info,
1121                                             RegisterValue &value) {
1122  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1123  int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg);
1124
1125  if (set == -1)
1126    return false;
1127
1128  if (ReadRegisterSet(set, false) != KERN_SUCCESS)
1129    return false;
1130
1131  switch (reg) {
1132  case gpr_r0:
1133  case gpr_r1:
1134  case gpr_r2:
1135  case gpr_r3:
1136  case gpr_r4:
1137  case gpr_r5:
1138  case gpr_r6:
1139  case gpr_r7:
1140  case gpr_r8:
1141  case gpr_r9:
1142  case gpr_r10:
1143  case gpr_r11:
1144  case gpr_r12:
1145  case gpr_sp:
1146  case gpr_lr:
1147  case gpr_pc:
1148  case gpr_cpsr:
1149    value.SetUInt32(gpr.r[reg - gpr_r0]);
1150    break;
1151
1152  case fpu_s0:
1153  case fpu_s1:
1154  case fpu_s2:
1155  case fpu_s3:
1156  case fpu_s4:
1157  case fpu_s5:
1158  case fpu_s6:
1159  case fpu_s7:
1160  case fpu_s8:
1161  case fpu_s9:
1162  case fpu_s10:
1163  case fpu_s11:
1164  case fpu_s12:
1165  case fpu_s13:
1166  case fpu_s14:
1167  case fpu_s15:
1168  case fpu_s16:
1169  case fpu_s17:
1170  case fpu_s18:
1171  case fpu_s19:
1172  case fpu_s20:
1173  case fpu_s21:
1174  case fpu_s22:
1175  case fpu_s23:
1176  case fpu_s24:
1177  case fpu_s25:
1178  case fpu_s26:
1179  case fpu_s27:
1180  case fpu_s28:
1181  case fpu_s29:
1182  case fpu_s30:
1183  case fpu_s31:
1184    value.SetUInt32(fpu.floats.s[reg], RegisterValue::eTypeFloat);
1185    break;
1186
1187  case fpu_fpscr:
1188    value.SetUInt32(fpu.fpscr);
1189    break;
1190
1191  case exc_exception:
1192    value.SetUInt32(exc.exception);
1193    break;
1194  case exc_fsr:
1195    value.SetUInt32(exc.fsr);
1196    break;
1197  case exc_far:
1198    value.SetUInt32(exc.far);
1199    break;
1200
1201  default:
1202    value.SetValueToInvalid();
1203    return false;
1204  }
1205  return true;
1206}
1207
1208bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info,
1209                                              const RegisterValue &value) {
1210  const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1211  int set = GetSetForNativeRegNum(reg);
1212
1213  if (set == -1)
1214    return false;
1215
1216  if (ReadRegisterSet(set, false) != KERN_SUCCESS)
1217    return false;
1218
1219  switch (reg) {
1220  case gpr_r0:
1221  case gpr_r1:
1222  case gpr_r2:
1223  case gpr_r3:
1224  case gpr_r4:
1225  case gpr_r5:
1226  case gpr_r6:
1227  case gpr_r7:
1228  case gpr_r8:
1229  case gpr_r9:
1230  case gpr_r10:
1231  case gpr_r11:
1232  case gpr_r12:
1233  case gpr_sp:
1234  case gpr_lr:
1235  case gpr_pc:
1236  case gpr_cpsr:
1237    gpr.r[reg - gpr_r0] = value.GetAsUInt32();
1238    break;
1239
1240  case fpu_s0:
1241  case fpu_s1:
1242  case fpu_s2:
1243  case fpu_s3:
1244  case fpu_s4:
1245  case fpu_s5:
1246  case fpu_s6:
1247  case fpu_s7:
1248  case fpu_s8:
1249  case fpu_s9:
1250  case fpu_s10:
1251  case fpu_s11:
1252  case fpu_s12:
1253  case fpu_s13:
1254  case fpu_s14:
1255  case fpu_s15:
1256  case fpu_s16:
1257  case fpu_s17:
1258  case fpu_s18:
1259  case fpu_s19:
1260  case fpu_s20:
1261  case fpu_s21:
1262  case fpu_s22:
1263  case fpu_s23:
1264  case fpu_s24:
1265  case fpu_s25:
1266  case fpu_s26:
1267  case fpu_s27:
1268  case fpu_s28:
1269  case fpu_s29:
1270  case fpu_s30:
1271  case fpu_s31:
1272    fpu.floats.s[reg] = value.GetAsUInt32();
1273    break;
1274
1275  case fpu_fpscr:
1276    fpu.fpscr = value.GetAsUInt32();
1277    break;
1278
1279  case exc_exception:
1280    exc.exception = value.GetAsUInt32();
1281    break;
1282  case exc_fsr:
1283    exc.fsr = value.GetAsUInt32();
1284    break;
1285  case exc_far:
1286    exc.far = value.GetAsUInt32();
1287    break;
1288
1289  default:
1290    return false;
1291  }
1292  return WriteRegisterSet(set) == KERN_SUCCESS;
1293}
1294
1295bool RegisterContextDarwin_arm::ReadAllRegisterValues(
1296    lldb::DataBufferSP &data_sp) {
1297  data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);
1298  if (data_sp && ReadGPR(false) == KERN_SUCCESS &&
1299      ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {
1300    uint8_t *dst = data_sp->GetBytes();
1301    ::memcpy(dst, &gpr, sizeof(gpr));
1302    dst += sizeof(gpr);
1303
1304    ::memcpy(dst, &fpu, sizeof(fpu));
1305    dst += sizeof(gpr);
1306
1307    ::memcpy(dst, &exc, sizeof(exc));
1308    return true;
1309  }
1310  return false;
1311}
1312
1313bool RegisterContextDarwin_arm::WriteAllRegisterValues(
1314    const lldb::DataBufferSP &data_sp) {
1315  if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
1316    const uint8_t *src = data_sp->GetBytes();
1317    ::memcpy(&gpr, src, sizeof(gpr));
1318    src += sizeof(gpr);
1319
1320    ::memcpy(&fpu, src, sizeof(fpu));
1321    src += sizeof(gpr);
1322
1323    ::memcpy(&exc, src, sizeof(exc));
1324    uint32_t success_count = 0;
1325    if (WriteGPR() == KERN_SUCCESS)
1326      ++success_count;
1327    if (WriteFPU() == KERN_SUCCESS)
1328      ++success_count;
1329    if (WriteEXC() == KERN_SUCCESS)
1330      ++success_count;
1331    return success_count == 3;
1332  }
1333  return false;
1334}
1335
1336uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(
1337    lldb::RegisterKind kind, uint32_t reg) {
1338  if (kind == eRegisterKindGeneric) {
1339    switch (reg) {
1340    case LLDB_REGNUM_GENERIC_PC:
1341      return gpr_pc;
1342    case LLDB_REGNUM_GENERIC_SP:
1343      return gpr_sp;
1344    case LLDB_REGNUM_GENERIC_FP:
1345      return gpr_r7;
1346    case LLDB_REGNUM_GENERIC_RA:
1347      return gpr_lr;
1348    case LLDB_REGNUM_GENERIC_FLAGS:
1349      return gpr_cpsr;
1350    default:
1351      break;
1352    }
1353  } else if (kind == eRegisterKindDWARF) {
1354    switch (reg) {
1355    case dwarf_r0:
1356      return gpr_r0;
1357    case dwarf_r1:
1358      return gpr_r1;
1359    case dwarf_r2:
1360      return gpr_r2;
1361    case dwarf_r3:
1362      return gpr_r3;
1363    case dwarf_r4:
1364      return gpr_r4;
1365    case dwarf_r5:
1366      return gpr_r5;
1367    case dwarf_r6:
1368      return gpr_r6;
1369    case dwarf_r7:
1370      return gpr_r7;
1371    case dwarf_r8:
1372      return gpr_r8;
1373    case dwarf_r9:
1374      return gpr_r9;
1375    case dwarf_r10:
1376      return gpr_r10;
1377    case dwarf_r11:
1378      return gpr_r11;
1379    case dwarf_r12:
1380      return gpr_r12;
1381    case dwarf_sp:
1382      return gpr_sp;
1383    case dwarf_lr:
1384      return gpr_lr;
1385    case dwarf_pc:
1386      return gpr_pc;
1387    case dwarf_spsr:
1388      return gpr_cpsr;
1389
1390    case dwarf_s0:
1391      return fpu_s0;
1392    case dwarf_s1:
1393      return fpu_s1;
1394    case dwarf_s2:
1395      return fpu_s2;
1396    case dwarf_s3:
1397      return fpu_s3;
1398    case dwarf_s4:
1399      return fpu_s4;
1400    case dwarf_s5:
1401      return fpu_s5;
1402    case dwarf_s6:
1403      return fpu_s6;
1404    case dwarf_s7:
1405      return fpu_s7;
1406    case dwarf_s8:
1407      return fpu_s8;
1408    case dwarf_s9:
1409      return fpu_s9;
1410    case dwarf_s10:
1411      return fpu_s10;
1412    case dwarf_s11:
1413      return fpu_s11;
1414    case dwarf_s12:
1415      return fpu_s12;
1416    case dwarf_s13:
1417      return fpu_s13;
1418    case dwarf_s14:
1419      return fpu_s14;
1420    case dwarf_s15:
1421      return fpu_s15;
1422    case dwarf_s16:
1423      return fpu_s16;
1424    case dwarf_s17:
1425      return fpu_s17;
1426    case dwarf_s18:
1427      return fpu_s18;
1428    case dwarf_s19:
1429      return fpu_s19;
1430    case dwarf_s20:
1431      return fpu_s20;
1432    case dwarf_s21:
1433      return fpu_s21;
1434    case dwarf_s22:
1435      return fpu_s22;
1436    case dwarf_s23:
1437      return fpu_s23;
1438    case dwarf_s24:
1439      return fpu_s24;
1440    case dwarf_s25:
1441      return fpu_s25;
1442    case dwarf_s26:
1443      return fpu_s26;
1444    case dwarf_s27:
1445      return fpu_s27;
1446    case dwarf_s28:
1447      return fpu_s28;
1448    case dwarf_s29:
1449      return fpu_s29;
1450    case dwarf_s30:
1451      return fpu_s30;
1452    case dwarf_s31:
1453      return fpu_s31;
1454
1455    default:
1456      break;
1457    }
1458  } else if (kind == eRegisterKindEHFrame) {
1459    switch (reg) {
1460    case ehframe_r0:
1461      return gpr_r0;
1462    case ehframe_r1:
1463      return gpr_r1;
1464    case ehframe_r2:
1465      return gpr_r2;
1466    case ehframe_r3:
1467      return gpr_r3;
1468    case ehframe_r4:
1469      return gpr_r4;
1470    case ehframe_r5:
1471      return gpr_r5;
1472    case ehframe_r6:
1473      return gpr_r6;
1474    case ehframe_r7:
1475      return gpr_r7;
1476    case ehframe_r8:
1477      return gpr_r8;
1478    case ehframe_r9:
1479      return gpr_r9;
1480    case ehframe_r10:
1481      return gpr_r10;
1482    case ehframe_r11:
1483      return gpr_r11;
1484    case ehframe_r12:
1485      return gpr_r12;
1486    case ehframe_sp:
1487      return gpr_sp;
1488    case ehframe_lr:
1489      return gpr_lr;
1490    case ehframe_pc:
1491      return gpr_pc;
1492    case ehframe_cpsr:
1493      return gpr_cpsr;
1494    }
1495  } else if (kind == eRegisterKindLLDB) {
1496    return reg;
1497  }
1498  return LLDB_INVALID_REGNUM;
1499}
1500
1501uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
1502#if defined(__APPLE__) && defined(__arm__)
1503  // Set the init value to something that will let us know that we need to
1504  // autodetect how many breakpoints are supported dynamically...
1505  static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
1506  if (g_num_supported_hw_breakpoints == UINT32_MAX) {
1507    // Set this to zero in case we can't tell if there are any HW breakpoints
1508    g_num_supported_hw_breakpoints = 0;
1509
1510    uint32_t register_DBGDIDR;
1511
1512    asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1513    g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24);
1514    // Zero is reserved for the BRP count, so don't increment it if it is zero
1515    if (g_num_supported_hw_breakpoints > 0)
1516      g_num_supported_hw_breakpoints++;
1517    //        if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)",
1518    //        register_DBGDIDR, g_num_supported_hw_breakpoints);
1519  }
1520  return g_num_supported_hw_breakpoints;
1521#else
1522  // TODO: figure out remote case here!
1523  return 6;
1524#endif
1525}
1526
1527uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr,
1528                                                          size_t size) {
1529  // Make sure our address isn't bogus
1530  if (addr & 1)
1531    return LLDB_INVALID_INDEX32;
1532
1533  int kret = ReadDBG(false);
1534
1535  if (kret == KERN_SUCCESS) {
1536    const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
1537    uint32_t i;
1538    for (i = 0; i < num_hw_breakpoints; ++i) {
1539      if ((dbg.bcr[i] & BCR_ENABLE) == 0)
1540        break; // We found an available hw breakpoint slot (in i)
1541    }
1542
1543    // See if we found an available hw breakpoint slot above
1544    if (i < num_hw_breakpoints) {
1545      // Make sure bits 1:0 are clear in our address
1546      dbg.bvr[i] = addr & ~((lldb::addr_t)3);
1547
1548      if (size == 2 || addr & 2) {
1549        uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
1550
1551        // We have a thumb breakpoint
1552        // We have an ARM breakpoint
1553        dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address mismatch
1554                     byte_addr_select | // Set the correct byte address select
1555                                        // so we only trigger on the correct
1556                                        // opcode
1557                     S_USER |    // Which modes should this breakpoint stop in?
1558                     BCR_ENABLE; // Enable this hardware breakpoint
1559                                 //                if (log) log->Printf
1560        //                ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1561        //                addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1562        //                0x%8.8x (Thumb)",
1563        //                        addr,
1564        //                        size,
1565        //                        i,
1566        //                        i,
1567        //                        dbg.bvr[i],
1568        //                        dbg.bcr[i]);
1569      } else if (size == 4) {
1570        // We have an ARM breakpoint
1571        dbg.bcr[i] =
1572            BCR_M_IMVA_MATCH | // Stop on address mismatch
1573            BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
1574            S_USER |       // Which modes should this breakpoint stop in?
1575            BCR_ENABLE;    // Enable this hardware breakpoint
1576                           //                if (log) log->Printf
1577        //                ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1578        //                addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1579        //                0x%8.8x (ARM)",
1580        //                        addr,
1581        //                        size,
1582        //                        i,
1583        //                        i,
1584        //                        dbg.bvr[i],
1585        //                        dbg.bcr[i]);
1586      }
1587
1588      kret = WriteDBG();
1589      //            if (log) log->Printf
1590      //            ("RegisterContextDarwin_arm::EnableHardwareBreakpoint()
1591      //            WriteDBG() => 0x%8.8x.", kret);
1592
1593      if (kret == KERN_SUCCESS)
1594        return i;
1595    }
1596    //        else
1597    //        {
1598    //            if (log) log->Printf
1599    //            ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr =
1600    //            %8.8p, size = %u) => all hardware breakpoint resources are
1601    //            being used.", addr, size);
1602    //        }
1603  }
1604
1605  return LLDB_INVALID_INDEX32;
1606}
1607
1608bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {
1609  int kret = ReadDBG(false);
1610
1611  const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
1612  if (kret == KERN_SUCCESS) {
1613    if (hw_index < num_hw_points) {
1614      dbg.bcr[hw_index] = 0;
1615      //            if (log) log->Printf
1616      //            ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) -
1617      //            BVR%u = 0x%8.8x  BCR%u = 0x%8.8x",
1618      //                    hw_index,
1619      //                    hw_index,
1620      //                    dbg.bvr[hw_index],
1621      //                    hw_index,
1622      //                    dbg.bcr[hw_index]);
1623
1624      kret = WriteDBG();
1625
1626      if (kret == KERN_SUCCESS)
1627        return true;
1628    }
1629  }
1630  return false;
1631}
1632
1633uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
1634#if defined(__APPLE__) && defined(__arm__)
1635  // Set the init value to something that will let us know that we need to
1636  // autodetect how many watchpoints are supported dynamically...
1637  static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
1638  if (g_num_supported_hw_watchpoints == UINT32_MAX) {
1639    // Set this to zero in case we can't tell if there are any HW breakpoints
1640    g_num_supported_hw_watchpoints = 0;
1641
1642    uint32_t register_DBGDIDR;
1643    asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1644    g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;
1645    //        if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)",
1646    //        register_DBGDIDR, g_num_supported_hw_watchpoints);
1647  }
1648  return g_num_supported_hw_watchpoints;
1649#else
1650  // TODO: figure out remote case here!
1651  return 2;
1652#endif
1653}
1654
1655uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
1656                                                          size_t size,
1657                                                          bool read,
1658                                                          bool write) {
1659  //    if (log) log->Printf
1660  //    ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size
1661  //    = %u, read = %u, write = %u)", addr, size, read, write);
1662
1663  const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1664
1665  // Can't watch zero bytes
1666  if (size == 0)
1667    return LLDB_INVALID_INDEX32;
1668
1669  // We must watch for either read or write
1670  if (!read && !write)
1671    return LLDB_INVALID_INDEX32;
1672
1673  // Can't watch more than 4 bytes per WVR/WCR pair
1674  if (size > 4)
1675    return LLDB_INVALID_INDEX32;
1676
1677  // We can only watch up to four bytes that follow a 4 byte aligned address
1678  // per watchpoint register pair. Since we have at most so we can only watch
1679  // until the next 4 byte boundary and we need to make sure we can properly
1680  // encode this.
1681  uint32_t addr_word_offset = addr % 4;
1682  //    if (log) log->Printf
1683  //    ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() -
1684  //    addr_word_offset = 0x%8.8x", addr_word_offset);
1685
1686  uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
1687  //    if (log) log->Printf
1688  //    ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask =
1689  //    0x%8.8x", byte_mask);
1690  if (byte_mask > 0xfu)
1691    return LLDB_INVALID_INDEX32;
1692
1693  // Read the debug state
1694  int kret = ReadDBG(false);
1695
1696  if (kret == KERN_SUCCESS) {
1697    // Check to make sure we have the needed hardware support
1698    uint32_t i = 0;
1699
1700    for (i = 0; i < num_hw_watchpoints; ++i) {
1701      if ((dbg.wcr[i] & WCR_ENABLE) == 0)
1702        break; // We found an available hw breakpoint slot (in i)
1703    }
1704
1705    // See if we found an available hw breakpoint slot above
1706    if (i < num_hw_watchpoints) {
1707      // Make the byte_mask into a valid Byte Address Select mask
1708      uint32_t byte_address_select = byte_mask << 5;
1709      // Make sure bits 1:0 are clear in our address
1710      dbg.wvr[i] = addr & ~((lldb::addr_t)3);
1711      dbg.wcr[i] = byte_address_select |     // Which bytes that follow the IMVA
1712                                             // that we will watch
1713                   S_USER |                  // Stop only in user mode
1714                   (read ? WCR_LOAD : 0) |   // Stop on read access?
1715                   (write ? WCR_STORE : 0) | // Stop on write access?
1716                   WCR_ENABLE;               // Enable this watchpoint;
1717
1718      kret = WriteDBG();
1719      //            if (log) log->Printf
1720      //            ("RegisterContextDarwin_arm::EnableHardwareWatchpoint()
1721      //            WriteDBG() => 0x%8.8x.", kret);
1722
1723      if (kret == KERN_SUCCESS)
1724        return i;
1725    } else {
1726      //            if (log) log->Printf
1727      //            ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All
1728      //            hardware resources (%u) are in use.", num_hw_watchpoints);
1729    }
1730  }
1731  return LLDB_INVALID_INDEX32;
1732}
1733
1734bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {
1735  int kret = ReadDBG(false);
1736
1737  const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
1738  if (kret == KERN_SUCCESS) {
1739    if (hw_index < num_hw_points) {
1740      dbg.wcr[hw_index] = 0;
1741      //            if (log) log->Printf
1742      //            ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) -
1743      //            WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
1744      //                    hw_index,
1745      //                    hw_index,
1746      //                    dbg.wvr[hw_index],
1747      //                    hw_index,
1748      //                    dbg.wcr[hw_index]);
1749
1750      kret = WriteDBG();
1751
1752      if (kret == KERN_SUCCESS)
1753        return true;
1754    }
1755  }
1756  return false;
1757}
1758