RegisterContextDarwin_arm.cpp revision 296417
1//===-- RegisterContextDarwin_arm.cpp ---------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#if defined(__APPLE__)
11
12#include "RegisterContextDarwin_arm.h"
13
14// C Includes
15#include <mach/mach_types.h>
16#include <mach/thread_act.h>
17
18// C++ Includes
19// Other libraries and framework includes
20#include "lldb/Core/DataBufferHeap.h"
21#include "lldb/Core/DataExtractor.h"
22#include "lldb/Core/Log.h"
23#include "lldb/Core/RegisterValue.h"
24#include "lldb/Core/Scalar.h"
25#include "lldb/Host/Endian.h"
26#include "llvm/Support/Compiler.h"
27
28#include "Plugins/Process/Utility/InstructionUtils.h"
29
30// Support building against older versions of LLVM, this macro was added
31// recently.
32#ifndef LLVM_EXTENSION
33#define LLVM_EXTENSION
34#endif
35
36// Project includes
37#include "ARM_DWARF_Registers.h"
38#include "Utility/ARM_ehframe_Registers.h"
39
40#include "llvm/ADT/STLExtras.h"
41
42using namespace lldb;
43using namespace lldb_private;
44
45enum
46{
47    gpr_r0 = 0,
48    gpr_r1,
49    gpr_r2,
50    gpr_r3,
51    gpr_r4,
52    gpr_r5,
53    gpr_r6,
54    gpr_r7,
55    gpr_r8,
56    gpr_r9,
57    gpr_r10,
58    gpr_r11,
59    gpr_r12,
60    gpr_r13, gpr_sp = gpr_r13,
61    gpr_r14, gpr_lr = gpr_r14,
62    gpr_r15, gpr_pc = gpr_r15,
63    gpr_cpsr,
64
65    fpu_s0,
66    fpu_s1,
67    fpu_s2,
68    fpu_s3,
69    fpu_s4,
70    fpu_s5,
71    fpu_s6,
72    fpu_s7,
73    fpu_s8,
74    fpu_s9,
75    fpu_s10,
76    fpu_s11,
77    fpu_s12,
78    fpu_s13,
79    fpu_s14,
80    fpu_s15,
81    fpu_s16,
82    fpu_s17,
83    fpu_s18,
84    fpu_s19,
85    fpu_s20,
86    fpu_s21,
87    fpu_s22,
88    fpu_s23,
89    fpu_s24,
90    fpu_s25,
91    fpu_s26,
92    fpu_s27,
93    fpu_s28,
94    fpu_s29,
95    fpu_s30,
96    fpu_s31,
97    fpu_fpscr,
98
99    exc_exception,
100    exc_fsr,
101    exc_far,
102
103    dbg_bvr0,
104    dbg_bvr1,
105    dbg_bvr2,
106    dbg_bvr3,
107    dbg_bvr4,
108    dbg_bvr5,
109    dbg_bvr6,
110    dbg_bvr7,
111    dbg_bvr8,
112    dbg_bvr9,
113    dbg_bvr10,
114    dbg_bvr11,
115    dbg_bvr12,
116    dbg_bvr13,
117    dbg_bvr14,
118    dbg_bvr15,
119
120    dbg_bcr0,
121    dbg_bcr1,
122    dbg_bcr2,
123    dbg_bcr3,
124    dbg_bcr4,
125    dbg_bcr5,
126    dbg_bcr6,
127    dbg_bcr7,
128    dbg_bcr8,
129    dbg_bcr9,
130    dbg_bcr10,
131    dbg_bcr11,
132    dbg_bcr12,
133    dbg_bcr13,
134    dbg_bcr14,
135    dbg_bcr15,
136
137    dbg_wvr0,
138    dbg_wvr1,
139    dbg_wvr2,
140    dbg_wvr3,
141    dbg_wvr4,
142    dbg_wvr5,
143    dbg_wvr6,
144    dbg_wvr7,
145    dbg_wvr8,
146    dbg_wvr9,
147    dbg_wvr10,
148    dbg_wvr11,
149    dbg_wvr12,
150    dbg_wvr13,
151    dbg_wvr14,
152    dbg_wvr15,
153
154    dbg_wcr0,
155    dbg_wcr1,
156    dbg_wcr2,
157    dbg_wcr3,
158    dbg_wcr4,
159    dbg_wcr5,
160    dbg_wcr6,
161    dbg_wcr7,
162    dbg_wcr8,
163    dbg_wcr9,
164    dbg_wcr10,
165    dbg_wcr11,
166    dbg_wcr12,
167    dbg_wcr13,
168    dbg_wcr14,
169    dbg_wcr15,
170
171    k_num_registers
172};
173
174
175#define GPR_OFFSET(idx) ((idx) * 4)
176#define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR))
177#define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU))
178#define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextDarwin_arm::DBG, reg) + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC)))
179
180#define DEFINE_DBG(reg, i)  #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL
181#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC))
182
183static RegisterInfo g_register_infos[] = {
184// General purpose registers
185//  NAME        ALT     SZ  OFFSET              ENCODING        FORMAT          EH_FRAME                DWARF               GENERIC                     PROCESS PLUGIN          LLDB NATIVE   VALUE REGS    INVALIDATE REGS
186//  ======      ======= ==  =============       =============   ============    ===============         ===============     =========================   =====================   ============= ==========    ===============
187{   "r0",       NULL,   4,  GPR_OFFSET(0),      eEncodingUint,  eFormatHex,     { ehframe_r0,               dwarf_r0,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r0      },      NULL,              NULL},
188{   "r1",       NULL,   4,  GPR_OFFSET(1),      eEncodingUint,  eFormatHex,     { ehframe_r1,               dwarf_r1,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r1      },      NULL,              NULL},
189{   "r2",       NULL,   4,  GPR_OFFSET(2),      eEncodingUint,  eFormatHex,     { ehframe_r2,               dwarf_r2,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r2      },      NULL,              NULL},
190{   "r3",       NULL,   4,  GPR_OFFSET(3),      eEncodingUint,  eFormatHex,     { ehframe_r3,               dwarf_r3,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r3      },      NULL,              NULL},
191{   "r4",       NULL,   4,  GPR_OFFSET(4),      eEncodingUint,  eFormatHex,     { ehframe_r4,               dwarf_r4,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r4      },      NULL,              NULL},
192{   "r5",       NULL,   4,  GPR_OFFSET(5),      eEncodingUint,  eFormatHex,     { ehframe_r5,               dwarf_r5,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r5      },      NULL,              NULL},
193{   "r6",       NULL,   4,  GPR_OFFSET(6),      eEncodingUint,  eFormatHex,     { ehframe_r6,               dwarf_r6,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r6      },      NULL,              NULL},
194{   "r7",       NULL,   4,  GPR_OFFSET(7),      eEncodingUint,  eFormatHex,     { ehframe_r7,               dwarf_r7,           LLDB_REGNUM_GENERIC_FP,     LLDB_INVALID_REGNUM,    gpr_r7      },      NULL,              NULL},
195{   "r8",       NULL,   4,  GPR_OFFSET(8),      eEncodingUint,  eFormatHex,     { ehframe_r8,               dwarf_r8,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r8      },      NULL,              NULL},
196{   "r9",       NULL,   4,  GPR_OFFSET(9),      eEncodingUint,  eFormatHex,     { ehframe_r9,               dwarf_r9,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r9      },      NULL,              NULL},
197{   "r10",      NULL,   4,  GPR_OFFSET(10),     eEncodingUint,  eFormatHex,     { ehframe_r10,              dwarf_r10,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r10     },      NULL,              NULL},
198{   "r11",      NULL,   4,  GPR_OFFSET(11),     eEncodingUint,  eFormatHex,     { ehframe_r11,              dwarf_r11,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r11     },      NULL,              NULL},
199{   "r12",      NULL,   4,  GPR_OFFSET(12),     eEncodingUint,  eFormatHex,     { ehframe_r12,              dwarf_r12,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    gpr_r12     },      NULL,              NULL},
200{   "sp",       "r13",  4,  GPR_OFFSET(13),     eEncodingUint,  eFormatHex,     { ehframe_sp,               dwarf_sp,           LLDB_REGNUM_GENERIC_SP,     LLDB_INVALID_REGNUM,    gpr_sp      },      NULL,              NULL},
201{   "lr",       "r14",  4,  GPR_OFFSET(14),     eEncodingUint,  eFormatHex,     { ehframe_lr,               dwarf_lr,           LLDB_REGNUM_GENERIC_RA,     LLDB_INVALID_REGNUM,    gpr_lr      },      NULL,              NULL},
202{   "pc",       "r15",  4,  GPR_OFFSET(15),     eEncodingUint,  eFormatHex,     { ehframe_pc,               dwarf_pc,           LLDB_REGNUM_GENERIC_PC,     LLDB_INVALID_REGNUM,    gpr_pc      },      NULL,              NULL},
203{   "cpsr",     "psr",  4,  GPR_OFFSET(16),     eEncodingUint,  eFormatHex,     { ehframe_cpsr,             dwarf_cpsr,         LLDB_REGNUM_GENERIC_FLAGS,  LLDB_INVALID_REGNUM,    gpr_cpsr    },      NULL,              NULL},
204
205{   "s0",       NULL,   4,  FPU_OFFSET(0),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s0,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s0      },      NULL,              NULL},
206{   "s1",       NULL,   4,  FPU_OFFSET(1),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s1,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s1      },      NULL,              NULL},
207{   "s2",       NULL,   4,  FPU_OFFSET(2),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s2,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s2      },      NULL,              NULL},
208{   "s3",       NULL,   4,  FPU_OFFSET(3),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s3,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s3      },      NULL,              NULL},
209{   "s4",       NULL,   4,  FPU_OFFSET(4),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s4,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s4      },      NULL,              NULL},
210{   "s5",       NULL,   4,  FPU_OFFSET(5),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s5,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s5      },      NULL,              NULL},
211{   "s6",       NULL,   4,  FPU_OFFSET(6),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s6,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s6      },      NULL,              NULL},
212{   "s7",       NULL,   4,  FPU_OFFSET(7),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s7,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s7      },      NULL,              NULL},
213{   "s8",       NULL,   4,  FPU_OFFSET(8),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s8,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s8      },      NULL,              NULL},
214{   "s9",       NULL,   4,  FPU_OFFSET(9),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s9,           LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s9      },      NULL,              NULL},
215{   "s10",      NULL,   4,  FPU_OFFSET(10),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s10,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s10     },      NULL,              NULL},
216{   "s11",      NULL,   4,  FPU_OFFSET(11),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s11,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s11     },      NULL,              NULL},
217{   "s12",      NULL,   4,  FPU_OFFSET(12),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s12,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s12     },      NULL,              NULL},
218{   "s13",      NULL,   4,  FPU_OFFSET(13),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s13,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s13     },      NULL,              NULL},
219{   "s14",      NULL,   4,  FPU_OFFSET(14),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s14,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s14     },      NULL,              NULL},
220{   "s15",      NULL,   4,  FPU_OFFSET(15),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s15,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s15     },      NULL,              NULL},
221{   "s16",      NULL,   4,  FPU_OFFSET(16),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s16,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s16     },      NULL,              NULL},
222{   "s17",      NULL,   4,  FPU_OFFSET(17),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s17,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s17     },      NULL,              NULL},
223{   "s18",      NULL,   4,  FPU_OFFSET(18),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s18,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s18     },      NULL,              NULL},
224{   "s19",      NULL,   4,  FPU_OFFSET(19),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s19,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s19     },      NULL,              NULL},
225{   "s20",      NULL,   4,  FPU_OFFSET(20),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s20,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s20     },      NULL,              NULL},
226{   "s21",      NULL,   4,  FPU_OFFSET(21),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s21,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s21     },      NULL,              NULL},
227{   "s22",      NULL,   4,  FPU_OFFSET(22),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s22,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s22     },      NULL,              NULL},
228{   "s23",      NULL,   4,  FPU_OFFSET(23),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s23,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s23     },      NULL,              NULL},
229{   "s24",      NULL,   4,  FPU_OFFSET(24),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s24,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s24     },      NULL,              NULL},
230{   "s25",      NULL,   4,  FPU_OFFSET(25),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s25,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s25     },      NULL,              NULL},
231{   "s26",      NULL,   4,  FPU_OFFSET(26),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s26,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s26     },      NULL,              NULL},
232{   "s27",      NULL,   4,  FPU_OFFSET(27),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s27,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s27     },      NULL,              NULL},
233{   "s28",      NULL,   4,  FPU_OFFSET(28),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s28,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s28     },      NULL,              NULL},
234{   "s29",      NULL,   4,  FPU_OFFSET(29),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s29,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s29     },      NULL,              NULL},
235{   "s30",      NULL,   4,  FPU_OFFSET(30),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s30,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s30     },      NULL,              NULL},
236{   "s31",      NULL,   4,  FPU_OFFSET(31),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s31,          LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_s31     },      NULL,              NULL},
237{   "fpscr",    NULL,   4,  FPU_OFFSET(32),     eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    fpu_fpscr   },      NULL,              NULL},
238
239{   "exception",NULL,   4,  EXC_OFFSET(0),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_exception },    NULL,              NULL},
240{   "fsr",      NULL,   4,  EXC_OFFSET(1),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_fsr       },    NULL,              NULL},
241{   "far",      NULL,   4,  EXC_OFFSET(2),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_far       },    NULL,              NULL},
242
243{   DEFINE_DBG (bvr, 0) },
244{   DEFINE_DBG (bvr, 1) },
245{   DEFINE_DBG (bvr, 2) },
246{   DEFINE_DBG (bvr, 3) },
247{   DEFINE_DBG (bvr, 4) },
248{   DEFINE_DBG (bvr, 5) },
249{   DEFINE_DBG (bvr, 6) },
250{   DEFINE_DBG (bvr, 7) },
251{   DEFINE_DBG (bvr, 8) },
252{   DEFINE_DBG (bvr, 9) },
253{   DEFINE_DBG (bvr, 10) },
254{   DEFINE_DBG (bvr, 11) },
255{   DEFINE_DBG (bvr, 12) },
256{   DEFINE_DBG (bvr, 13) },
257{   DEFINE_DBG (bvr, 14) },
258{   DEFINE_DBG (bvr, 15) },
259
260{   DEFINE_DBG (bcr, 0) },
261{   DEFINE_DBG (bcr, 1) },
262{   DEFINE_DBG (bcr, 2) },
263{   DEFINE_DBG (bcr, 3) },
264{   DEFINE_DBG (bcr, 4) },
265{   DEFINE_DBG (bcr, 5) },
266{   DEFINE_DBG (bcr, 6) },
267{   DEFINE_DBG (bcr, 7) },
268{   DEFINE_DBG (bcr, 8) },
269{   DEFINE_DBG (bcr, 9) },
270{   DEFINE_DBG (bcr, 10) },
271{   DEFINE_DBG (bcr, 11) },
272{   DEFINE_DBG (bcr, 12) },
273{   DEFINE_DBG (bcr, 13) },
274{   DEFINE_DBG (bcr, 14) },
275{   DEFINE_DBG (bcr, 15) },
276
277{   DEFINE_DBG (wvr, 0) },
278{   DEFINE_DBG (wvr, 1) },
279{   DEFINE_DBG (wvr, 2) },
280{   DEFINE_DBG (wvr, 3) },
281{   DEFINE_DBG (wvr, 4) },
282{   DEFINE_DBG (wvr, 5) },
283{   DEFINE_DBG (wvr, 6) },
284{   DEFINE_DBG (wvr, 7) },
285{   DEFINE_DBG (wvr, 8) },
286{   DEFINE_DBG (wvr, 9) },
287{   DEFINE_DBG (wvr, 10) },
288{   DEFINE_DBG (wvr, 11) },
289{   DEFINE_DBG (wvr, 12) },
290{   DEFINE_DBG (wvr, 13) },
291{   DEFINE_DBG (wvr, 14) },
292{   DEFINE_DBG (wvr, 15) },
293
294{   DEFINE_DBG (wcr, 0) },
295{   DEFINE_DBG (wcr, 1) },
296{   DEFINE_DBG (wcr, 2) },
297{   DEFINE_DBG (wcr, 3) },
298{   DEFINE_DBG (wcr, 4) },
299{   DEFINE_DBG (wcr, 5) },
300{   DEFINE_DBG (wcr, 6) },
301{   DEFINE_DBG (wcr, 7) },
302{   DEFINE_DBG (wcr, 8) },
303{   DEFINE_DBG (wcr, 9) },
304{   DEFINE_DBG (wcr, 10) },
305{   DEFINE_DBG (wcr, 11) },
306{   DEFINE_DBG (wcr, 12) },
307{   DEFINE_DBG (wcr, 13) },
308{   DEFINE_DBG (wcr, 14) },
309{   DEFINE_DBG (wcr, 15) }
310};
311
312// General purpose registers
313static uint32_t
314g_gpr_regnums[] =
315{
316    gpr_r0,
317    gpr_r1,
318    gpr_r2,
319    gpr_r3,
320    gpr_r4,
321    gpr_r5,
322    gpr_r6,
323    gpr_r7,
324    gpr_r8,
325    gpr_r9,
326    gpr_r10,
327    gpr_r11,
328    gpr_r12,
329    gpr_sp,
330    gpr_lr,
331    gpr_pc,
332    gpr_cpsr
333};
334
335// Floating point registers
336static uint32_t
337g_fpu_regnums[] =
338{
339    fpu_s0,
340    fpu_s1,
341    fpu_s2,
342    fpu_s3,
343    fpu_s4,
344    fpu_s5,
345    fpu_s6,
346    fpu_s7,
347    fpu_s8,
348    fpu_s9,
349    fpu_s10,
350    fpu_s11,
351    fpu_s12,
352    fpu_s13,
353    fpu_s14,
354    fpu_s15,
355    fpu_s16,
356    fpu_s17,
357    fpu_s18,
358    fpu_s19,
359    fpu_s20,
360    fpu_s21,
361    fpu_s22,
362    fpu_s23,
363    fpu_s24,
364    fpu_s25,
365    fpu_s26,
366    fpu_s27,
367    fpu_s28,
368    fpu_s29,
369    fpu_s30,
370    fpu_s31,
371    fpu_fpscr,
372};
373
374// Exception registers
375
376static uint32_t
377g_exc_regnums[] =
378{
379    exc_exception,
380    exc_fsr,
381    exc_far,
382};
383
384static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
385
386RegisterContextDarwin_arm::RegisterContextDarwin_arm(Thread &thread, uint32_t concrete_frame_idx) :
387    RegisterContext(thread, concrete_frame_idx),
388    gpr(),
389    fpu(),
390    exc()
391{
392    uint32_t i;
393    for (i=0; i<kNumErrors; i++)
394    {
395        gpr_errs[i] = -1;
396        fpu_errs[i] = -1;
397        exc_errs[i] = -1;
398    }
399}
400
401RegisterContextDarwin_arm::~RegisterContextDarwin_arm()
402{
403}
404
405
406void
407RegisterContextDarwin_arm::InvalidateAllRegisters ()
408{
409    InvalidateAllRegisterStates();
410}
411
412
413size_t
414RegisterContextDarwin_arm::GetRegisterCount ()
415{
416    assert(k_num_register_infos == k_num_registers);
417    return k_num_registers;
418}
419
420const RegisterInfo *
421RegisterContextDarwin_arm::GetRegisterInfoAtIndex (size_t reg)
422{
423    assert(k_num_register_infos == k_num_registers);
424    if (reg < k_num_registers)
425        return &g_register_infos[reg];
426    return NULL;
427}
428
429size_t
430RegisterContextDarwin_arm::GetRegisterInfosCount ()
431{
432    return k_num_register_infos;
433}
434
435const RegisterInfo *
436RegisterContextDarwin_arm::GetRegisterInfos ()
437{
438    return g_register_infos;
439}
440
441
442// Number of registers in each register set
443const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
444const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
445const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
446
447//----------------------------------------------------------------------
448// Register set definitions. The first definitions at register set index
449// of zero is for all registers, followed by other registers sets. The
450// register information for the all register set need not be filled in.
451//----------------------------------------------------------------------
452static const RegisterSet g_reg_sets[] =
453{
454    { "General Purpose Registers",  "gpr",  k_num_gpr_registers,    g_gpr_regnums,      },
455    { "Floating Point Registers",   "fpu",  k_num_fpu_registers,    g_fpu_regnums       },
456    { "Exception State Registers",  "exc",  k_num_exc_registers,    g_exc_regnums       }
457};
458
459const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
460
461
462size_t
463RegisterContextDarwin_arm::GetRegisterSetCount ()
464{
465    return k_num_regsets;
466}
467
468const RegisterSet *
469RegisterContextDarwin_arm::GetRegisterSet (size_t reg_set)
470{
471    if (reg_set < k_num_regsets)
472        return &g_reg_sets[reg_set];
473    return NULL;
474}
475
476
477//----------------------------------------------------------------------
478// Register information definitions for 32 bit i386.
479//----------------------------------------------------------------------
480int
481RegisterContextDarwin_arm::GetSetForNativeRegNum (int reg)
482{
483    if (reg < fpu_s0)
484        return GPRRegSet;
485    else if (reg < exc_exception)
486        return FPURegSet;
487    else if (reg < k_num_registers)
488        return EXCRegSet;
489    return -1;
490}
491
492int
493RegisterContextDarwin_arm::ReadGPR (bool force)
494{
495    int set = GPRRegSet;
496    if (force || !RegisterSetIsCached(set))
497    {
498        SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
499    }
500    return GetError(GPRRegSet, Read);
501}
502
503int
504RegisterContextDarwin_arm::ReadFPU (bool force)
505{
506    int set = FPURegSet;
507    if (force || !RegisterSetIsCached(set))
508    {
509        SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
510    }
511    return GetError(FPURegSet, Read);
512}
513
514int
515RegisterContextDarwin_arm::ReadEXC (bool force)
516{
517    int set = EXCRegSet;
518    if (force || !RegisterSetIsCached(set))
519    {
520        SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
521    }
522    return GetError(EXCRegSet, Read);
523}
524
525int
526RegisterContextDarwin_arm::ReadDBG (bool force)
527{
528    int set = DBGRegSet;
529    if (force || !RegisterSetIsCached(set))
530    {
531        SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
532    }
533    return GetError(DBGRegSet, Read);
534}
535
536int
537RegisterContextDarwin_arm::WriteGPR ()
538{
539    int set = GPRRegSet;
540    if (!RegisterSetIsCached(set))
541    {
542        SetError (set, Write, -1);
543        return KERN_INVALID_ARGUMENT;
544    }
545    SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
546    SetError (set, Read, -1);
547    return GetError(GPRRegSet, Write);
548}
549
550int
551RegisterContextDarwin_arm::WriteFPU ()
552{
553    int set = FPURegSet;
554    if (!RegisterSetIsCached(set))
555    {
556        SetError (set, Write, -1);
557        return KERN_INVALID_ARGUMENT;
558    }
559    SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
560    SetError (set, Read, -1);
561    return GetError(FPURegSet, Write);
562}
563
564int
565RegisterContextDarwin_arm::WriteEXC ()
566{
567    int set = EXCRegSet;
568    if (!RegisterSetIsCached(set))
569    {
570        SetError (set, Write, -1);
571        return KERN_INVALID_ARGUMENT;
572    }
573    SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
574    SetError (set, Read, -1);
575    return GetError(EXCRegSet, Write);
576}
577
578int
579RegisterContextDarwin_arm::WriteDBG ()
580{
581    int set = DBGRegSet;
582    if (!RegisterSetIsCached(set))
583    {
584        SetError (set, Write, -1);
585        return KERN_INVALID_ARGUMENT;
586    }
587    SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
588    SetError (set, Read, -1);
589    return GetError(DBGRegSet, Write);
590}
591
592
593int
594RegisterContextDarwin_arm::ReadRegisterSet (uint32_t set, bool force)
595{
596    switch (set)
597    {
598    case GPRRegSet:    return ReadGPR(force);
599    case FPURegSet:    return ReadFPU(force);
600    case EXCRegSet:    return ReadEXC(force);
601    case DBGRegSet:    return ReadDBG(force);
602    default: break;
603    }
604    return KERN_INVALID_ARGUMENT;
605}
606
607int
608RegisterContextDarwin_arm::WriteRegisterSet (uint32_t set)
609{
610    // Make sure we have a valid context to set.
611    if (RegisterSetIsCached(set))
612    {
613        switch (set)
614        {
615        case GPRRegSet:    return WriteGPR();
616        case FPURegSet:    return WriteFPU();
617        case EXCRegSet:    return WriteEXC();
618        case DBGRegSet:    return WriteDBG();
619        default: break;
620        }
621    }
622    return KERN_INVALID_ARGUMENT;
623}
624
625void
626RegisterContextDarwin_arm::LogDBGRegisters (Log *log, const DBG& dbg)
627{
628    if (log)
629    {
630        for (uint32_t i=0; i<16; i++)
631            log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }",
632                i, i, dbg.bvr[i], dbg.bcr[i],
633                i, i, dbg.wvr[i], dbg.wcr[i]);
634    }
635}
636
637
638bool
639RegisterContextDarwin_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
640{
641    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
642    int set = RegisterContextDarwin_arm::GetSetForNativeRegNum (reg);
643
644    if (set == -1)
645        return false;
646
647    if (ReadRegisterSet(set, false) != KERN_SUCCESS)
648        return false;
649
650    switch (reg)
651    {
652    case gpr_r0:
653    case gpr_r1:
654    case gpr_r2:
655    case gpr_r3:
656    case gpr_r4:
657    case gpr_r5:
658    case gpr_r6:
659    case gpr_r7:
660    case gpr_r8:
661    case gpr_r9:
662    case gpr_r10:
663    case gpr_r11:
664    case gpr_r12:
665    case gpr_sp:
666    case gpr_lr:
667    case gpr_pc:
668    case gpr_cpsr:
669        value.SetUInt32 (gpr.r[reg - gpr_r0]);
670        break;
671
672    case fpu_s0:
673    case fpu_s1:
674    case fpu_s2:
675    case fpu_s3:
676    case fpu_s4:
677    case fpu_s5:
678    case fpu_s6:
679    case fpu_s7:
680    case fpu_s8:
681    case fpu_s9:
682    case fpu_s10:
683    case fpu_s11:
684    case fpu_s12:
685    case fpu_s13:
686    case fpu_s14:
687    case fpu_s15:
688    case fpu_s16:
689    case fpu_s17:
690    case fpu_s18:
691    case fpu_s19:
692    case fpu_s20:
693    case fpu_s21:
694    case fpu_s22:
695    case fpu_s23:
696    case fpu_s24:
697    case fpu_s25:
698    case fpu_s26:
699    case fpu_s27:
700    case fpu_s28:
701    case fpu_s29:
702    case fpu_s30:
703    case fpu_s31:
704        value.SetUInt32 (fpu.floats.s[reg], RegisterValue::eTypeFloat);
705        break;
706
707    case fpu_fpscr:
708        value.SetUInt32 (fpu.fpscr);
709        break;
710
711    case exc_exception:
712        value.SetUInt32 (exc.exception);
713        break;
714    case exc_fsr:
715        value.SetUInt32 (exc.fsr);
716        break;
717    case exc_far:
718        value.SetUInt32 (exc.far);
719        break;
720
721    default:
722        value.SetValueToInvalid();
723        return false;
724
725    }
726    return true;
727}
728
729
730bool
731RegisterContextDarwin_arm::WriteRegister (const RegisterInfo *reg_info,
732                                        const RegisterValue &value)
733{
734    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
735    int set = GetSetForNativeRegNum (reg);
736
737    if (set == -1)
738        return false;
739
740    if (ReadRegisterSet(set, false) != KERN_SUCCESS)
741        return false;
742
743    switch (reg)
744    {
745    case gpr_r0:
746    case gpr_r1:
747    case gpr_r2:
748    case gpr_r3:
749    case gpr_r4:
750    case gpr_r5:
751    case gpr_r6:
752    case gpr_r7:
753    case gpr_r8:
754    case gpr_r9:
755    case gpr_r10:
756    case gpr_r11:
757    case gpr_r12:
758    case gpr_sp:
759    case gpr_lr:
760    case gpr_pc:
761    case gpr_cpsr:
762            gpr.r[reg - gpr_r0] = value.GetAsUInt32();
763        break;
764
765    case fpu_s0:
766    case fpu_s1:
767    case fpu_s2:
768    case fpu_s3:
769    case fpu_s4:
770    case fpu_s5:
771    case fpu_s6:
772    case fpu_s7:
773    case fpu_s8:
774    case fpu_s9:
775    case fpu_s10:
776    case fpu_s11:
777    case fpu_s12:
778    case fpu_s13:
779    case fpu_s14:
780    case fpu_s15:
781    case fpu_s16:
782    case fpu_s17:
783    case fpu_s18:
784    case fpu_s19:
785    case fpu_s20:
786    case fpu_s21:
787    case fpu_s22:
788    case fpu_s23:
789    case fpu_s24:
790    case fpu_s25:
791    case fpu_s26:
792    case fpu_s27:
793    case fpu_s28:
794    case fpu_s29:
795    case fpu_s30:
796    case fpu_s31:
797        fpu.floats.s[reg] = value.GetAsUInt32();
798        break;
799
800    case fpu_fpscr:
801        fpu.fpscr = value.GetAsUInt32();
802        break;
803
804    case exc_exception:
805        exc.exception = value.GetAsUInt32();
806        break;
807    case exc_fsr:
808        exc.fsr = value.GetAsUInt32();
809        break;
810    case exc_far:
811        exc.far = value.GetAsUInt32();
812        break;
813
814    default:
815        return false;
816
817    }
818    return WriteRegisterSet(set) == KERN_SUCCESS;
819}
820
821bool
822RegisterContextDarwin_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
823{
824    data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
825    if (data_sp &&
826        ReadGPR (false) == KERN_SUCCESS &&
827        ReadFPU (false) == KERN_SUCCESS &&
828        ReadEXC (false) == KERN_SUCCESS)
829    {
830        uint8_t *dst = data_sp->GetBytes();
831        ::memcpy (dst, &gpr, sizeof(gpr));
832        dst += sizeof(gpr);
833
834        ::memcpy (dst, &fpu, sizeof(fpu));
835        dst += sizeof(gpr);
836
837        ::memcpy (dst, &exc, sizeof(exc));
838        return true;
839    }
840    return false;
841}
842
843bool
844RegisterContextDarwin_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
845{
846    if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
847    {
848        const uint8_t *src = data_sp->GetBytes();
849        ::memcpy (&gpr, src, sizeof(gpr));
850        src += sizeof(gpr);
851
852        ::memcpy (&fpu, src, sizeof(fpu));
853        src += sizeof(gpr);
854
855        ::memcpy (&exc, src, sizeof(exc));
856        uint32_t success_count = 0;
857        if (WriteGPR() == KERN_SUCCESS)
858            ++success_count;
859        if (WriteFPU() == KERN_SUCCESS)
860            ++success_count;
861        if (WriteEXC() == KERN_SUCCESS)
862            ++success_count;
863        return success_count == 3;
864    }
865    return false;
866}
867
868uint32_t
869RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t reg)
870{
871    if (kind == eRegisterKindGeneric)
872    {
873        switch (reg)
874        {
875        case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
876        case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
877        case LLDB_REGNUM_GENERIC_FP: return gpr_r7;
878        case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
879        case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
880        default:
881            break;
882        }
883    }
884    else if (kind == eRegisterKindDWARF)
885    {
886        switch (reg)
887        {
888        case dwarf_r0:  return gpr_r0;
889        case dwarf_r1:  return gpr_r1;
890        case dwarf_r2:  return gpr_r2;
891        case dwarf_r3:  return gpr_r3;
892        case dwarf_r4:  return gpr_r4;
893        case dwarf_r5:  return gpr_r5;
894        case dwarf_r6:  return gpr_r6;
895        case dwarf_r7:  return gpr_r7;
896        case dwarf_r8:  return gpr_r8;
897        case dwarf_r9:  return gpr_r9;
898        case dwarf_r10: return gpr_r10;
899        case dwarf_r11: return gpr_r11;
900        case dwarf_r12: return gpr_r12;
901        case dwarf_sp:  return gpr_sp;
902        case dwarf_lr:  return gpr_lr;
903        case dwarf_pc:  return gpr_pc;
904        case dwarf_spsr: return gpr_cpsr;
905
906        case dwarf_s0:  return fpu_s0;
907        case dwarf_s1:  return fpu_s1;
908        case dwarf_s2:  return fpu_s2;
909        case dwarf_s3:  return fpu_s3;
910        case dwarf_s4:  return fpu_s4;
911        case dwarf_s5:  return fpu_s5;
912        case dwarf_s6:  return fpu_s6;
913        case dwarf_s7:  return fpu_s7;
914        case dwarf_s8:  return fpu_s8;
915        case dwarf_s9:  return fpu_s9;
916        case dwarf_s10: return fpu_s10;
917        case dwarf_s11: return fpu_s11;
918        case dwarf_s12: return fpu_s12;
919        case dwarf_s13: return fpu_s13;
920        case dwarf_s14: return fpu_s14;
921        case dwarf_s15: return fpu_s15;
922        case dwarf_s16: return fpu_s16;
923        case dwarf_s17: return fpu_s17;
924        case dwarf_s18: return fpu_s18;
925        case dwarf_s19: return fpu_s19;
926        case dwarf_s20: return fpu_s20;
927        case dwarf_s21: return fpu_s21;
928        case dwarf_s22: return fpu_s22;
929        case dwarf_s23: return fpu_s23;
930        case dwarf_s24: return fpu_s24;
931        case dwarf_s25: return fpu_s25;
932        case dwarf_s26: return fpu_s26;
933        case dwarf_s27: return fpu_s27;
934        case dwarf_s28: return fpu_s28;
935        case dwarf_s29: return fpu_s29;
936        case dwarf_s30: return fpu_s30;
937        case dwarf_s31: return fpu_s31;
938
939        default:
940            break;
941        }
942    }
943    else if (kind == eRegisterKindEHFrame)
944    {
945        switch (reg)
946        {
947        case ehframe_r0:    return gpr_r0;
948        case ehframe_r1:    return gpr_r1;
949        case ehframe_r2:    return gpr_r2;
950        case ehframe_r3:    return gpr_r3;
951        case ehframe_r4:    return gpr_r4;
952        case ehframe_r5:    return gpr_r5;
953        case ehframe_r6:    return gpr_r6;
954        case ehframe_r7:    return gpr_r7;
955        case ehframe_r8:    return gpr_r8;
956        case ehframe_r9:    return gpr_r9;
957        case ehframe_r10:   return gpr_r10;
958        case ehframe_r11:   return gpr_r11;
959        case ehframe_r12:   return gpr_r12;
960        case ehframe_sp:    return gpr_sp;
961        case ehframe_lr:    return gpr_lr;
962        case ehframe_pc:    return gpr_pc;
963        case ehframe_cpsr:  return gpr_cpsr;
964        }
965    }
966    else if (kind == eRegisterKindLLDB)
967    {
968        return reg;
969    }
970    return LLDB_INVALID_REGNUM;
971}
972
973
974uint32_t
975RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints ()
976{
977#if defined (__arm__)
978    // Set the init value to something that will let us know that we need to
979    // autodetect how many breakpoints are supported dynamically...
980    static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
981    if (g_num_supported_hw_breakpoints == UINT32_MAX)
982    {
983        // Set this to zero in case we can't tell if there are any HW breakpoints
984        g_num_supported_hw_breakpoints = 0;
985
986        uint32_t register_DBGDIDR;
987
988        asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
989        g_num_supported_hw_breakpoints = Bits32 (register_DBGDIDR, 27, 24);
990        // Zero is reserved for the BRP count, so don't increment it if it is zero
991        if (g_num_supported_hw_breakpoints > 0)
992            g_num_supported_hw_breakpoints++;
993//        if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_breakpoints);
994
995    }
996    return g_num_supported_hw_breakpoints;
997#else
998    // TODO: figure out remote case here!
999    return 6;
1000#endif
1001}
1002
1003uint32_t
1004RegisterContextDarwin_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
1005{
1006    // Make sure our address isn't bogus
1007    if (addr & 1)
1008        return LLDB_INVALID_INDEX32;
1009
1010    int kret = ReadDBG (false);
1011
1012    if (kret == KERN_SUCCESS)
1013    {
1014        const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
1015        uint32_t i;
1016        for (i=0; i<num_hw_breakpoints; ++i)
1017        {
1018            if ((dbg.bcr[i] & BCR_ENABLE) == 0)
1019                break; // We found an available hw breakpoint slot (in i)
1020        }
1021
1022        // See if we found an available hw breakpoint slot above
1023        if (i < num_hw_breakpoints)
1024        {
1025            // Make sure bits 1:0 are clear in our address
1026            dbg.bvr[i] = addr & ~((lldb::addr_t)3);
1027
1028            if (size == 2 || addr & 2)
1029            {
1030                uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
1031
1032                // We have a thumb breakpoint
1033                // We have an ARM breakpoint
1034                dbg.bcr[i] =  BCR_M_IMVA_MATCH |    // Stop on address mismatch
1035                                        byte_addr_select |  // Set the correct byte address select so we only trigger on the correct opcode
1036                                        S_USER |            // Which modes should this breakpoint stop in?
1037                                        BCR_ENABLE;         // Enable this hardware breakpoint
1038//                if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)",
1039//                        addr,
1040//                        size,
1041//                        i,
1042//                        i,
1043//                        dbg.bvr[i],
1044//                        dbg.bcr[i]);
1045            }
1046            else if (size == 4)
1047            {
1048                // We have an ARM breakpoint
1049                dbg.bcr[i] =  BCR_M_IMVA_MATCH |    // Stop on address mismatch
1050                                        BAS_IMVA_ALL |      // Stop on any of the four bytes following the IMVA
1051                                        S_USER |            // Which modes should this breakpoint stop in?
1052                                        BCR_ENABLE;         // Enable this hardware breakpoint
1053//                if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)",
1054//                        addr,
1055//                        size,
1056//                        i,
1057//                        i,
1058//                        dbg.bvr[i],
1059//                        dbg.bcr[i]);
1060            }
1061
1062            kret = WriteDBG();
1063//            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint() WriteDBG() => 0x%8.8x.", kret);
1064
1065            if (kret == KERN_SUCCESS)
1066                return i;
1067        }
1068//        else
1069//        {
1070//            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size);
1071//        }
1072    }
1073
1074    return LLDB_INVALID_INDEX32;
1075}
1076
1077bool
1078RegisterContextDarwin_arm::ClearHardwareBreakpoint (uint32_t hw_index)
1079{
1080    int kret = ReadDBG (false);
1081
1082    const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
1083    if (kret == KERN_SUCCESS)
1084    {
1085        if (hw_index < num_hw_points)
1086        {
1087            dbg.bcr[hw_index] = 0;
1088//            if (log) log->Printf ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x  BCR%u = 0x%8.8x",
1089//                    hw_index,
1090//                    hw_index,
1091//                    dbg.bvr[hw_index],
1092//                    hw_index,
1093//                    dbg.bcr[hw_index]);
1094
1095            kret = WriteDBG();
1096
1097            if (kret == KERN_SUCCESS)
1098                return true;
1099        }
1100    }
1101    return false;
1102}
1103
1104uint32_t
1105RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints ()
1106{
1107#if defined (__arm__)
1108    // Set the init value to something that will let us know that we need to
1109    // autodetect how many watchpoints are supported dynamically...
1110    static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
1111    if (g_num_supported_hw_watchpoints == UINT32_MAX)
1112    {
1113        // Set this to zero in case we can't tell if there are any HW breakpoints
1114        g_num_supported_hw_watchpoints = 0;
1115
1116        uint32_t register_DBGDIDR;
1117        asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
1118        g_num_supported_hw_watchpoints = Bits32 (register_DBGDIDR, 31, 28) + 1;
1119//        if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_watchpoints);
1120    }
1121    return g_num_supported_hw_watchpoints;
1122#else
1123    // TODO: figure out remote case here!
1124    return 2;
1125#endif
1126}
1127
1128
1129uint32_t
1130RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
1131{
1132//    if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
1133
1134    const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1135
1136    // Can't watch zero bytes
1137    if (size == 0)
1138        return LLDB_INVALID_INDEX32;
1139
1140    // We must watch for either read or write
1141    if (read == false && write == false)
1142        return LLDB_INVALID_INDEX32;
1143
1144    // Can't watch more than 4 bytes per WVR/WCR pair
1145    if (size > 4)
1146        return LLDB_INVALID_INDEX32;
1147
1148    // We can only watch up to four bytes that follow a 4 byte aligned address
1149    // per watchpoint register pair. Since we have at most so we can only watch
1150    // until the next 4 byte boundary and we need to make sure we can properly
1151    // encode this.
1152    uint32_t addr_word_offset = addr % 4;
1153//    if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
1154
1155    uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
1156//    if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
1157    if (byte_mask > 0xfu)
1158        return LLDB_INVALID_INDEX32;
1159
1160    // Read the debug state
1161    int kret = ReadDBG (false);
1162
1163    if (kret == KERN_SUCCESS)
1164    {
1165        // Check to make sure we have the needed hardware support
1166        uint32_t i = 0;
1167
1168        for (i=0; i<num_hw_watchpoints; ++i)
1169        {
1170            if ((dbg.wcr[i] & WCR_ENABLE) == 0)
1171                break; // We found an available hw breakpoint slot (in i)
1172        }
1173
1174        // See if we found an available hw breakpoint slot above
1175        if (i < num_hw_watchpoints)
1176        {
1177            // Make the byte_mask into a valid Byte Address Select mask
1178            uint32_t byte_address_select = byte_mask << 5;
1179            // Make sure bits 1:0 are clear in our address
1180            dbg.wvr[i] = addr & ~((lldb::addr_t)3);
1181            dbg.wcr[i] =  byte_address_select |       // Which bytes that follow the IMVA that we will watch
1182                                    S_USER |                    // Stop only in user mode
1183                                    (read ? WCR_LOAD : 0) |     // Stop on read access?
1184                                    (write ? WCR_STORE : 0) |   // Stop on write access?
1185                                    WCR_ENABLE;                 // Enable this watchpoint;
1186
1187            kret = WriteDBG();
1188//            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
1189
1190            if (kret == KERN_SUCCESS)
1191                return i;
1192        }
1193        else
1194        {
1195//            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
1196        }
1197    }
1198    return LLDB_INVALID_INDEX32;
1199}
1200
1201bool
1202RegisterContextDarwin_arm::ClearHardwareWatchpoint (uint32_t hw_index)
1203{
1204    int kret = ReadDBG (false);
1205
1206    const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
1207    if (kret == KERN_SUCCESS)
1208    {
1209        if (hw_index < num_hw_points)
1210        {
1211            dbg.wcr[hw_index] = 0;
1212//            if (log) log->Printf ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
1213//                    hw_index,
1214//                    hw_index,
1215//                    dbg.wvr[hw_index],
1216//                    hw_index,
1217//                    dbg.wcr[hw_index]);
1218
1219            kret = WriteDBG();
1220
1221            if (kret == KERN_SUCCESS)
1222                return true;
1223        }
1224    }
1225    return false;
1226}
1227
1228#endif
1229