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