]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
MFV r293415:
[FreeBSD/FreeBSD.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 #include "llvm/ADT/STLExtras.h"
41
42 using namespace lldb;
43 using namespace lldb_private;
44
45 enum
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 RegisterContextDarwin_arm::RegisterContextDarwin_arm(Thread &thread, uint32_t concrete_frame_idx) :
176     RegisterContext(thread, concrete_frame_idx),
177     gpr(),
178     fpu(),
179     exc()
180 {
181     uint32_t i;
182     for (i=0; i<kNumErrors; i++)
183     {
184         gpr_errs[i] = -1;
185         fpu_errs[i] = -1;
186         exc_errs[i] = -1;
187     }
188 }
189
190 RegisterContextDarwin_arm::~RegisterContextDarwin_arm()
191 {
192 }
193
194
195 #define GPR_OFFSET(idx) ((idx) * 4)
196 #define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR))
197 #define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU))
198 #define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextDarwin_arm::DBG, reg) + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC)))
199
200 #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
201 #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC))
202
203 static RegisterInfo g_register_infos[] = {
204 // General purpose registers
205 //  NAME        ALT     SZ  OFFSET              ENCODING        FORMAT          COMPILER                DWARF               GENERIC                     GDB                     LLDB NATIVE   VALUE REGS    INVALIDATE REGS
206 //  ======      ======= ==  =============       =============   ============    ===============         ===============     =========================   =====================   ============= ==========    ===============
207 {   "r0",       NULL,   4,  GPR_OFFSET(0),      eEncodingUint,  eFormatHex,     { gcc_r0,               dwarf_r0,           LLDB_INVALID_REGNUM,        gdb_arm_r0,             gpr_r0      },      NULL,              NULL},
208 {   "r1",       NULL,   4,  GPR_OFFSET(1),      eEncodingUint,  eFormatHex,     { gcc_r1,               dwarf_r1,           LLDB_INVALID_REGNUM,        gdb_arm_r1,             gpr_r1      },      NULL,              NULL},
209 {   "r2",       NULL,   4,  GPR_OFFSET(2),      eEncodingUint,  eFormatHex,     { gcc_r2,               dwarf_r2,           LLDB_INVALID_REGNUM,        gdb_arm_r2,             gpr_r2      },      NULL,              NULL},
210 {   "r3",       NULL,   4,  GPR_OFFSET(3),      eEncodingUint,  eFormatHex,     { gcc_r3,               dwarf_r3,           LLDB_INVALID_REGNUM,        gdb_arm_r3,             gpr_r3      },      NULL,              NULL},
211 {   "r4",       NULL,   4,  GPR_OFFSET(4),      eEncodingUint,  eFormatHex,     { gcc_r4,               dwarf_r4,           LLDB_INVALID_REGNUM,        gdb_arm_r4,             gpr_r4      },      NULL,              NULL},
212 {   "r5",       NULL,   4,  GPR_OFFSET(5),      eEncodingUint,  eFormatHex,     { gcc_r5,               dwarf_r5,           LLDB_INVALID_REGNUM,        gdb_arm_r5,             gpr_r5      },      NULL,              NULL},
213 {   "r6",       NULL,   4,  GPR_OFFSET(6),      eEncodingUint,  eFormatHex,     { gcc_r6,               dwarf_r6,           LLDB_INVALID_REGNUM,        gdb_arm_r6,             gpr_r6      },      NULL,              NULL},
214 {   "r7",       NULL,   4,  GPR_OFFSET(7),      eEncodingUint,  eFormatHex,     { gcc_r7,               dwarf_r7,           LLDB_REGNUM_GENERIC_FP,     gdb_arm_r7,             gpr_r7      },      NULL,              NULL},
215 {   "r8",       NULL,   4,  GPR_OFFSET(8),      eEncodingUint,  eFormatHex,     { gcc_r8,               dwarf_r8,           LLDB_INVALID_REGNUM,        gdb_arm_r8,             gpr_r8      },      NULL,              NULL},
216 {   "r9",       NULL,   4,  GPR_OFFSET(9),      eEncodingUint,  eFormatHex,     { gcc_r9,               dwarf_r9,           LLDB_INVALID_REGNUM,        gdb_arm_r9,             gpr_r9      },      NULL,              NULL},
217 {   "r10",      NULL,   4,  GPR_OFFSET(10),     eEncodingUint,  eFormatHex,     { gcc_r10,              dwarf_r10,          LLDB_INVALID_REGNUM,        gdb_arm_r10,            gpr_r10     },      NULL,              NULL},
218 {   "r11",      NULL,   4,  GPR_OFFSET(11),     eEncodingUint,  eFormatHex,     { gcc_r11,              dwarf_r11,          LLDB_INVALID_REGNUM,        gdb_arm_r11,            gpr_r11     },      NULL,              NULL},
219 {   "r12",      NULL,   4,  GPR_OFFSET(12),     eEncodingUint,  eFormatHex,     { gcc_r12,              dwarf_r12,          LLDB_INVALID_REGNUM,        gdb_arm_r12,            gpr_r12     },      NULL,              NULL},
220 {   "sp",       "r13",  4,  GPR_OFFSET(13),     eEncodingUint,  eFormatHex,     { gcc_sp,               dwarf_sp,           LLDB_REGNUM_GENERIC_SP,     gdb_arm_sp,             gpr_sp      },      NULL,              NULL},
221 {   "lr",       "r14",  4,  GPR_OFFSET(14),     eEncodingUint,  eFormatHex,     { gcc_lr,               dwarf_lr,           LLDB_REGNUM_GENERIC_RA,     gdb_arm_lr,             gpr_lr      },      NULL,              NULL},
222 {   "pc",       "r15",  4,  GPR_OFFSET(15),     eEncodingUint,  eFormatHex,     { gcc_pc,               dwarf_pc,           LLDB_REGNUM_GENERIC_PC,     gdb_arm_pc,             gpr_pc      },      NULL,              NULL},
223 {   "cpsr",     "psr",  4,  GPR_OFFSET(16),     eEncodingUint,  eFormatHex,     { gcc_cpsr,             dwarf_cpsr,         LLDB_REGNUM_GENERIC_FLAGS,  gdb_arm_cpsr,           gpr_cpsr    },      NULL,              NULL},
224
225 {   "s0",       NULL,   4,  FPU_OFFSET(0),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s0,           LLDB_INVALID_REGNUM,        gdb_arm_s0,             fpu_s0      },      NULL,              NULL},
226 {   "s1",       NULL,   4,  FPU_OFFSET(1),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s1,           LLDB_INVALID_REGNUM,        gdb_arm_s1,             fpu_s1      },      NULL,              NULL},
227 {   "s2",       NULL,   4,  FPU_OFFSET(2),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s2,           LLDB_INVALID_REGNUM,        gdb_arm_s2,             fpu_s2      },      NULL,              NULL},
228 {   "s3",       NULL,   4,  FPU_OFFSET(3),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s3,           LLDB_INVALID_REGNUM,        gdb_arm_s3,             fpu_s3      },      NULL,              NULL},
229 {   "s4",       NULL,   4,  FPU_OFFSET(4),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s4,           LLDB_INVALID_REGNUM,        gdb_arm_s4,             fpu_s4      },      NULL,              NULL},
230 {   "s5",       NULL,   4,  FPU_OFFSET(5),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s5,           LLDB_INVALID_REGNUM,        gdb_arm_s5,             fpu_s5      },      NULL,              NULL},
231 {   "s6",       NULL,   4,  FPU_OFFSET(6),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s6,           LLDB_INVALID_REGNUM,        gdb_arm_s6,             fpu_s6      },      NULL,              NULL},
232 {   "s7",       NULL,   4,  FPU_OFFSET(7),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s7,           LLDB_INVALID_REGNUM,        gdb_arm_s7,             fpu_s7      },      NULL,              NULL},
233 {   "s8",       NULL,   4,  FPU_OFFSET(8),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s8,           LLDB_INVALID_REGNUM,        gdb_arm_s8,             fpu_s8      },      NULL,              NULL},
234 {   "s9",       NULL,   4,  FPU_OFFSET(9),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s9,           LLDB_INVALID_REGNUM,        gdb_arm_s9,             fpu_s9      },      NULL,              NULL},
235 {   "s10",      NULL,   4,  FPU_OFFSET(10),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s10,          LLDB_INVALID_REGNUM,        gdb_arm_s10,            fpu_s10     },      NULL,              NULL},
236 {   "s11",      NULL,   4,  FPU_OFFSET(11),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s11,          LLDB_INVALID_REGNUM,        gdb_arm_s11,            fpu_s11     },      NULL,              NULL},
237 {   "s12",      NULL,   4,  FPU_OFFSET(12),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s12,          LLDB_INVALID_REGNUM,        gdb_arm_s12,            fpu_s12     },      NULL,              NULL},
238 {   "s13",      NULL,   4,  FPU_OFFSET(13),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s13,          LLDB_INVALID_REGNUM,        gdb_arm_s13,            fpu_s13     },      NULL,              NULL},
239 {   "s14",      NULL,   4,  FPU_OFFSET(14),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s14,          LLDB_INVALID_REGNUM,        gdb_arm_s14,            fpu_s14     },      NULL,              NULL},
240 {   "s15",      NULL,   4,  FPU_OFFSET(15),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s15,          LLDB_INVALID_REGNUM,        gdb_arm_s15,            fpu_s15     },      NULL,              NULL},
241 {   "s16",      NULL,   4,  FPU_OFFSET(16),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s16,          LLDB_INVALID_REGNUM,        gdb_arm_s16,            fpu_s16     },      NULL,              NULL},
242 {   "s17",      NULL,   4,  FPU_OFFSET(17),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s17,          LLDB_INVALID_REGNUM,        gdb_arm_s17,            fpu_s17     },      NULL,              NULL},
243 {   "s18",      NULL,   4,  FPU_OFFSET(18),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s18,          LLDB_INVALID_REGNUM,        gdb_arm_s18,            fpu_s18     },      NULL,              NULL},
244 {   "s19",      NULL,   4,  FPU_OFFSET(19),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s19,          LLDB_INVALID_REGNUM,        gdb_arm_s19,            fpu_s19     },      NULL,              NULL},
245 {   "s20",      NULL,   4,  FPU_OFFSET(20),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s20,          LLDB_INVALID_REGNUM,        gdb_arm_s20,            fpu_s20     },      NULL,              NULL},
246 {   "s21",      NULL,   4,  FPU_OFFSET(21),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s21,          LLDB_INVALID_REGNUM,        gdb_arm_s21,            fpu_s21     },      NULL,              NULL},
247 {   "s22",      NULL,   4,  FPU_OFFSET(22),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s22,          LLDB_INVALID_REGNUM,        gdb_arm_s22,            fpu_s22     },      NULL,              NULL},
248 {   "s23",      NULL,   4,  FPU_OFFSET(23),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s23,          LLDB_INVALID_REGNUM,        gdb_arm_s23,            fpu_s23     },      NULL,              NULL},
249 {   "s24",      NULL,   4,  FPU_OFFSET(24),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s24,          LLDB_INVALID_REGNUM,        gdb_arm_s24,            fpu_s24     },      NULL,              NULL},
250 {   "s25",      NULL,   4,  FPU_OFFSET(25),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s25,          LLDB_INVALID_REGNUM,        gdb_arm_s25,            fpu_s25     },      NULL,              NULL},
251 {   "s26",      NULL,   4,  FPU_OFFSET(26),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s26,          LLDB_INVALID_REGNUM,        gdb_arm_s26,            fpu_s26     },      NULL,              NULL},
252 {   "s27",      NULL,   4,  FPU_OFFSET(27),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s27,          LLDB_INVALID_REGNUM,        gdb_arm_s27,            fpu_s27     },      NULL,              NULL},
253 {   "s28",      NULL,   4,  FPU_OFFSET(28),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s28,          LLDB_INVALID_REGNUM,        gdb_arm_s28,            fpu_s28     },      NULL,              NULL},
254 {   "s29",      NULL,   4,  FPU_OFFSET(29),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s29,          LLDB_INVALID_REGNUM,        gdb_arm_s29,            fpu_s29     },      NULL,              NULL},
255 {   "s30",      NULL,   4,  FPU_OFFSET(30),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s30,          LLDB_INVALID_REGNUM,        gdb_arm_s30,            fpu_s30     },      NULL,              NULL},
256 {   "s31",      NULL,   4,  FPU_OFFSET(31),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s31,          LLDB_INVALID_REGNUM,        gdb_arm_s31,            fpu_s31     },      NULL,              NULL},
257 {   "fpscr",    NULL,   4,  FPU_OFFSET(32),     eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        gdb_arm_fpscr,          fpu_fpscr   },      NULL,              NULL},
258
259 {   "exception",NULL,   4,  EXC_OFFSET(0),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_exception },    NULL,              NULL},
260 {   "fsr",      NULL,   4,  EXC_OFFSET(1),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_fsr       },    NULL,              NULL},
261 {   "far",      NULL,   4,  EXC_OFFSET(2),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_far       },    NULL,              NULL},
262
263 {   DEFINE_DBG (bvr, 0) },
264 {   DEFINE_DBG (bvr, 1) },
265 {   DEFINE_DBG (bvr, 2) },
266 {   DEFINE_DBG (bvr, 3) },
267 {   DEFINE_DBG (bvr, 4) },
268 {   DEFINE_DBG (bvr, 5) },
269 {   DEFINE_DBG (bvr, 6) },
270 {   DEFINE_DBG (bvr, 7) },
271 {   DEFINE_DBG (bvr, 8) },
272 {   DEFINE_DBG (bvr, 9) },
273 {   DEFINE_DBG (bvr, 10) },
274 {   DEFINE_DBG (bvr, 11) },
275 {   DEFINE_DBG (bvr, 12) },
276 {   DEFINE_DBG (bvr, 13) },
277 {   DEFINE_DBG (bvr, 14) },
278 {   DEFINE_DBG (bvr, 15) },
279
280 {   DEFINE_DBG (bcr, 0) },
281 {   DEFINE_DBG (bcr, 1) },
282 {   DEFINE_DBG (bcr, 2) },
283 {   DEFINE_DBG (bcr, 3) },
284 {   DEFINE_DBG (bcr, 4) },
285 {   DEFINE_DBG (bcr, 5) },
286 {   DEFINE_DBG (bcr, 6) },
287 {   DEFINE_DBG (bcr, 7) },
288 {   DEFINE_DBG (bcr, 8) },
289 {   DEFINE_DBG (bcr, 9) },
290 {   DEFINE_DBG (bcr, 10) },
291 {   DEFINE_DBG (bcr, 11) },
292 {   DEFINE_DBG (bcr, 12) },
293 {   DEFINE_DBG (bcr, 13) },
294 {   DEFINE_DBG (bcr, 14) },
295 {   DEFINE_DBG (bcr, 15) },
296
297 {   DEFINE_DBG (wvr, 0) },
298 {   DEFINE_DBG (wvr, 1) },
299 {   DEFINE_DBG (wvr, 2) },
300 {   DEFINE_DBG (wvr, 3) },
301 {   DEFINE_DBG (wvr, 4) },
302 {   DEFINE_DBG (wvr, 5) },
303 {   DEFINE_DBG (wvr, 6) },
304 {   DEFINE_DBG (wvr, 7) },
305 {   DEFINE_DBG (wvr, 8) },
306 {   DEFINE_DBG (wvr, 9) },
307 {   DEFINE_DBG (wvr, 10) },
308 {   DEFINE_DBG (wvr, 11) },
309 {   DEFINE_DBG (wvr, 12) },
310 {   DEFINE_DBG (wvr, 13) },
311 {   DEFINE_DBG (wvr, 14) },
312 {   DEFINE_DBG (wvr, 15) },
313
314 {   DEFINE_DBG (wcr, 0) },
315 {   DEFINE_DBG (wcr, 1) },
316 {   DEFINE_DBG (wcr, 2) },
317 {   DEFINE_DBG (wcr, 3) },
318 {   DEFINE_DBG (wcr, 4) },
319 {   DEFINE_DBG (wcr, 5) },
320 {   DEFINE_DBG (wcr, 6) },
321 {   DEFINE_DBG (wcr, 7) },
322 {   DEFINE_DBG (wcr, 8) },
323 {   DEFINE_DBG (wcr, 9) },
324 {   DEFINE_DBG (wcr, 10) },
325 {   DEFINE_DBG (wcr, 11) },
326 {   DEFINE_DBG (wcr, 12) },
327 {   DEFINE_DBG (wcr, 13) },
328 {   DEFINE_DBG (wcr, 14) },
329 {   DEFINE_DBG (wcr, 15) }
330 };
331
332 // General purpose registers
333 static uint32_t
334 g_gpr_regnums[] =
335 {
336     gpr_r0,
337     gpr_r1,
338     gpr_r2,
339     gpr_r3,
340     gpr_r4,
341     gpr_r5,
342     gpr_r6,
343     gpr_r7,
344     gpr_r8,
345     gpr_r9,
346     gpr_r10,
347     gpr_r11,
348     gpr_r12,
349     gpr_sp,
350     gpr_lr,
351     gpr_pc,
352     gpr_cpsr
353 };
354
355 // Floating point registers
356 static uint32_t
357 g_fpu_regnums[] =
358 {
359     fpu_s0,
360     fpu_s1,
361     fpu_s2,
362     fpu_s3,
363     fpu_s4,
364     fpu_s5,
365     fpu_s6,
366     fpu_s7,
367     fpu_s8,
368     fpu_s9,
369     fpu_s10,
370     fpu_s11,
371     fpu_s12,
372     fpu_s13,
373     fpu_s14,
374     fpu_s15,
375     fpu_s16,
376     fpu_s17,
377     fpu_s18,
378     fpu_s19,
379     fpu_s20,
380     fpu_s21,
381     fpu_s22,
382     fpu_s23,
383     fpu_s24,
384     fpu_s25,
385     fpu_s26,
386     fpu_s27,
387     fpu_s28,
388     fpu_s29,
389     fpu_s30,
390     fpu_s31,
391     fpu_fpscr,
392 };
393
394 // Exception registers
395
396 static uint32_t
397 g_exc_regnums[] =
398 {
399     exc_exception,
400     exc_fsr,
401     exc_far,
402 };
403
404 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
405
406 void
407 RegisterContextDarwin_arm::InvalidateAllRegisters ()
408 {
409     InvalidateAllRegisterStates();
410 }
411
412
413 size_t
414 RegisterContextDarwin_arm::GetRegisterCount ()
415 {
416     assert(k_num_register_infos == k_num_registers);
417     return k_num_registers;
418 }
419
420 const RegisterInfo *
421 RegisterContextDarwin_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
429 size_t
430 RegisterContextDarwin_arm::GetRegisterInfosCount ()
431 {
432     return k_num_register_infos;
433 }
434
435 const RegisterInfo *
436 RegisterContextDarwin_arm::GetRegisterInfos ()
437 {
438     return g_register_infos;
439 }
440
441
442 // Number of registers in each register set
443 const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
444 const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
445 const 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 //----------------------------------------------------------------------
452 static 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
459 const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
460
461
462 size_t
463 RegisterContextDarwin_arm::GetRegisterSetCount ()
464 {
465     return k_num_regsets;
466 }
467
468 const RegisterSet *
469 RegisterContextDarwin_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 //----------------------------------------------------------------------
480 int
481 RegisterContextDarwin_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
492 int
493 RegisterContextDarwin_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
503 int
504 RegisterContextDarwin_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
514 int
515 RegisterContextDarwin_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
525 int
526 RegisterContextDarwin_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
536 int
537 RegisterContextDarwin_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
550 int
551 RegisterContextDarwin_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
564 int
565 RegisterContextDarwin_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
578 int
579 RegisterContextDarwin_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
593 int
594 RegisterContextDarwin_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
607 int
608 RegisterContextDarwin_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
625 void
626 RegisterContextDarwin_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
638 bool
639 RegisterContextDarwin_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
730 bool
731 RegisterContextDarwin_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
821 bool
822 RegisterContextDarwin_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
843 bool
844 RegisterContextDarwin_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
868 uint32_t
869 RegisterContextDarwin_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 == eRegisterKindGCC)
944     {
945         switch (reg)
946         {
947         case gcc_r0:    return gpr_r0;
948         case gcc_r1:    return gpr_r1;
949         case gcc_r2:    return gpr_r2;
950         case gcc_r3:    return gpr_r3;
951         case gcc_r4:    return gpr_r4;
952         case gcc_r5:    return gpr_r5;
953         case gcc_r6:    return gpr_r6;
954         case gcc_r7:    return gpr_r7;
955         case gcc_r8:    return gpr_r8;
956         case gcc_r9:    return gpr_r9;
957         case gcc_r10:   return gpr_r10;
958         case gcc_r11:   return gpr_r11;
959         case gcc_r12:   return gpr_r12;
960         case gcc_sp:    return gpr_sp;
961         case gcc_lr:    return gpr_lr;
962         case gcc_pc:    return gpr_pc;
963         case gcc_cpsr:  return gpr_cpsr;
964         }
965     }
966     else if (kind == eRegisterKindLLDB)
967     {
968         return reg;
969     }
970     return LLDB_INVALID_REGNUM;
971 }
972
973
974 uint32_t
975 RegisterContextDarwin_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
1003 uint32_t
1004 RegisterContextDarwin_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
1077 bool
1078 RegisterContextDarwin_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
1104 uint32_t
1105 RegisterContextDarwin_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
1129 uint32_t
1130 RegisterContextDarwin_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
1201 bool
1202 RegisterContextDarwin_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