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