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