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