1dda28197Spatrick //===-- RegisterContextDarwin_arm.cpp -------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "RegisterContextDarwin_arm.h"
10061da546Spatrick #include "RegisterContextDarwinConstants.h"
11061da546Spatrick
12061da546Spatrick #include "lldb/Utility/DataBufferHeap.h"
13061da546Spatrick #include "lldb/Utility/DataExtractor.h"
14061da546Spatrick #include "lldb/Utility/Endian.h"
15061da546Spatrick #include "lldb/Utility/Log.h"
16061da546Spatrick #include "lldb/Utility/RegisterValue.h"
17061da546Spatrick #include "lldb/Utility/Scalar.h"
18061da546Spatrick #include "llvm/Support/Compiler.h"
19061da546Spatrick
20061da546Spatrick #include "Plugins/Process/Utility/InstructionUtils.h"
21061da546Spatrick
22061da546Spatrick #include <memory>
23061da546Spatrick
24061da546Spatrick #include "Utility/ARM_DWARF_Registers.h"
25061da546Spatrick #include "Utility/ARM_ehframe_Registers.h"
26061da546Spatrick
27061da546Spatrick #include "llvm/ADT/STLExtras.h"
28061da546Spatrick
29061da546Spatrick using namespace lldb;
30061da546Spatrick using namespace lldb_private;
31061da546Spatrick
32061da546Spatrick enum {
33061da546Spatrick gpr_r0 = 0,
34061da546Spatrick gpr_r1,
35061da546Spatrick gpr_r2,
36061da546Spatrick gpr_r3,
37061da546Spatrick gpr_r4,
38061da546Spatrick gpr_r5,
39061da546Spatrick gpr_r6,
40061da546Spatrick gpr_r7,
41061da546Spatrick gpr_r8,
42061da546Spatrick gpr_r9,
43061da546Spatrick gpr_r10,
44061da546Spatrick gpr_r11,
45061da546Spatrick gpr_r12,
46061da546Spatrick gpr_r13,
47061da546Spatrick gpr_sp = gpr_r13,
48061da546Spatrick gpr_r14,
49061da546Spatrick gpr_lr = gpr_r14,
50061da546Spatrick gpr_r15,
51061da546Spatrick gpr_pc = gpr_r15,
52061da546Spatrick gpr_cpsr,
53061da546Spatrick
54061da546Spatrick fpu_s0,
55061da546Spatrick fpu_s1,
56061da546Spatrick fpu_s2,
57061da546Spatrick fpu_s3,
58061da546Spatrick fpu_s4,
59061da546Spatrick fpu_s5,
60061da546Spatrick fpu_s6,
61061da546Spatrick fpu_s7,
62061da546Spatrick fpu_s8,
63061da546Spatrick fpu_s9,
64061da546Spatrick fpu_s10,
65061da546Spatrick fpu_s11,
66061da546Spatrick fpu_s12,
67061da546Spatrick fpu_s13,
68061da546Spatrick fpu_s14,
69061da546Spatrick fpu_s15,
70061da546Spatrick fpu_s16,
71061da546Spatrick fpu_s17,
72061da546Spatrick fpu_s18,
73061da546Spatrick fpu_s19,
74061da546Spatrick fpu_s20,
75061da546Spatrick fpu_s21,
76061da546Spatrick fpu_s22,
77061da546Spatrick fpu_s23,
78061da546Spatrick fpu_s24,
79061da546Spatrick fpu_s25,
80061da546Spatrick fpu_s26,
81061da546Spatrick fpu_s27,
82061da546Spatrick fpu_s28,
83061da546Spatrick fpu_s29,
84061da546Spatrick fpu_s30,
85061da546Spatrick fpu_s31,
86061da546Spatrick fpu_fpscr,
87061da546Spatrick
88061da546Spatrick exc_exception,
89061da546Spatrick exc_fsr,
90061da546Spatrick exc_far,
91061da546Spatrick
92061da546Spatrick dbg_bvr0,
93061da546Spatrick dbg_bvr1,
94061da546Spatrick dbg_bvr2,
95061da546Spatrick dbg_bvr3,
96061da546Spatrick dbg_bvr4,
97061da546Spatrick dbg_bvr5,
98061da546Spatrick dbg_bvr6,
99061da546Spatrick dbg_bvr7,
100061da546Spatrick dbg_bvr8,
101061da546Spatrick dbg_bvr9,
102061da546Spatrick dbg_bvr10,
103061da546Spatrick dbg_bvr11,
104061da546Spatrick dbg_bvr12,
105061da546Spatrick dbg_bvr13,
106061da546Spatrick dbg_bvr14,
107061da546Spatrick dbg_bvr15,
108061da546Spatrick
109061da546Spatrick dbg_bcr0,
110061da546Spatrick dbg_bcr1,
111061da546Spatrick dbg_bcr2,
112061da546Spatrick dbg_bcr3,
113061da546Spatrick dbg_bcr4,
114061da546Spatrick dbg_bcr5,
115061da546Spatrick dbg_bcr6,
116061da546Spatrick dbg_bcr7,
117061da546Spatrick dbg_bcr8,
118061da546Spatrick dbg_bcr9,
119061da546Spatrick dbg_bcr10,
120061da546Spatrick dbg_bcr11,
121061da546Spatrick dbg_bcr12,
122061da546Spatrick dbg_bcr13,
123061da546Spatrick dbg_bcr14,
124061da546Spatrick dbg_bcr15,
125061da546Spatrick
126061da546Spatrick dbg_wvr0,
127061da546Spatrick dbg_wvr1,
128061da546Spatrick dbg_wvr2,
129061da546Spatrick dbg_wvr3,
130061da546Spatrick dbg_wvr4,
131061da546Spatrick dbg_wvr5,
132061da546Spatrick dbg_wvr6,
133061da546Spatrick dbg_wvr7,
134061da546Spatrick dbg_wvr8,
135061da546Spatrick dbg_wvr9,
136061da546Spatrick dbg_wvr10,
137061da546Spatrick dbg_wvr11,
138061da546Spatrick dbg_wvr12,
139061da546Spatrick dbg_wvr13,
140061da546Spatrick dbg_wvr14,
141061da546Spatrick dbg_wvr15,
142061da546Spatrick
143061da546Spatrick dbg_wcr0,
144061da546Spatrick dbg_wcr1,
145061da546Spatrick dbg_wcr2,
146061da546Spatrick dbg_wcr3,
147061da546Spatrick dbg_wcr4,
148061da546Spatrick dbg_wcr5,
149061da546Spatrick dbg_wcr6,
150061da546Spatrick dbg_wcr7,
151061da546Spatrick dbg_wcr8,
152061da546Spatrick dbg_wcr9,
153061da546Spatrick dbg_wcr10,
154061da546Spatrick dbg_wcr11,
155061da546Spatrick dbg_wcr12,
156061da546Spatrick dbg_wcr13,
157061da546Spatrick dbg_wcr14,
158061da546Spatrick dbg_wcr15,
159061da546Spatrick
160061da546Spatrick k_num_registers
161061da546Spatrick };
162061da546Spatrick
163061da546Spatrick #define GPR_OFFSET(idx) ((idx)*4)
164061da546Spatrick #define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR))
165061da546Spatrick #define EXC_OFFSET(idx) \
166061da546Spatrick ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR) + \
167061da546Spatrick sizeof(RegisterContextDarwin_arm::FPU))
168061da546Spatrick #define DBG_OFFSET(reg) \
169061da546Spatrick ((LLVM_EXTENSION offsetof(RegisterContextDarwin_arm::DBG, reg) + \
170061da546Spatrick sizeof(RegisterContextDarwin_arm::GPR) + \
171061da546Spatrick sizeof(RegisterContextDarwin_arm::FPU) + \
172061da546Spatrick sizeof(RegisterContextDarwin_arm::EXC)))
173061da546Spatrick
174061da546Spatrick #define DEFINE_DBG(reg, i) \
175061da546Spatrick #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *) NULL)->reg[i]), \
176061da546Spatrick DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
177061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
178061da546Spatrick LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
179061da546Spatrick LLDB_INVALID_REGNUM }, \
180*f6aab3d8Srobert nullptr, nullptr,
181061da546Spatrick #define REG_CONTEXT_SIZE \
182061da546Spatrick (sizeof(RegisterContextDarwin_arm::GPR) + \
183061da546Spatrick sizeof(RegisterContextDarwin_arm::FPU) + \
184061da546Spatrick sizeof(RegisterContextDarwin_arm::EXC))
185061da546Spatrick
186061da546Spatrick static RegisterInfo g_register_infos[] = {
187061da546Spatrick // General purpose registers
188061da546Spatrick // NAME ALT SZ OFFSET ENCODING FORMAT
189061da546Spatrick // EH_FRAME DWARF GENERIC
190061da546Spatrick // PROCESS PLUGIN LLDB NATIVE
191061da546Spatrick // ====== ======= == ============= ============= ============
192061da546Spatrick // =============== =============== =========================
193061da546Spatrick // ===================== =============
194061da546Spatrick {"r0",
195061da546Spatrick nullptr,
196061da546Spatrick 4,
197061da546Spatrick GPR_OFFSET(0),
198061da546Spatrick eEncodingUint,
199061da546Spatrick eFormatHex,
200061da546Spatrick {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0},
201061da546Spatrick nullptr,
202061da546Spatrick nullptr,
203*f6aab3d8Srobert },
204061da546Spatrick {"r1",
205061da546Spatrick nullptr,
206061da546Spatrick 4,
207061da546Spatrick GPR_OFFSET(1),
208061da546Spatrick eEncodingUint,
209061da546Spatrick eFormatHex,
210061da546Spatrick {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1},
211061da546Spatrick nullptr,
212061da546Spatrick nullptr,
213*f6aab3d8Srobert },
214061da546Spatrick {"r2",
215061da546Spatrick nullptr,
216061da546Spatrick 4,
217061da546Spatrick GPR_OFFSET(2),
218061da546Spatrick eEncodingUint,
219061da546Spatrick eFormatHex,
220061da546Spatrick {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2},
221061da546Spatrick nullptr,
222061da546Spatrick nullptr,
223*f6aab3d8Srobert },
224061da546Spatrick {"r3",
225061da546Spatrick nullptr,
226061da546Spatrick 4,
227061da546Spatrick GPR_OFFSET(3),
228061da546Spatrick eEncodingUint,
229061da546Spatrick eFormatHex,
230061da546Spatrick {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3},
231061da546Spatrick nullptr,
232061da546Spatrick nullptr,
233*f6aab3d8Srobert },
234061da546Spatrick {"r4",
235061da546Spatrick nullptr,
236061da546Spatrick 4,
237061da546Spatrick GPR_OFFSET(4),
238061da546Spatrick eEncodingUint,
239061da546Spatrick eFormatHex,
240061da546Spatrick {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},
241061da546Spatrick nullptr,
242061da546Spatrick nullptr,
243*f6aab3d8Srobert },
244061da546Spatrick {"r5",
245061da546Spatrick nullptr,
246061da546Spatrick 4,
247061da546Spatrick GPR_OFFSET(5),
248061da546Spatrick eEncodingUint,
249061da546Spatrick eFormatHex,
250061da546Spatrick {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},
251061da546Spatrick nullptr,
252061da546Spatrick nullptr,
253*f6aab3d8Srobert },
254061da546Spatrick {"r6",
255061da546Spatrick nullptr,
256061da546Spatrick 4,
257061da546Spatrick GPR_OFFSET(6),
258061da546Spatrick eEncodingUint,
259061da546Spatrick eFormatHex,
260061da546Spatrick {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},
261061da546Spatrick nullptr,
262061da546Spatrick nullptr,
263*f6aab3d8Srobert },
264061da546Spatrick {"r7",
265061da546Spatrick nullptr,
266061da546Spatrick 4,
267061da546Spatrick GPR_OFFSET(7),
268061da546Spatrick eEncodingUint,
269061da546Spatrick eFormatHex,
270061da546Spatrick {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
271061da546Spatrick gpr_r7},
272061da546Spatrick nullptr,
273061da546Spatrick nullptr,
274*f6aab3d8Srobert },
275061da546Spatrick {"r8",
276061da546Spatrick nullptr,
277061da546Spatrick 4,
278061da546Spatrick GPR_OFFSET(8),
279061da546Spatrick eEncodingUint,
280061da546Spatrick eFormatHex,
281061da546Spatrick {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},
282061da546Spatrick nullptr,
283061da546Spatrick nullptr,
284*f6aab3d8Srobert },
285061da546Spatrick {"r9",
286061da546Spatrick nullptr,
287061da546Spatrick 4,
288061da546Spatrick GPR_OFFSET(9),
289061da546Spatrick eEncodingUint,
290061da546Spatrick eFormatHex,
291061da546Spatrick {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},
292061da546Spatrick nullptr,
293061da546Spatrick nullptr,
294*f6aab3d8Srobert },
295061da546Spatrick {"r10",
296061da546Spatrick nullptr,
297061da546Spatrick 4,
298061da546Spatrick GPR_OFFSET(10),
299061da546Spatrick eEncodingUint,
300061da546Spatrick eFormatHex,
301061da546Spatrick {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
302061da546Spatrick gpr_r10},
303061da546Spatrick nullptr,
304061da546Spatrick nullptr,
305*f6aab3d8Srobert },
306061da546Spatrick {"r11",
307061da546Spatrick nullptr,
308061da546Spatrick 4,
309061da546Spatrick GPR_OFFSET(11),
310061da546Spatrick eEncodingUint,
311061da546Spatrick eFormatHex,
312061da546Spatrick {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
313061da546Spatrick gpr_r11},
314061da546Spatrick nullptr,
315061da546Spatrick nullptr,
316*f6aab3d8Srobert },
317061da546Spatrick {"r12",
318061da546Spatrick nullptr,
319061da546Spatrick 4,
320061da546Spatrick GPR_OFFSET(12),
321061da546Spatrick eEncodingUint,
322061da546Spatrick eFormatHex,
323061da546Spatrick {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
324061da546Spatrick gpr_r12},
325061da546Spatrick nullptr,
326061da546Spatrick nullptr,
327*f6aab3d8Srobert },
328061da546Spatrick {"sp",
329061da546Spatrick "r13",
330061da546Spatrick 4,
331061da546Spatrick GPR_OFFSET(13),
332061da546Spatrick eEncodingUint,
333061da546Spatrick eFormatHex,
334061da546Spatrick {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
335061da546Spatrick gpr_sp},
336061da546Spatrick nullptr,
337061da546Spatrick nullptr,
338*f6aab3d8Srobert },
339061da546Spatrick {"lr",
340061da546Spatrick "r14",
341061da546Spatrick 4,
342061da546Spatrick GPR_OFFSET(14),
343061da546Spatrick eEncodingUint,
344061da546Spatrick eFormatHex,
345061da546Spatrick {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,
346061da546Spatrick gpr_lr},
347061da546Spatrick nullptr,
348061da546Spatrick nullptr,
349*f6aab3d8Srobert },
350061da546Spatrick {"pc",
351061da546Spatrick "r15",
352061da546Spatrick 4,
353061da546Spatrick GPR_OFFSET(15),
354061da546Spatrick eEncodingUint,
355061da546Spatrick eFormatHex,
356061da546Spatrick {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
357061da546Spatrick gpr_pc},
358061da546Spatrick nullptr,
359061da546Spatrick nullptr,
360*f6aab3d8Srobert },
361061da546Spatrick {"cpsr",
362061da546Spatrick "psr",
363061da546Spatrick 4,
364061da546Spatrick GPR_OFFSET(16),
365061da546Spatrick eEncodingUint,
366061da546Spatrick eFormatHex,
367061da546Spatrick {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,
368061da546Spatrick gpr_cpsr},
369061da546Spatrick nullptr,
370061da546Spatrick nullptr,
371*f6aab3d8Srobert },
372061da546Spatrick
373061da546Spatrick {"s0",
374061da546Spatrick nullptr,
375061da546Spatrick 4,
376061da546Spatrick FPU_OFFSET(0),
377061da546Spatrick eEncodingIEEE754,
378061da546Spatrick eFormatFloat,
379061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
380061da546Spatrick fpu_s0},
381061da546Spatrick nullptr,
382061da546Spatrick nullptr,
383*f6aab3d8Srobert },
384061da546Spatrick {"s1",
385061da546Spatrick nullptr,
386061da546Spatrick 4,
387061da546Spatrick FPU_OFFSET(1),
388061da546Spatrick eEncodingIEEE754,
389061da546Spatrick eFormatFloat,
390061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
391061da546Spatrick fpu_s1},
392061da546Spatrick nullptr,
393061da546Spatrick nullptr,
394*f6aab3d8Srobert },
395061da546Spatrick {"s2",
396061da546Spatrick nullptr,
397061da546Spatrick 4,
398061da546Spatrick FPU_OFFSET(2),
399061da546Spatrick eEncodingIEEE754,
400061da546Spatrick eFormatFloat,
401061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
402061da546Spatrick fpu_s2},
403061da546Spatrick nullptr,
404061da546Spatrick nullptr,
405*f6aab3d8Srobert },
406061da546Spatrick {"s3",
407061da546Spatrick nullptr,
408061da546Spatrick 4,
409061da546Spatrick FPU_OFFSET(3),
410061da546Spatrick eEncodingIEEE754,
411061da546Spatrick eFormatFloat,
412061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
413061da546Spatrick fpu_s3},
414061da546Spatrick nullptr,
415061da546Spatrick nullptr,
416*f6aab3d8Srobert },
417061da546Spatrick {"s4",
418061da546Spatrick nullptr,
419061da546Spatrick 4,
420061da546Spatrick FPU_OFFSET(4),
421061da546Spatrick eEncodingIEEE754,
422061da546Spatrick eFormatFloat,
423061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
424061da546Spatrick fpu_s4},
425061da546Spatrick nullptr,
426061da546Spatrick nullptr,
427*f6aab3d8Srobert },
428061da546Spatrick {"s5",
429061da546Spatrick nullptr,
430061da546Spatrick 4,
431061da546Spatrick FPU_OFFSET(5),
432061da546Spatrick eEncodingIEEE754,
433061da546Spatrick eFormatFloat,
434061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
435061da546Spatrick fpu_s5},
436061da546Spatrick nullptr,
437061da546Spatrick nullptr,
438*f6aab3d8Srobert },
439061da546Spatrick {"s6",
440061da546Spatrick nullptr,
441061da546Spatrick 4,
442061da546Spatrick FPU_OFFSET(6),
443061da546Spatrick eEncodingIEEE754,
444061da546Spatrick eFormatFloat,
445061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
446061da546Spatrick fpu_s6},
447061da546Spatrick nullptr,
448061da546Spatrick nullptr,
449*f6aab3d8Srobert },
450061da546Spatrick {"s7",
451061da546Spatrick nullptr,
452061da546Spatrick 4,
453061da546Spatrick FPU_OFFSET(7),
454061da546Spatrick eEncodingIEEE754,
455061da546Spatrick eFormatFloat,
456061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
457061da546Spatrick fpu_s7},
458061da546Spatrick nullptr,
459061da546Spatrick nullptr,
460*f6aab3d8Srobert },
461061da546Spatrick {"s8",
462061da546Spatrick nullptr,
463061da546Spatrick 4,
464061da546Spatrick FPU_OFFSET(8),
465061da546Spatrick eEncodingIEEE754,
466061da546Spatrick eFormatFloat,
467061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
468061da546Spatrick fpu_s8},
469061da546Spatrick nullptr,
470061da546Spatrick nullptr,
471*f6aab3d8Srobert },
472061da546Spatrick {"s9",
473061da546Spatrick nullptr,
474061da546Spatrick 4,
475061da546Spatrick FPU_OFFSET(9),
476061da546Spatrick eEncodingIEEE754,
477061da546Spatrick eFormatFloat,
478061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
479061da546Spatrick fpu_s9},
480061da546Spatrick nullptr,
481061da546Spatrick nullptr,
482*f6aab3d8Srobert },
483061da546Spatrick {"s10",
484061da546Spatrick nullptr,
485061da546Spatrick 4,
486061da546Spatrick FPU_OFFSET(10),
487061da546Spatrick eEncodingIEEE754,
488061da546Spatrick eFormatFloat,
489061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
490061da546Spatrick fpu_s10},
491061da546Spatrick nullptr,
492061da546Spatrick nullptr,
493*f6aab3d8Srobert },
494061da546Spatrick {"s11",
495061da546Spatrick nullptr,
496061da546Spatrick 4,
497061da546Spatrick FPU_OFFSET(11),
498061da546Spatrick eEncodingIEEE754,
499061da546Spatrick eFormatFloat,
500061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
501061da546Spatrick fpu_s11},
502061da546Spatrick nullptr,
503061da546Spatrick nullptr,
504*f6aab3d8Srobert },
505061da546Spatrick {"s12",
506061da546Spatrick nullptr,
507061da546Spatrick 4,
508061da546Spatrick FPU_OFFSET(12),
509061da546Spatrick eEncodingIEEE754,
510061da546Spatrick eFormatFloat,
511061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
512061da546Spatrick fpu_s12},
513061da546Spatrick nullptr,
514061da546Spatrick nullptr,
515*f6aab3d8Srobert },
516061da546Spatrick {"s13",
517061da546Spatrick nullptr,
518061da546Spatrick 4,
519061da546Spatrick FPU_OFFSET(13),
520061da546Spatrick eEncodingIEEE754,
521061da546Spatrick eFormatFloat,
522061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
523061da546Spatrick fpu_s13},
524061da546Spatrick nullptr,
525061da546Spatrick nullptr,
526*f6aab3d8Srobert },
527061da546Spatrick {"s14",
528061da546Spatrick nullptr,
529061da546Spatrick 4,
530061da546Spatrick FPU_OFFSET(14),
531061da546Spatrick eEncodingIEEE754,
532061da546Spatrick eFormatFloat,
533061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
534061da546Spatrick fpu_s14},
535061da546Spatrick nullptr,
536061da546Spatrick nullptr,
537*f6aab3d8Srobert },
538061da546Spatrick {"s15",
539061da546Spatrick nullptr,
540061da546Spatrick 4,
541061da546Spatrick FPU_OFFSET(15),
542061da546Spatrick eEncodingIEEE754,
543061da546Spatrick eFormatFloat,
544061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
545061da546Spatrick fpu_s15},
546061da546Spatrick nullptr,
547061da546Spatrick nullptr,
548*f6aab3d8Srobert },
549061da546Spatrick {"s16",
550061da546Spatrick nullptr,
551061da546Spatrick 4,
552061da546Spatrick FPU_OFFSET(16),
553061da546Spatrick eEncodingIEEE754,
554061da546Spatrick eFormatFloat,
555061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
556061da546Spatrick fpu_s16},
557061da546Spatrick nullptr,
558061da546Spatrick nullptr,
559*f6aab3d8Srobert },
560061da546Spatrick {"s17",
561061da546Spatrick nullptr,
562061da546Spatrick 4,
563061da546Spatrick FPU_OFFSET(17),
564061da546Spatrick eEncodingIEEE754,
565061da546Spatrick eFormatFloat,
566061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
567061da546Spatrick fpu_s17},
568061da546Spatrick nullptr,
569061da546Spatrick nullptr,
570*f6aab3d8Srobert },
571061da546Spatrick {"s18",
572061da546Spatrick nullptr,
573061da546Spatrick 4,
574061da546Spatrick FPU_OFFSET(18),
575061da546Spatrick eEncodingIEEE754,
576061da546Spatrick eFormatFloat,
577061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
578061da546Spatrick fpu_s18},
579061da546Spatrick nullptr,
580061da546Spatrick nullptr,
581*f6aab3d8Srobert },
582061da546Spatrick {"s19",
583061da546Spatrick nullptr,
584061da546Spatrick 4,
585061da546Spatrick FPU_OFFSET(19),
586061da546Spatrick eEncodingIEEE754,
587061da546Spatrick eFormatFloat,
588061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
589061da546Spatrick fpu_s19},
590061da546Spatrick nullptr,
591061da546Spatrick nullptr,
592*f6aab3d8Srobert },
593061da546Spatrick {"s20",
594061da546Spatrick nullptr,
595061da546Spatrick 4,
596061da546Spatrick FPU_OFFSET(20),
597061da546Spatrick eEncodingIEEE754,
598061da546Spatrick eFormatFloat,
599061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
600061da546Spatrick fpu_s20},
601061da546Spatrick nullptr,
602061da546Spatrick nullptr,
603*f6aab3d8Srobert },
604061da546Spatrick {"s21",
605061da546Spatrick nullptr,
606061da546Spatrick 4,
607061da546Spatrick FPU_OFFSET(21),
608061da546Spatrick eEncodingIEEE754,
609061da546Spatrick eFormatFloat,
610061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
611061da546Spatrick fpu_s21},
612061da546Spatrick nullptr,
613061da546Spatrick nullptr,
614*f6aab3d8Srobert },
615061da546Spatrick {"s22",
616061da546Spatrick nullptr,
617061da546Spatrick 4,
618061da546Spatrick FPU_OFFSET(22),
619061da546Spatrick eEncodingIEEE754,
620061da546Spatrick eFormatFloat,
621061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
622061da546Spatrick fpu_s22},
623061da546Spatrick nullptr,
624061da546Spatrick nullptr,
625*f6aab3d8Srobert },
626061da546Spatrick {"s23",
627061da546Spatrick nullptr,
628061da546Spatrick 4,
629061da546Spatrick FPU_OFFSET(23),
630061da546Spatrick eEncodingIEEE754,
631061da546Spatrick eFormatFloat,
632061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
633061da546Spatrick fpu_s23},
634061da546Spatrick nullptr,
635061da546Spatrick nullptr,
636*f6aab3d8Srobert },
637061da546Spatrick {"s24",
638061da546Spatrick nullptr,
639061da546Spatrick 4,
640061da546Spatrick FPU_OFFSET(24),
641061da546Spatrick eEncodingIEEE754,
642061da546Spatrick eFormatFloat,
643061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
644061da546Spatrick fpu_s24},
645061da546Spatrick nullptr,
646061da546Spatrick nullptr,
647*f6aab3d8Srobert },
648061da546Spatrick {"s25",
649061da546Spatrick nullptr,
650061da546Spatrick 4,
651061da546Spatrick FPU_OFFSET(25),
652061da546Spatrick eEncodingIEEE754,
653061da546Spatrick eFormatFloat,
654061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
655061da546Spatrick fpu_s25},
656061da546Spatrick nullptr,
657061da546Spatrick nullptr,
658*f6aab3d8Srobert },
659061da546Spatrick {"s26",
660061da546Spatrick nullptr,
661061da546Spatrick 4,
662061da546Spatrick FPU_OFFSET(26),
663061da546Spatrick eEncodingIEEE754,
664061da546Spatrick eFormatFloat,
665061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
666061da546Spatrick fpu_s26},
667061da546Spatrick nullptr,
668061da546Spatrick nullptr,
669*f6aab3d8Srobert },
670061da546Spatrick {"s27",
671061da546Spatrick nullptr,
672061da546Spatrick 4,
673061da546Spatrick FPU_OFFSET(27),
674061da546Spatrick eEncodingIEEE754,
675061da546Spatrick eFormatFloat,
676061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
677061da546Spatrick fpu_s27},
678061da546Spatrick nullptr,
679061da546Spatrick nullptr,
680*f6aab3d8Srobert },
681061da546Spatrick {"s28",
682061da546Spatrick nullptr,
683061da546Spatrick 4,
684061da546Spatrick FPU_OFFSET(28),
685061da546Spatrick eEncodingIEEE754,
686061da546Spatrick eFormatFloat,
687061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
688061da546Spatrick fpu_s28},
689061da546Spatrick nullptr,
690061da546Spatrick nullptr,
691*f6aab3d8Srobert },
692061da546Spatrick {"s29",
693061da546Spatrick nullptr,
694061da546Spatrick 4,
695061da546Spatrick FPU_OFFSET(29),
696061da546Spatrick eEncodingIEEE754,
697061da546Spatrick eFormatFloat,
698061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
699061da546Spatrick fpu_s29},
700061da546Spatrick nullptr,
701061da546Spatrick nullptr,
702*f6aab3d8Srobert },
703061da546Spatrick {"s30",
704061da546Spatrick nullptr,
705061da546Spatrick 4,
706061da546Spatrick FPU_OFFSET(30),
707061da546Spatrick eEncodingIEEE754,
708061da546Spatrick eFormatFloat,
709061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
710061da546Spatrick fpu_s30},
711061da546Spatrick nullptr,
712061da546Spatrick nullptr,
713*f6aab3d8Srobert },
714061da546Spatrick {"s31",
715061da546Spatrick nullptr,
716061da546Spatrick 4,
717061da546Spatrick FPU_OFFSET(31),
718061da546Spatrick eEncodingIEEE754,
719061da546Spatrick eFormatFloat,
720061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
721061da546Spatrick fpu_s31},
722061da546Spatrick nullptr,
723061da546Spatrick nullptr,
724*f6aab3d8Srobert },
725061da546Spatrick {"fpscr",
726061da546Spatrick nullptr,
727061da546Spatrick 4,
728061da546Spatrick FPU_OFFSET(32),
729061da546Spatrick eEncodingUint,
730061da546Spatrick eFormatHex,
731061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
732061da546Spatrick LLDB_INVALID_REGNUM, fpu_fpscr},
733061da546Spatrick nullptr,
734061da546Spatrick nullptr,
735*f6aab3d8Srobert },
736061da546Spatrick
737061da546Spatrick {"exception",
738061da546Spatrick nullptr,
739061da546Spatrick 4,
740061da546Spatrick EXC_OFFSET(0),
741061da546Spatrick eEncodingUint,
742061da546Spatrick eFormatHex,
743061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
744061da546Spatrick LLDB_INVALID_REGNUM, exc_exception},
745061da546Spatrick nullptr,
746061da546Spatrick nullptr,
747*f6aab3d8Srobert },
748061da546Spatrick {"fsr",
749061da546Spatrick nullptr,
750061da546Spatrick 4,
751061da546Spatrick EXC_OFFSET(1),
752061da546Spatrick eEncodingUint,
753061da546Spatrick eFormatHex,
754061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
755061da546Spatrick LLDB_INVALID_REGNUM, exc_fsr},
756061da546Spatrick nullptr,
757061da546Spatrick nullptr,
758*f6aab3d8Srobert },
759061da546Spatrick {"far",
760061da546Spatrick nullptr,
761061da546Spatrick 4,
762061da546Spatrick EXC_OFFSET(2),
763061da546Spatrick eEncodingUint,
764061da546Spatrick eFormatHex,
765061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
766061da546Spatrick LLDB_INVALID_REGNUM, exc_far},
767061da546Spatrick nullptr,
768061da546Spatrick nullptr,
769*f6aab3d8Srobert },
770061da546Spatrick
771061da546Spatrick {DEFINE_DBG(bvr, 0)},
772061da546Spatrick {DEFINE_DBG(bvr, 1)},
773061da546Spatrick {DEFINE_DBG(bvr, 2)},
774061da546Spatrick {DEFINE_DBG(bvr, 3)},
775061da546Spatrick {DEFINE_DBG(bvr, 4)},
776061da546Spatrick {DEFINE_DBG(bvr, 5)},
777061da546Spatrick {DEFINE_DBG(bvr, 6)},
778061da546Spatrick {DEFINE_DBG(bvr, 7)},
779061da546Spatrick {DEFINE_DBG(bvr, 8)},
780061da546Spatrick {DEFINE_DBG(bvr, 9)},
781061da546Spatrick {DEFINE_DBG(bvr, 10)},
782061da546Spatrick {DEFINE_DBG(bvr, 11)},
783061da546Spatrick {DEFINE_DBG(bvr, 12)},
784061da546Spatrick {DEFINE_DBG(bvr, 13)},
785061da546Spatrick {DEFINE_DBG(bvr, 14)},
786061da546Spatrick {DEFINE_DBG(bvr, 15)},
787061da546Spatrick
788061da546Spatrick {DEFINE_DBG(bcr, 0)},
789061da546Spatrick {DEFINE_DBG(bcr, 1)},
790061da546Spatrick {DEFINE_DBG(bcr, 2)},
791061da546Spatrick {DEFINE_DBG(bcr, 3)},
792061da546Spatrick {DEFINE_DBG(bcr, 4)},
793061da546Spatrick {DEFINE_DBG(bcr, 5)},
794061da546Spatrick {DEFINE_DBG(bcr, 6)},
795061da546Spatrick {DEFINE_DBG(bcr, 7)},
796061da546Spatrick {DEFINE_DBG(bcr, 8)},
797061da546Spatrick {DEFINE_DBG(bcr, 9)},
798061da546Spatrick {DEFINE_DBG(bcr, 10)},
799061da546Spatrick {DEFINE_DBG(bcr, 11)},
800061da546Spatrick {DEFINE_DBG(bcr, 12)},
801061da546Spatrick {DEFINE_DBG(bcr, 13)},
802061da546Spatrick {DEFINE_DBG(bcr, 14)},
803061da546Spatrick {DEFINE_DBG(bcr, 15)},
804061da546Spatrick
805061da546Spatrick {DEFINE_DBG(wvr, 0)},
806061da546Spatrick {DEFINE_DBG(wvr, 1)},
807061da546Spatrick {DEFINE_DBG(wvr, 2)},
808061da546Spatrick {DEFINE_DBG(wvr, 3)},
809061da546Spatrick {DEFINE_DBG(wvr, 4)},
810061da546Spatrick {DEFINE_DBG(wvr, 5)},
811061da546Spatrick {DEFINE_DBG(wvr, 6)},
812061da546Spatrick {DEFINE_DBG(wvr, 7)},
813061da546Spatrick {DEFINE_DBG(wvr, 8)},
814061da546Spatrick {DEFINE_DBG(wvr, 9)},
815061da546Spatrick {DEFINE_DBG(wvr, 10)},
816061da546Spatrick {DEFINE_DBG(wvr, 11)},
817061da546Spatrick {DEFINE_DBG(wvr, 12)},
818061da546Spatrick {DEFINE_DBG(wvr, 13)},
819061da546Spatrick {DEFINE_DBG(wvr, 14)},
820061da546Spatrick {DEFINE_DBG(wvr, 15)},
821061da546Spatrick
822061da546Spatrick {DEFINE_DBG(wcr, 0)},
823061da546Spatrick {DEFINE_DBG(wcr, 1)},
824061da546Spatrick {DEFINE_DBG(wcr, 2)},
825061da546Spatrick {DEFINE_DBG(wcr, 3)},
826061da546Spatrick {DEFINE_DBG(wcr, 4)},
827061da546Spatrick {DEFINE_DBG(wcr, 5)},
828061da546Spatrick {DEFINE_DBG(wcr, 6)},
829061da546Spatrick {DEFINE_DBG(wcr, 7)},
830061da546Spatrick {DEFINE_DBG(wcr, 8)},
831061da546Spatrick {DEFINE_DBG(wcr, 9)},
832061da546Spatrick {DEFINE_DBG(wcr, 10)},
833061da546Spatrick {DEFINE_DBG(wcr, 11)},
834061da546Spatrick {DEFINE_DBG(wcr, 12)},
835061da546Spatrick {DEFINE_DBG(wcr, 13)},
836061da546Spatrick {DEFINE_DBG(wcr, 14)},
837061da546Spatrick {DEFINE_DBG(wcr, 15)}};
838061da546Spatrick
839061da546Spatrick // General purpose registers
840061da546Spatrick static uint32_t g_gpr_regnums[] = {
841061da546Spatrick gpr_r0, gpr_r1, gpr_r2, gpr_r3, gpr_r4, gpr_r5, gpr_r6, gpr_r7, gpr_r8,
842061da546Spatrick gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr};
843061da546Spatrick
844061da546Spatrick // Floating point registers
845061da546Spatrick static uint32_t g_fpu_regnums[] = {
846061da546Spatrick fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6,
847061da546Spatrick fpu_s7, fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13,
848061da546Spatrick fpu_s14, fpu_s15, fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20,
849061da546Spatrick fpu_s21, fpu_s22, fpu_s23, fpu_s24, fpu_s25, fpu_s26, fpu_s27,
850061da546Spatrick fpu_s28, fpu_s29, fpu_s30, fpu_s31, fpu_fpscr,
851061da546Spatrick };
852061da546Spatrick
853061da546Spatrick // Exception registers
854061da546Spatrick
855061da546Spatrick static uint32_t g_exc_regnums[] = {
856061da546Spatrick exc_exception, exc_fsr, exc_far,
857061da546Spatrick };
858061da546Spatrick
859*f6aab3d8Srobert static size_t k_num_register_infos = std::size(g_register_infos);
860061da546Spatrick
RegisterContextDarwin_arm(Thread & thread,uint32_t concrete_frame_idx)861061da546Spatrick RegisterContextDarwin_arm::RegisterContextDarwin_arm(
862061da546Spatrick Thread &thread, uint32_t concrete_frame_idx)
863061da546Spatrick : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
864061da546Spatrick uint32_t i;
865061da546Spatrick for (i = 0; i < kNumErrors; i++) {
866061da546Spatrick gpr_errs[i] = -1;
867061da546Spatrick fpu_errs[i] = -1;
868061da546Spatrick exc_errs[i] = -1;
869061da546Spatrick }
870061da546Spatrick }
871061da546Spatrick
872be691f3bSpatrick RegisterContextDarwin_arm::~RegisterContextDarwin_arm() = default;
873061da546Spatrick
InvalidateAllRegisters()874061da546Spatrick void RegisterContextDarwin_arm::InvalidateAllRegisters() {
875061da546Spatrick InvalidateAllRegisterStates();
876061da546Spatrick }
877061da546Spatrick
GetRegisterCount()878061da546Spatrick size_t RegisterContextDarwin_arm::GetRegisterCount() {
879061da546Spatrick assert(k_num_register_infos == k_num_registers);
880061da546Spatrick return k_num_registers;
881061da546Spatrick }
882061da546Spatrick
883061da546Spatrick const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)884061da546Spatrick RegisterContextDarwin_arm::GetRegisterInfoAtIndex(size_t reg) {
885061da546Spatrick assert(k_num_register_infos == k_num_registers);
886061da546Spatrick if (reg < k_num_registers)
887061da546Spatrick return &g_register_infos[reg];
888061da546Spatrick return nullptr;
889061da546Spatrick }
890061da546Spatrick
GetRegisterInfosCount()891061da546Spatrick size_t RegisterContextDarwin_arm::GetRegisterInfosCount() {
892061da546Spatrick return k_num_register_infos;
893061da546Spatrick }
894061da546Spatrick
GetRegisterInfos()895061da546Spatrick const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() {
896061da546Spatrick return g_register_infos;
897061da546Spatrick }
898061da546Spatrick
899061da546Spatrick // Number of registers in each register set
900*f6aab3d8Srobert const size_t k_num_gpr_registers = std::size(g_gpr_regnums);
901*f6aab3d8Srobert const size_t k_num_fpu_registers = std::size(g_fpu_regnums);
902*f6aab3d8Srobert const size_t k_num_exc_registers = std::size(g_exc_regnums);
903061da546Spatrick
904061da546Spatrick // Register set definitions. The first definitions at register set index of
905061da546Spatrick // zero is for all registers, followed by other registers sets. The register
906061da546Spatrick // information for the all register set need not be filled in.
907061da546Spatrick static const RegisterSet g_reg_sets[] = {
908061da546Spatrick {
909061da546Spatrick "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
910061da546Spatrick },
911061da546Spatrick {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
912061da546Spatrick {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
913061da546Spatrick
914*f6aab3d8Srobert const size_t k_num_regsets = std::size(g_reg_sets);
915061da546Spatrick
GetRegisterSetCount()916061da546Spatrick size_t RegisterContextDarwin_arm::GetRegisterSetCount() {
917061da546Spatrick return k_num_regsets;
918061da546Spatrick }
919061da546Spatrick
GetRegisterSet(size_t reg_set)920061da546Spatrick const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) {
921061da546Spatrick if (reg_set < k_num_regsets)
922061da546Spatrick return &g_reg_sets[reg_set];
923061da546Spatrick return nullptr;
924061da546Spatrick }
925061da546Spatrick
926061da546Spatrick // Register information definitions for 32 bit i386.
GetSetForNativeRegNum(int reg)927061da546Spatrick int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) {
928061da546Spatrick if (reg < fpu_s0)
929061da546Spatrick return GPRRegSet;
930061da546Spatrick else if (reg < exc_exception)
931061da546Spatrick return FPURegSet;
932061da546Spatrick else if (reg < k_num_registers)
933061da546Spatrick return EXCRegSet;
934061da546Spatrick return -1;
935061da546Spatrick }
936061da546Spatrick
ReadGPR(bool force)937061da546Spatrick int RegisterContextDarwin_arm::ReadGPR(bool force) {
938061da546Spatrick int set = GPRRegSet;
939061da546Spatrick if (force || !RegisterSetIsCached(set)) {
940061da546Spatrick SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
941061da546Spatrick }
942061da546Spatrick return GetError(GPRRegSet, Read);
943061da546Spatrick }
944061da546Spatrick
ReadFPU(bool force)945061da546Spatrick int RegisterContextDarwin_arm::ReadFPU(bool force) {
946061da546Spatrick int set = FPURegSet;
947061da546Spatrick if (force || !RegisterSetIsCached(set)) {
948061da546Spatrick SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
949061da546Spatrick }
950061da546Spatrick return GetError(FPURegSet, Read);
951061da546Spatrick }
952061da546Spatrick
ReadEXC(bool force)953061da546Spatrick int RegisterContextDarwin_arm::ReadEXC(bool force) {
954061da546Spatrick int set = EXCRegSet;
955061da546Spatrick if (force || !RegisterSetIsCached(set)) {
956061da546Spatrick SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
957061da546Spatrick }
958061da546Spatrick return GetError(EXCRegSet, Read);
959061da546Spatrick }
960061da546Spatrick
ReadDBG(bool force)961061da546Spatrick int RegisterContextDarwin_arm::ReadDBG(bool force) {
962061da546Spatrick int set = DBGRegSet;
963061da546Spatrick if (force || !RegisterSetIsCached(set)) {
964061da546Spatrick SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
965061da546Spatrick }
966061da546Spatrick return GetError(DBGRegSet, Read);
967061da546Spatrick }
968061da546Spatrick
WriteGPR()969061da546Spatrick int RegisterContextDarwin_arm::WriteGPR() {
970061da546Spatrick int set = GPRRegSet;
971061da546Spatrick if (!RegisterSetIsCached(set)) {
972061da546Spatrick SetError(set, Write, -1);
973061da546Spatrick return KERN_INVALID_ARGUMENT;
974061da546Spatrick }
975061da546Spatrick SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
976061da546Spatrick SetError(set, Read, -1);
977061da546Spatrick return GetError(GPRRegSet, Write);
978061da546Spatrick }
979061da546Spatrick
WriteFPU()980061da546Spatrick int RegisterContextDarwin_arm::WriteFPU() {
981061da546Spatrick int set = FPURegSet;
982061da546Spatrick if (!RegisterSetIsCached(set)) {
983061da546Spatrick SetError(set, Write, -1);
984061da546Spatrick return KERN_INVALID_ARGUMENT;
985061da546Spatrick }
986061da546Spatrick SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
987061da546Spatrick SetError(set, Read, -1);
988061da546Spatrick return GetError(FPURegSet, Write);
989061da546Spatrick }
990061da546Spatrick
WriteEXC()991061da546Spatrick int RegisterContextDarwin_arm::WriteEXC() {
992061da546Spatrick int set = EXCRegSet;
993061da546Spatrick if (!RegisterSetIsCached(set)) {
994061da546Spatrick SetError(set, Write, -1);
995061da546Spatrick return KERN_INVALID_ARGUMENT;
996061da546Spatrick }
997061da546Spatrick SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
998061da546Spatrick SetError(set, Read, -1);
999061da546Spatrick return GetError(EXCRegSet, Write);
1000061da546Spatrick }
1001061da546Spatrick
WriteDBG()1002061da546Spatrick int RegisterContextDarwin_arm::WriteDBG() {
1003061da546Spatrick int set = DBGRegSet;
1004061da546Spatrick if (!RegisterSetIsCached(set)) {
1005061da546Spatrick SetError(set, Write, -1);
1006061da546Spatrick return KERN_INVALID_ARGUMENT;
1007061da546Spatrick }
1008061da546Spatrick SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));
1009061da546Spatrick SetError(set, Read, -1);
1010061da546Spatrick return GetError(DBGRegSet, Write);
1011061da546Spatrick }
1012061da546Spatrick
ReadRegisterSet(uint32_t set,bool force)1013061da546Spatrick int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) {
1014061da546Spatrick switch (set) {
1015061da546Spatrick case GPRRegSet:
1016061da546Spatrick return ReadGPR(force);
1017061da546Spatrick case GPRAltRegSet:
1018061da546Spatrick return ReadGPR(force);
1019061da546Spatrick case FPURegSet:
1020061da546Spatrick return ReadFPU(force);
1021061da546Spatrick case EXCRegSet:
1022061da546Spatrick return ReadEXC(force);
1023061da546Spatrick case DBGRegSet:
1024061da546Spatrick return ReadDBG(force);
1025061da546Spatrick default:
1026061da546Spatrick break;
1027061da546Spatrick }
1028061da546Spatrick return KERN_INVALID_ARGUMENT;
1029061da546Spatrick }
1030061da546Spatrick
WriteRegisterSet(uint32_t set)1031061da546Spatrick int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {
1032061da546Spatrick // Make sure we have a valid context to set.
1033061da546Spatrick if (RegisterSetIsCached(set)) {
1034061da546Spatrick switch (set) {
1035061da546Spatrick case GPRRegSet:
1036061da546Spatrick return WriteGPR();
1037061da546Spatrick case GPRAltRegSet:
1038061da546Spatrick return WriteGPR();
1039061da546Spatrick case FPURegSet:
1040061da546Spatrick return WriteFPU();
1041061da546Spatrick case EXCRegSet:
1042061da546Spatrick return WriteEXC();
1043061da546Spatrick case DBGRegSet:
1044061da546Spatrick return WriteDBG();
1045061da546Spatrick default:
1046061da546Spatrick break;
1047061da546Spatrick }
1048061da546Spatrick }
1049061da546Spatrick return KERN_INVALID_ARGUMENT;
1050061da546Spatrick }
1051061da546Spatrick
LogDBGRegisters(Log * log,const DBG & dbg)1052061da546Spatrick void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {
1053061da546Spatrick if (log) {
1054061da546Spatrick for (uint32_t i = 0; i < 16; i++)
1055061da546Spatrick LLDB_LOGF(log,
1056061da546Spatrick "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "
1057061da546Spatrick "0x%8.8x, 0x%8.8x }",
1058061da546Spatrick i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);
1059061da546Spatrick }
1060061da546Spatrick }
1061061da546Spatrick
ReadRegister(const RegisterInfo * reg_info,RegisterValue & value)1062061da546Spatrick bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info,
1063061da546Spatrick RegisterValue &value) {
1064061da546Spatrick const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1065061da546Spatrick int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg);
1066061da546Spatrick
1067061da546Spatrick if (set == -1)
1068061da546Spatrick return false;
1069061da546Spatrick
1070061da546Spatrick if (ReadRegisterSet(set, false) != KERN_SUCCESS)
1071061da546Spatrick return false;
1072061da546Spatrick
1073061da546Spatrick switch (reg) {
1074061da546Spatrick case gpr_r0:
1075061da546Spatrick case gpr_r1:
1076061da546Spatrick case gpr_r2:
1077061da546Spatrick case gpr_r3:
1078061da546Spatrick case gpr_r4:
1079061da546Spatrick case gpr_r5:
1080061da546Spatrick case gpr_r6:
1081061da546Spatrick case gpr_r7:
1082061da546Spatrick case gpr_r8:
1083061da546Spatrick case gpr_r9:
1084061da546Spatrick case gpr_r10:
1085061da546Spatrick case gpr_r11:
1086061da546Spatrick case gpr_r12:
1087061da546Spatrick case gpr_sp:
1088061da546Spatrick case gpr_lr:
1089061da546Spatrick case gpr_pc:
1090061da546Spatrick value.SetUInt32(gpr.r[reg - gpr_r0]);
1091061da546Spatrick break;
1092061da546Spatrick case gpr_cpsr:
1093061da546Spatrick value.SetUInt32(gpr.cpsr);
1094061da546Spatrick break;
1095061da546Spatrick case fpu_s0:
1096061da546Spatrick case fpu_s1:
1097061da546Spatrick case fpu_s2:
1098061da546Spatrick case fpu_s3:
1099061da546Spatrick case fpu_s4:
1100061da546Spatrick case fpu_s5:
1101061da546Spatrick case fpu_s6:
1102061da546Spatrick case fpu_s7:
1103061da546Spatrick case fpu_s8:
1104061da546Spatrick case fpu_s9:
1105061da546Spatrick case fpu_s10:
1106061da546Spatrick case fpu_s11:
1107061da546Spatrick case fpu_s12:
1108061da546Spatrick case fpu_s13:
1109061da546Spatrick case fpu_s14:
1110061da546Spatrick case fpu_s15:
1111061da546Spatrick case fpu_s16:
1112061da546Spatrick case fpu_s17:
1113061da546Spatrick case fpu_s18:
1114061da546Spatrick case fpu_s19:
1115061da546Spatrick case fpu_s20:
1116061da546Spatrick case fpu_s21:
1117061da546Spatrick case fpu_s22:
1118061da546Spatrick case fpu_s23:
1119061da546Spatrick case fpu_s24:
1120061da546Spatrick case fpu_s25:
1121061da546Spatrick case fpu_s26:
1122061da546Spatrick case fpu_s27:
1123061da546Spatrick case fpu_s28:
1124061da546Spatrick case fpu_s29:
1125061da546Spatrick case fpu_s30:
1126061da546Spatrick case fpu_s31:
1127061da546Spatrick value.SetUInt32(fpu.floats.s[reg], RegisterValue::eTypeFloat);
1128061da546Spatrick break;
1129061da546Spatrick
1130061da546Spatrick case fpu_fpscr:
1131061da546Spatrick value.SetUInt32(fpu.fpscr);
1132061da546Spatrick break;
1133061da546Spatrick
1134061da546Spatrick case exc_exception:
1135061da546Spatrick value.SetUInt32(exc.exception);
1136061da546Spatrick break;
1137061da546Spatrick case exc_fsr:
1138061da546Spatrick value.SetUInt32(exc.fsr);
1139061da546Spatrick break;
1140061da546Spatrick case exc_far:
1141061da546Spatrick value.SetUInt32(exc.far);
1142061da546Spatrick break;
1143061da546Spatrick
1144061da546Spatrick default:
1145061da546Spatrick value.SetValueToInvalid();
1146061da546Spatrick return false;
1147061da546Spatrick }
1148061da546Spatrick return true;
1149061da546Spatrick }
1150061da546Spatrick
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & value)1151061da546Spatrick bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info,
1152061da546Spatrick const RegisterValue &value) {
1153061da546Spatrick const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
1154061da546Spatrick int set = GetSetForNativeRegNum(reg);
1155061da546Spatrick
1156061da546Spatrick if (set == -1)
1157061da546Spatrick return false;
1158061da546Spatrick
1159061da546Spatrick if (ReadRegisterSet(set, false) != KERN_SUCCESS)
1160061da546Spatrick return false;
1161061da546Spatrick
1162061da546Spatrick switch (reg) {
1163061da546Spatrick case gpr_r0:
1164061da546Spatrick case gpr_r1:
1165061da546Spatrick case gpr_r2:
1166061da546Spatrick case gpr_r3:
1167061da546Spatrick case gpr_r4:
1168061da546Spatrick case gpr_r5:
1169061da546Spatrick case gpr_r6:
1170061da546Spatrick case gpr_r7:
1171061da546Spatrick case gpr_r8:
1172061da546Spatrick case gpr_r9:
1173061da546Spatrick case gpr_r10:
1174061da546Spatrick case gpr_r11:
1175061da546Spatrick case gpr_r12:
1176061da546Spatrick case gpr_sp:
1177061da546Spatrick case gpr_lr:
1178061da546Spatrick case gpr_pc:
1179061da546Spatrick case gpr_cpsr:
1180061da546Spatrick gpr.r[reg - gpr_r0] = value.GetAsUInt32();
1181061da546Spatrick break;
1182061da546Spatrick
1183061da546Spatrick case fpu_s0:
1184061da546Spatrick case fpu_s1:
1185061da546Spatrick case fpu_s2:
1186061da546Spatrick case fpu_s3:
1187061da546Spatrick case fpu_s4:
1188061da546Spatrick case fpu_s5:
1189061da546Spatrick case fpu_s6:
1190061da546Spatrick case fpu_s7:
1191061da546Spatrick case fpu_s8:
1192061da546Spatrick case fpu_s9:
1193061da546Spatrick case fpu_s10:
1194061da546Spatrick case fpu_s11:
1195061da546Spatrick case fpu_s12:
1196061da546Spatrick case fpu_s13:
1197061da546Spatrick case fpu_s14:
1198061da546Spatrick case fpu_s15:
1199061da546Spatrick case fpu_s16:
1200061da546Spatrick case fpu_s17:
1201061da546Spatrick case fpu_s18:
1202061da546Spatrick case fpu_s19:
1203061da546Spatrick case fpu_s20:
1204061da546Spatrick case fpu_s21:
1205061da546Spatrick case fpu_s22:
1206061da546Spatrick case fpu_s23:
1207061da546Spatrick case fpu_s24:
1208061da546Spatrick case fpu_s25:
1209061da546Spatrick case fpu_s26:
1210061da546Spatrick case fpu_s27:
1211061da546Spatrick case fpu_s28:
1212061da546Spatrick case fpu_s29:
1213061da546Spatrick case fpu_s30:
1214061da546Spatrick case fpu_s31:
1215061da546Spatrick fpu.floats.s[reg] = value.GetAsUInt32();
1216061da546Spatrick break;
1217061da546Spatrick
1218061da546Spatrick case fpu_fpscr:
1219061da546Spatrick fpu.fpscr = value.GetAsUInt32();
1220061da546Spatrick break;
1221061da546Spatrick
1222061da546Spatrick case exc_exception:
1223061da546Spatrick exc.exception = value.GetAsUInt32();
1224061da546Spatrick break;
1225061da546Spatrick case exc_fsr:
1226061da546Spatrick exc.fsr = value.GetAsUInt32();
1227061da546Spatrick break;
1228061da546Spatrick case exc_far:
1229061da546Spatrick exc.far = value.GetAsUInt32();
1230061da546Spatrick break;
1231061da546Spatrick
1232061da546Spatrick default:
1233061da546Spatrick return false;
1234061da546Spatrick }
1235061da546Spatrick return WriteRegisterSet(set) == KERN_SUCCESS;
1236061da546Spatrick }
1237061da546Spatrick
ReadAllRegisterValues(lldb::WritableDataBufferSP & data_sp)1238061da546Spatrick bool RegisterContextDarwin_arm::ReadAllRegisterValues(
1239*f6aab3d8Srobert lldb::WritableDataBufferSP &data_sp) {
1240061da546Spatrick data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);
1241061da546Spatrick if (data_sp && ReadGPR(false) == KERN_SUCCESS &&
1242061da546Spatrick ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {
1243061da546Spatrick uint8_t *dst = data_sp->GetBytes();
1244061da546Spatrick ::memcpy(dst, &gpr, sizeof(gpr));
1245061da546Spatrick dst += sizeof(gpr);
1246061da546Spatrick
1247061da546Spatrick ::memcpy(dst, &fpu, sizeof(fpu));
1248061da546Spatrick dst += sizeof(gpr);
1249061da546Spatrick
1250061da546Spatrick ::memcpy(dst, &exc, sizeof(exc));
1251061da546Spatrick return true;
1252061da546Spatrick }
1253061da546Spatrick return false;
1254061da546Spatrick }
1255061da546Spatrick
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)1256061da546Spatrick bool RegisterContextDarwin_arm::WriteAllRegisterValues(
1257061da546Spatrick const lldb::DataBufferSP &data_sp) {
1258061da546Spatrick if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
1259061da546Spatrick const uint8_t *src = data_sp->GetBytes();
1260061da546Spatrick ::memcpy(&gpr, src, sizeof(gpr));
1261061da546Spatrick src += sizeof(gpr);
1262061da546Spatrick
1263061da546Spatrick ::memcpy(&fpu, src, sizeof(fpu));
1264061da546Spatrick src += sizeof(gpr);
1265061da546Spatrick
1266061da546Spatrick ::memcpy(&exc, src, sizeof(exc));
1267061da546Spatrick uint32_t success_count = 0;
1268061da546Spatrick if (WriteGPR() == KERN_SUCCESS)
1269061da546Spatrick ++success_count;
1270061da546Spatrick if (WriteFPU() == KERN_SUCCESS)
1271061da546Spatrick ++success_count;
1272061da546Spatrick if (WriteEXC() == KERN_SUCCESS)
1273061da546Spatrick ++success_count;
1274061da546Spatrick return success_count == 3;
1275061da546Spatrick }
1276061da546Spatrick return false;
1277061da546Spatrick }
1278061da546Spatrick
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t reg)1279061da546Spatrick uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(
1280061da546Spatrick lldb::RegisterKind kind, uint32_t reg) {
1281061da546Spatrick if (kind == eRegisterKindGeneric) {
1282061da546Spatrick switch (reg) {
1283061da546Spatrick case LLDB_REGNUM_GENERIC_PC:
1284061da546Spatrick return gpr_pc;
1285061da546Spatrick case LLDB_REGNUM_GENERIC_SP:
1286061da546Spatrick return gpr_sp;
1287061da546Spatrick case LLDB_REGNUM_GENERIC_FP:
1288061da546Spatrick return gpr_r7;
1289061da546Spatrick case LLDB_REGNUM_GENERIC_RA:
1290061da546Spatrick return gpr_lr;
1291061da546Spatrick case LLDB_REGNUM_GENERIC_FLAGS:
1292061da546Spatrick return gpr_cpsr;
1293061da546Spatrick default:
1294061da546Spatrick break;
1295061da546Spatrick }
1296061da546Spatrick } else if (kind == eRegisterKindDWARF) {
1297061da546Spatrick switch (reg) {
1298061da546Spatrick case dwarf_r0:
1299061da546Spatrick return gpr_r0;
1300061da546Spatrick case dwarf_r1:
1301061da546Spatrick return gpr_r1;
1302061da546Spatrick case dwarf_r2:
1303061da546Spatrick return gpr_r2;
1304061da546Spatrick case dwarf_r3:
1305061da546Spatrick return gpr_r3;
1306061da546Spatrick case dwarf_r4:
1307061da546Spatrick return gpr_r4;
1308061da546Spatrick case dwarf_r5:
1309061da546Spatrick return gpr_r5;
1310061da546Spatrick case dwarf_r6:
1311061da546Spatrick return gpr_r6;
1312061da546Spatrick case dwarf_r7:
1313061da546Spatrick return gpr_r7;
1314061da546Spatrick case dwarf_r8:
1315061da546Spatrick return gpr_r8;
1316061da546Spatrick case dwarf_r9:
1317061da546Spatrick return gpr_r9;
1318061da546Spatrick case dwarf_r10:
1319061da546Spatrick return gpr_r10;
1320061da546Spatrick case dwarf_r11:
1321061da546Spatrick return gpr_r11;
1322061da546Spatrick case dwarf_r12:
1323061da546Spatrick return gpr_r12;
1324061da546Spatrick case dwarf_sp:
1325061da546Spatrick return gpr_sp;
1326061da546Spatrick case dwarf_lr:
1327061da546Spatrick return gpr_lr;
1328061da546Spatrick case dwarf_pc:
1329061da546Spatrick return gpr_pc;
1330061da546Spatrick case dwarf_spsr:
1331061da546Spatrick return gpr_cpsr;
1332061da546Spatrick
1333061da546Spatrick case dwarf_s0:
1334061da546Spatrick return fpu_s0;
1335061da546Spatrick case dwarf_s1:
1336061da546Spatrick return fpu_s1;
1337061da546Spatrick case dwarf_s2:
1338061da546Spatrick return fpu_s2;
1339061da546Spatrick case dwarf_s3:
1340061da546Spatrick return fpu_s3;
1341061da546Spatrick case dwarf_s4:
1342061da546Spatrick return fpu_s4;
1343061da546Spatrick case dwarf_s5:
1344061da546Spatrick return fpu_s5;
1345061da546Spatrick case dwarf_s6:
1346061da546Spatrick return fpu_s6;
1347061da546Spatrick case dwarf_s7:
1348061da546Spatrick return fpu_s7;
1349061da546Spatrick case dwarf_s8:
1350061da546Spatrick return fpu_s8;
1351061da546Spatrick case dwarf_s9:
1352061da546Spatrick return fpu_s9;
1353061da546Spatrick case dwarf_s10:
1354061da546Spatrick return fpu_s10;
1355061da546Spatrick case dwarf_s11:
1356061da546Spatrick return fpu_s11;
1357061da546Spatrick case dwarf_s12:
1358061da546Spatrick return fpu_s12;
1359061da546Spatrick case dwarf_s13:
1360061da546Spatrick return fpu_s13;
1361061da546Spatrick case dwarf_s14:
1362061da546Spatrick return fpu_s14;
1363061da546Spatrick case dwarf_s15:
1364061da546Spatrick return fpu_s15;
1365061da546Spatrick case dwarf_s16:
1366061da546Spatrick return fpu_s16;
1367061da546Spatrick case dwarf_s17:
1368061da546Spatrick return fpu_s17;
1369061da546Spatrick case dwarf_s18:
1370061da546Spatrick return fpu_s18;
1371061da546Spatrick case dwarf_s19:
1372061da546Spatrick return fpu_s19;
1373061da546Spatrick case dwarf_s20:
1374061da546Spatrick return fpu_s20;
1375061da546Spatrick case dwarf_s21:
1376061da546Spatrick return fpu_s21;
1377061da546Spatrick case dwarf_s22:
1378061da546Spatrick return fpu_s22;
1379061da546Spatrick case dwarf_s23:
1380061da546Spatrick return fpu_s23;
1381061da546Spatrick case dwarf_s24:
1382061da546Spatrick return fpu_s24;
1383061da546Spatrick case dwarf_s25:
1384061da546Spatrick return fpu_s25;
1385061da546Spatrick case dwarf_s26:
1386061da546Spatrick return fpu_s26;
1387061da546Spatrick case dwarf_s27:
1388061da546Spatrick return fpu_s27;
1389061da546Spatrick case dwarf_s28:
1390061da546Spatrick return fpu_s28;
1391061da546Spatrick case dwarf_s29:
1392061da546Spatrick return fpu_s29;
1393061da546Spatrick case dwarf_s30:
1394061da546Spatrick return fpu_s30;
1395061da546Spatrick case dwarf_s31:
1396061da546Spatrick return fpu_s31;
1397061da546Spatrick
1398061da546Spatrick default:
1399061da546Spatrick break;
1400061da546Spatrick }
1401061da546Spatrick } else if (kind == eRegisterKindEHFrame) {
1402061da546Spatrick switch (reg) {
1403061da546Spatrick case ehframe_r0:
1404061da546Spatrick return gpr_r0;
1405061da546Spatrick case ehframe_r1:
1406061da546Spatrick return gpr_r1;
1407061da546Spatrick case ehframe_r2:
1408061da546Spatrick return gpr_r2;
1409061da546Spatrick case ehframe_r3:
1410061da546Spatrick return gpr_r3;
1411061da546Spatrick case ehframe_r4:
1412061da546Spatrick return gpr_r4;
1413061da546Spatrick case ehframe_r5:
1414061da546Spatrick return gpr_r5;
1415061da546Spatrick case ehframe_r6:
1416061da546Spatrick return gpr_r6;
1417061da546Spatrick case ehframe_r7:
1418061da546Spatrick return gpr_r7;
1419061da546Spatrick case ehframe_r8:
1420061da546Spatrick return gpr_r8;
1421061da546Spatrick case ehframe_r9:
1422061da546Spatrick return gpr_r9;
1423061da546Spatrick case ehframe_r10:
1424061da546Spatrick return gpr_r10;
1425061da546Spatrick case ehframe_r11:
1426061da546Spatrick return gpr_r11;
1427061da546Spatrick case ehframe_r12:
1428061da546Spatrick return gpr_r12;
1429061da546Spatrick case ehframe_sp:
1430061da546Spatrick return gpr_sp;
1431061da546Spatrick case ehframe_lr:
1432061da546Spatrick return gpr_lr;
1433061da546Spatrick case ehframe_pc:
1434061da546Spatrick return gpr_pc;
1435061da546Spatrick case ehframe_cpsr:
1436061da546Spatrick return gpr_cpsr;
1437061da546Spatrick }
1438061da546Spatrick } else if (kind == eRegisterKindLLDB) {
1439061da546Spatrick return reg;
1440061da546Spatrick }
1441061da546Spatrick return LLDB_INVALID_REGNUM;
1442061da546Spatrick }
1443061da546Spatrick
NumSupportedHardwareBreakpoints()1444061da546Spatrick uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {
1445061da546Spatrick #if defined(__APPLE__) && defined(__arm__)
1446061da546Spatrick // Set the init value to something that will let us know that we need to
1447061da546Spatrick // autodetect how many breakpoints are supported dynamically...
1448061da546Spatrick static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
1449061da546Spatrick if (g_num_supported_hw_breakpoints == UINT32_MAX) {
1450061da546Spatrick // Set this to zero in case we can't tell if there are any HW breakpoints
1451061da546Spatrick g_num_supported_hw_breakpoints = 0;
1452061da546Spatrick
1453061da546Spatrick uint32_t register_DBGDIDR;
1454061da546Spatrick
1455061da546Spatrick asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1456061da546Spatrick g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24);
1457061da546Spatrick // Zero is reserved for the BRP count, so don't increment it if it is zero
1458061da546Spatrick if (g_num_supported_hw_breakpoints > 0)
1459061da546Spatrick g_num_supported_hw_breakpoints++;
1460061da546Spatrick }
1461061da546Spatrick return g_num_supported_hw_breakpoints;
1462061da546Spatrick #else
1463061da546Spatrick // TODO: figure out remote case here!
1464061da546Spatrick return 6;
1465061da546Spatrick #endif
1466061da546Spatrick }
1467061da546Spatrick
SetHardwareBreakpoint(lldb::addr_t addr,size_t size)1468061da546Spatrick uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr,
1469061da546Spatrick size_t size) {
1470061da546Spatrick // Make sure our address isn't bogus
1471061da546Spatrick if (addr & 1)
1472061da546Spatrick return LLDB_INVALID_INDEX32;
1473061da546Spatrick
1474061da546Spatrick int kret = ReadDBG(false);
1475061da546Spatrick
1476061da546Spatrick if (kret == KERN_SUCCESS) {
1477061da546Spatrick const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
1478061da546Spatrick uint32_t i;
1479061da546Spatrick for (i = 0; i < num_hw_breakpoints; ++i) {
1480061da546Spatrick if ((dbg.bcr[i] & BCR_ENABLE) == 0)
1481061da546Spatrick break; // We found an available hw breakpoint slot (in i)
1482061da546Spatrick }
1483061da546Spatrick
1484061da546Spatrick // See if we found an available hw breakpoint slot above
1485061da546Spatrick if (i < num_hw_breakpoints) {
1486061da546Spatrick // Make sure bits 1:0 are clear in our address
1487061da546Spatrick dbg.bvr[i] = addr & ~((lldb::addr_t)3);
1488061da546Spatrick
1489061da546Spatrick if (size == 2 || addr & 2) {
1490061da546Spatrick uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
1491061da546Spatrick
1492061da546Spatrick // We have a thumb breakpoint
1493061da546Spatrick // We have an ARM breakpoint
1494*f6aab3d8Srobert dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address match
1495061da546Spatrick byte_addr_select | // Set the correct byte address select
1496061da546Spatrick // so we only trigger on the correct
1497061da546Spatrick // opcode
1498061da546Spatrick S_USER | // Which modes should this breakpoint stop in?
1499061da546Spatrick BCR_ENABLE; // Enable this hardware breakpoint
1500061da546Spatrick // if (log) log->Printf
1501061da546Spatrick // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1502061da546Spatrick // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1503061da546Spatrick // 0x%8.8x (Thumb)",
1504061da546Spatrick // addr,
1505061da546Spatrick // size,
1506061da546Spatrick // i,
1507061da546Spatrick // i,
1508061da546Spatrick // dbg.bvr[i],
1509061da546Spatrick // dbg.bcr[i]);
1510061da546Spatrick } else if (size == 4) {
1511061da546Spatrick // We have an ARM breakpoint
1512061da546Spatrick dbg.bcr[i] =
1513*f6aab3d8Srobert BCR_M_IMVA_MATCH | // Stop on address match
1514061da546Spatrick BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA
1515061da546Spatrick S_USER | // Which modes should this breakpoint stop in?
1516061da546Spatrick BCR_ENABLE; // Enable this hardware breakpoint
1517061da546Spatrick // if (log) log->Printf
1518061da546Spatrick // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(
1519061da546Spatrick // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /
1520061da546Spatrick // 0x%8.8x (ARM)",
1521061da546Spatrick // addr,
1522061da546Spatrick // size,
1523061da546Spatrick // i,
1524061da546Spatrick // i,
1525061da546Spatrick // dbg.bvr[i],
1526061da546Spatrick // dbg.bcr[i]);
1527061da546Spatrick }
1528061da546Spatrick
1529061da546Spatrick kret = WriteDBG();
1530061da546Spatrick // if (log) log->Printf
1531061da546Spatrick // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint()
1532061da546Spatrick // WriteDBG() => 0x%8.8x.", kret);
1533061da546Spatrick
1534061da546Spatrick if (kret == KERN_SUCCESS)
1535061da546Spatrick return i;
1536061da546Spatrick }
1537061da546Spatrick // else
1538061da546Spatrick // {
1539061da546Spatrick // if (log) log->Printf
1540061da546Spatrick // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr =
1541061da546Spatrick // %8.8p, size = %u) => all hardware breakpoint resources are
1542061da546Spatrick // being used.", addr, size);
1543061da546Spatrick // }
1544061da546Spatrick }
1545061da546Spatrick
1546061da546Spatrick return LLDB_INVALID_INDEX32;
1547061da546Spatrick }
1548061da546Spatrick
ClearHardwareBreakpoint(uint32_t hw_index)1549061da546Spatrick bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {
1550061da546Spatrick int kret = ReadDBG(false);
1551061da546Spatrick
1552061da546Spatrick const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
1553061da546Spatrick if (kret == KERN_SUCCESS) {
1554061da546Spatrick if (hw_index < num_hw_points) {
1555061da546Spatrick dbg.bcr[hw_index] = 0;
1556061da546Spatrick // if (log) log->Printf
1557061da546Spatrick // ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) -
1558061da546Spatrick // BVR%u = 0x%8.8x BCR%u = 0x%8.8x",
1559061da546Spatrick // hw_index,
1560061da546Spatrick // hw_index,
1561061da546Spatrick // dbg.bvr[hw_index],
1562061da546Spatrick // hw_index,
1563061da546Spatrick // dbg.bcr[hw_index]);
1564061da546Spatrick
1565061da546Spatrick kret = WriteDBG();
1566061da546Spatrick
1567061da546Spatrick if (kret == KERN_SUCCESS)
1568061da546Spatrick return true;
1569061da546Spatrick }
1570061da546Spatrick }
1571061da546Spatrick return false;
1572061da546Spatrick }
1573061da546Spatrick
NumSupportedHardwareWatchpoints()1574061da546Spatrick uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {
1575061da546Spatrick #if defined(__APPLE__) && defined(__arm__)
1576061da546Spatrick // Set the init value to something that will let us know that we need to
1577061da546Spatrick // autodetect how many watchpoints are supported dynamically...
1578061da546Spatrick static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
1579061da546Spatrick if (g_num_supported_hw_watchpoints == UINT32_MAX) {
1580061da546Spatrick // Set this to zero in case we can't tell if there are any HW breakpoints
1581061da546Spatrick g_num_supported_hw_watchpoints = 0;
1582061da546Spatrick
1583061da546Spatrick uint32_t register_DBGDIDR;
1584061da546Spatrick asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));
1585061da546Spatrick g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;
1586061da546Spatrick }
1587061da546Spatrick return g_num_supported_hw_watchpoints;
1588061da546Spatrick #else
1589061da546Spatrick // TODO: figure out remote case here!
1590061da546Spatrick return 2;
1591061da546Spatrick #endif
1592061da546Spatrick }
1593061da546Spatrick
SetHardwareWatchpoint(lldb::addr_t addr,size_t size,bool read,bool write)1594061da546Spatrick uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,
1595061da546Spatrick size_t size,
1596061da546Spatrick bool read,
1597061da546Spatrick bool write) {
1598061da546Spatrick const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1599061da546Spatrick
1600061da546Spatrick // Can't watch zero bytes
1601061da546Spatrick if (size == 0)
1602061da546Spatrick return LLDB_INVALID_INDEX32;
1603061da546Spatrick
1604061da546Spatrick // We must watch for either read or write
1605061da546Spatrick if (!read && !write)
1606061da546Spatrick return LLDB_INVALID_INDEX32;
1607061da546Spatrick
1608061da546Spatrick // Can't watch more than 4 bytes per WVR/WCR pair
1609061da546Spatrick if (size > 4)
1610061da546Spatrick return LLDB_INVALID_INDEX32;
1611061da546Spatrick
1612061da546Spatrick // We can only watch up to four bytes that follow a 4 byte aligned address
1613061da546Spatrick // per watchpoint register pair. Since we have at most so we can only watch
1614061da546Spatrick // until the next 4 byte boundary and we need to make sure we can properly
1615061da546Spatrick // encode this.
1616061da546Spatrick uint32_t addr_word_offset = addr % 4;
1617061da546Spatrick // if (log) log->Printf
1618061da546Spatrick // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() -
1619061da546Spatrick // addr_word_offset = 0x%8.8x", addr_word_offset);
1620061da546Spatrick
1621061da546Spatrick uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
1622061da546Spatrick // if (log) log->Printf
1623061da546Spatrick // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask =
1624061da546Spatrick // 0x%8.8x", byte_mask);
1625061da546Spatrick if (byte_mask > 0xfu)
1626061da546Spatrick return LLDB_INVALID_INDEX32;
1627061da546Spatrick
1628061da546Spatrick // Read the debug state
1629061da546Spatrick int kret = ReadDBG(false);
1630061da546Spatrick
1631061da546Spatrick if (kret == KERN_SUCCESS) {
1632061da546Spatrick // Check to make sure we have the needed hardware support
1633061da546Spatrick uint32_t i = 0;
1634061da546Spatrick
1635061da546Spatrick for (i = 0; i < num_hw_watchpoints; ++i) {
1636061da546Spatrick if ((dbg.wcr[i] & WCR_ENABLE) == 0)
1637061da546Spatrick break; // We found an available hw breakpoint slot (in i)
1638061da546Spatrick }
1639061da546Spatrick
1640061da546Spatrick // See if we found an available hw breakpoint slot above
1641061da546Spatrick if (i < num_hw_watchpoints) {
1642061da546Spatrick // Make the byte_mask into a valid Byte Address Select mask
1643061da546Spatrick uint32_t byte_address_select = byte_mask << 5;
1644061da546Spatrick // Make sure bits 1:0 are clear in our address
1645061da546Spatrick dbg.wvr[i] = addr & ~((lldb::addr_t)3);
1646061da546Spatrick dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA
1647061da546Spatrick // that we will watch
1648061da546Spatrick S_USER | // Stop only in user mode
1649061da546Spatrick (read ? WCR_LOAD : 0) | // Stop on read access?
1650061da546Spatrick (write ? WCR_STORE : 0) | // Stop on write access?
1651061da546Spatrick WCR_ENABLE; // Enable this watchpoint;
1652061da546Spatrick
1653061da546Spatrick kret = WriteDBG();
1654061da546Spatrick // if (log) log->Printf
1655061da546Spatrick // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint()
1656061da546Spatrick // WriteDBG() => 0x%8.8x.", kret);
1657061da546Spatrick
1658061da546Spatrick if (kret == KERN_SUCCESS)
1659061da546Spatrick return i;
1660061da546Spatrick } else {
1661061da546Spatrick // if (log) log->Printf
1662061da546Spatrick // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All
1663061da546Spatrick // hardware resources (%u) are in use.", num_hw_watchpoints);
1664061da546Spatrick }
1665061da546Spatrick }
1666061da546Spatrick return LLDB_INVALID_INDEX32;
1667061da546Spatrick }
1668061da546Spatrick
ClearHardwareWatchpoint(uint32_t hw_index)1669061da546Spatrick bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {
1670061da546Spatrick int kret = ReadDBG(false);
1671061da546Spatrick
1672061da546Spatrick const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
1673061da546Spatrick if (kret == KERN_SUCCESS) {
1674061da546Spatrick if (hw_index < num_hw_points) {
1675061da546Spatrick dbg.wcr[hw_index] = 0;
1676061da546Spatrick // if (log) log->Printf
1677061da546Spatrick // ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) -
1678061da546Spatrick // WVR%u = 0x%8.8x WCR%u = 0x%8.8x",
1679061da546Spatrick // hw_index,
1680061da546Spatrick // hw_index,
1681061da546Spatrick // dbg.wvr[hw_index],
1682061da546Spatrick // hw_index,
1683061da546Spatrick // dbg.wcr[hw_index]);
1684061da546Spatrick
1685061da546Spatrick kret = WriteDBG();
1686061da546Spatrick
1687061da546Spatrick if (kret == KERN_SUCCESS)
1688061da546Spatrick return true;
1689061da546Spatrick }
1690061da546Spatrick }
1691061da546Spatrick return false;
1692061da546Spatrick }
1693