1dda28197Spatrick //===-- RegisterContextDarwin_x86_64.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
9be691f3bSpatrick #include <cinttypes>
10be691f3bSpatrick #include <cstdarg>
11be691f3bSpatrick #include <cstddef>
12061da546Spatrick
13061da546Spatrick #include <memory>
14061da546Spatrick
15061da546Spatrick #include "lldb/Utility/DataBufferHeap.h"
16061da546Spatrick #include "lldb/Utility/DataExtractor.h"
17061da546Spatrick #include "lldb/Utility/Endian.h"
18061da546Spatrick #include "lldb/Utility/Log.h"
19061da546Spatrick #include "lldb/Utility/RegisterValue.h"
20061da546Spatrick #include "lldb/Utility/Scalar.h"
21061da546Spatrick #include "llvm/ADT/STLExtras.h"
22061da546Spatrick #include "llvm/Support/Compiler.h"
23061da546Spatrick
24061da546Spatrick #include "RegisterContextDarwin_x86_64.h"
25061da546Spatrick
26061da546Spatrick using namespace lldb;
27061da546Spatrick using namespace lldb_private;
28061da546Spatrick
29061da546Spatrick enum {
30061da546Spatrick gpr_rax = 0,
31061da546Spatrick gpr_rbx,
32061da546Spatrick gpr_rcx,
33061da546Spatrick gpr_rdx,
34061da546Spatrick gpr_rdi,
35061da546Spatrick gpr_rsi,
36061da546Spatrick gpr_rbp,
37061da546Spatrick gpr_rsp,
38061da546Spatrick gpr_r8,
39061da546Spatrick gpr_r9,
40061da546Spatrick gpr_r10,
41061da546Spatrick gpr_r11,
42061da546Spatrick gpr_r12,
43061da546Spatrick gpr_r13,
44061da546Spatrick gpr_r14,
45061da546Spatrick gpr_r15,
46061da546Spatrick gpr_rip,
47061da546Spatrick gpr_rflags,
48061da546Spatrick gpr_cs,
49061da546Spatrick gpr_fs,
50061da546Spatrick gpr_gs,
51061da546Spatrick
52061da546Spatrick fpu_fcw,
53061da546Spatrick fpu_fsw,
54061da546Spatrick fpu_ftw,
55061da546Spatrick fpu_fop,
56061da546Spatrick fpu_ip,
57061da546Spatrick fpu_cs,
58061da546Spatrick fpu_dp,
59061da546Spatrick fpu_ds,
60061da546Spatrick fpu_mxcsr,
61061da546Spatrick fpu_mxcsrmask,
62061da546Spatrick fpu_stmm0,
63061da546Spatrick fpu_stmm1,
64061da546Spatrick fpu_stmm2,
65061da546Spatrick fpu_stmm3,
66061da546Spatrick fpu_stmm4,
67061da546Spatrick fpu_stmm5,
68061da546Spatrick fpu_stmm6,
69061da546Spatrick fpu_stmm7,
70061da546Spatrick fpu_xmm0,
71061da546Spatrick fpu_xmm1,
72061da546Spatrick fpu_xmm2,
73061da546Spatrick fpu_xmm3,
74061da546Spatrick fpu_xmm4,
75061da546Spatrick fpu_xmm5,
76061da546Spatrick fpu_xmm6,
77061da546Spatrick fpu_xmm7,
78061da546Spatrick fpu_xmm8,
79061da546Spatrick fpu_xmm9,
80061da546Spatrick fpu_xmm10,
81061da546Spatrick fpu_xmm11,
82061da546Spatrick fpu_xmm12,
83061da546Spatrick fpu_xmm13,
84061da546Spatrick fpu_xmm14,
85061da546Spatrick fpu_xmm15,
86061da546Spatrick
87061da546Spatrick exc_trapno,
88061da546Spatrick exc_err,
89061da546Spatrick exc_faultvaddr,
90061da546Spatrick
91061da546Spatrick k_num_registers,
92061da546Spatrick
93061da546Spatrick // Aliases
94061da546Spatrick fpu_fctrl = fpu_fcw,
95061da546Spatrick fpu_fstat = fpu_fsw,
96061da546Spatrick fpu_ftag = fpu_ftw,
97061da546Spatrick fpu_fiseg = fpu_cs,
98061da546Spatrick fpu_fioff = fpu_ip,
99061da546Spatrick fpu_foseg = fpu_ds,
100061da546Spatrick fpu_fooff = fpu_dp
101061da546Spatrick };
102061da546Spatrick
103061da546Spatrick enum ehframe_dwarf_regnums {
104061da546Spatrick ehframe_dwarf_gpr_rax = 0,
105061da546Spatrick ehframe_dwarf_gpr_rdx,
106061da546Spatrick ehframe_dwarf_gpr_rcx,
107061da546Spatrick ehframe_dwarf_gpr_rbx,
108061da546Spatrick ehframe_dwarf_gpr_rsi,
109061da546Spatrick ehframe_dwarf_gpr_rdi,
110061da546Spatrick ehframe_dwarf_gpr_rbp,
111061da546Spatrick ehframe_dwarf_gpr_rsp,
112061da546Spatrick ehframe_dwarf_gpr_r8,
113061da546Spatrick ehframe_dwarf_gpr_r9,
114061da546Spatrick ehframe_dwarf_gpr_r10,
115061da546Spatrick ehframe_dwarf_gpr_r11,
116061da546Spatrick ehframe_dwarf_gpr_r12,
117061da546Spatrick ehframe_dwarf_gpr_r13,
118061da546Spatrick ehframe_dwarf_gpr_r14,
119061da546Spatrick ehframe_dwarf_gpr_r15,
120061da546Spatrick ehframe_dwarf_gpr_rip,
121061da546Spatrick ehframe_dwarf_fpu_xmm0,
122061da546Spatrick ehframe_dwarf_fpu_xmm1,
123061da546Spatrick ehframe_dwarf_fpu_xmm2,
124061da546Spatrick ehframe_dwarf_fpu_xmm3,
125061da546Spatrick ehframe_dwarf_fpu_xmm4,
126061da546Spatrick ehframe_dwarf_fpu_xmm5,
127061da546Spatrick ehframe_dwarf_fpu_xmm6,
128061da546Spatrick ehframe_dwarf_fpu_xmm7,
129061da546Spatrick ehframe_dwarf_fpu_xmm8,
130061da546Spatrick ehframe_dwarf_fpu_xmm9,
131061da546Spatrick ehframe_dwarf_fpu_xmm10,
132061da546Spatrick ehframe_dwarf_fpu_xmm11,
133061da546Spatrick ehframe_dwarf_fpu_xmm12,
134061da546Spatrick ehframe_dwarf_fpu_xmm13,
135061da546Spatrick ehframe_dwarf_fpu_xmm14,
136061da546Spatrick ehframe_dwarf_fpu_xmm15,
137061da546Spatrick ehframe_dwarf_fpu_stmm0,
138061da546Spatrick ehframe_dwarf_fpu_stmm1,
139061da546Spatrick ehframe_dwarf_fpu_stmm2,
140061da546Spatrick ehframe_dwarf_fpu_stmm3,
141061da546Spatrick ehframe_dwarf_fpu_stmm4,
142061da546Spatrick ehframe_dwarf_fpu_stmm5,
143061da546Spatrick ehframe_dwarf_fpu_stmm6,
144061da546Spatrick ehframe_dwarf_fpu_stmm7
145061da546Spatrick
146061da546Spatrick };
147061da546Spatrick
148061da546Spatrick #define GPR_OFFSET(reg) \
149061da546Spatrick (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::GPR, reg))
150061da546Spatrick #define FPU_OFFSET(reg) \
151061da546Spatrick (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::FPU, reg) + \
152061da546Spatrick sizeof(RegisterContextDarwin_x86_64::GPR))
153061da546Spatrick #define EXC_OFFSET(reg) \
154061da546Spatrick (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::EXC, reg) + \
155061da546Spatrick sizeof(RegisterContextDarwin_x86_64::GPR) + \
156061da546Spatrick sizeof(RegisterContextDarwin_x86_64::FPU))
157061da546Spatrick
158061da546Spatrick // These macros will auto define the register name, alt name, register size,
159061da546Spatrick // register offset, encoding, format and native register. This ensures that the
160061da546Spatrick // register state structures are defined correctly and have the correct sizes
161061da546Spatrick // and offsets.
162061da546Spatrick #define DEFINE_GPR(reg, alt) \
163061da546Spatrick #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *) NULL)->reg), \
164061da546Spatrick GPR_OFFSET(reg), eEncodingUint, eFormatHex
165061da546Spatrick #define DEFINE_FPU_UINT(reg) \
166061da546Spatrick #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg), \
167061da546Spatrick FPU_OFFSET(reg), eEncodingUint, eFormatHex
168061da546Spatrick #define DEFINE_FPU_VECT(reg, i) \
169061da546Spatrick #reg #i, NULL, \
170061da546Spatrick sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg[i].bytes), \
171061da546Spatrick FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
172061da546Spatrick {ehframe_dwarf_fpu_##reg##i, \
173061da546Spatrick ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, \
174061da546Spatrick LLDB_INVALID_REGNUM, fpu_##reg##i }, \
175*f6aab3d8Srobert nullptr, nullptr,
176061da546Spatrick #define DEFINE_EXC(reg) \
177061da546Spatrick #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *) NULL)->reg), \
178061da546Spatrick EXC_OFFSET(reg), eEncodingUint, eFormatHex
179061da546Spatrick
180061da546Spatrick #define REG_CONTEXT_SIZE \
181061da546Spatrick (sizeof(RegisterContextDarwin_x86_64::GPR) + \
182061da546Spatrick sizeof(RegisterContextDarwin_x86_64::FPU) + \
183061da546Spatrick sizeof(RegisterContextDarwin_x86_64::EXC))
184061da546Spatrick
185061da546Spatrick // General purpose registers for 64 bit
186061da546Spatrick static RegisterInfo g_register_infos[] = {
187061da546Spatrick // Macro auto defines most stuff EH_FRAME DWARF
188061da546Spatrick // GENERIC PROCESS PLUGIN LLDB
189061da546Spatrick // =============================== ======================
190061da546Spatrick // =================== ========================== ====================
191061da546Spatrick // ===================
192061da546Spatrick {DEFINE_GPR(rax, nullptr),
193061da546Spatrick {ehframe_dwarf_gpr_rax, ehframe_dwarf_gpr_rax, LLDB_INVALID_REGNUM,
194061da546Spatrick LLDB_INVALID_REGNUM, gpr_rax},
195061da546Spatrick nullptr,
196061da546Spatrick nullptr,
197*f6aab3d8Srobert },
198061da546Spatrick {DEFINE_GPR(rbx, nullptr),
199061da546Spatrick {ehframe_dwarf_gpr_rbx, ehframe_dwarf_gpr_rbx, LLDB_INVALID_REGNUM,
200061da546Spatrick LLDB_INVALID_REGNUM, gpr_rbx},
201061da546Spatrick nullptr,
202061da546Spatrick nullptr,
203*f6aab3d8Srobert },
204061da546Spatrick {DEFINE_GPR(rcx, nullptr),
205061da546Spatrick {ehframe_dwarf_gpr_rcx, ehframe_dwarf_gpr_rcx, LLDB_INVALID_REGNUM,
206061da546Spatrick LLDB_INVALID_REGNUM, gpr_rcx},
207061da546Spatrick nullptr,
208061da546Spatrick nullptr,
209*f6aab3d8Srobert },
210061da546Spatrick {DEFINE_GPR(rdx, nullptr),
211061da546Spatrick {ehframe_dwarf_gpr_rdx, ehframe_dwarf_gpr_rdx, LLDB_INVALID_REGNUM,
212061da546Spatrick LLDB_INVALID_REGNUM, gpr_rdx},
213061da546Spatrick nullptr,
214061da546Spatrick nullptr,
215*f6aab3d8Srobert },
216061da546Spatrick {DEFINE_GPR(rdi, nullptr),
217061da546Spatrick {ehframe_dwarf_gpr_rdi, ehframe_dwarf_gpr_rdi, LLDB_INVALID_REGNUM,
218061da546Spatrick LLDB_INVALID_REGNUM, gpr_rdi},
219061da546Spatrick nullptr,
220061da546Spatrick nullptr,
221*f6aab3d8Srobert },
222061da546Spatrick {DEFINE_GPR(rsi, nullptr),
223061da546Spatrick {ehframe_dwarf_gpr_rsi, ehframe_dwarf_gpr_rsi, LLDB_INVALID_REGNUM,
224061da546Spatrick LLDB_INVALID_REGNUM, gpr_rsi},
225061da546Spatrick nullptr,
226061da546Spatrick nullptr,
227*f6aab3d8Srobert },
228061da546Spatrick {DEFINE_GPR(rbp, "fp"),
229061da546Spatrick {ehframe_dwarf_gpr_rbp, ehframe_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP,
230061da546Spatrick LLDB_INVALID_REGNUM, gpr_rbp},
231061da546Spatrick nullptr,
232061da546Spatrick nullptr,
233*f6aab3d8Srobert },
234061da546Spatrick {DEFINE_GPR(rsp, "sp"),
235061da546Spatrick {ehframe_dwarf_gpr_rsp, ehframe_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP,
236061da546Spatrick LLDB_INVALID_REGNUM, gpr_rsp},
237061da546Spatrick nullptr,
238061da546Spatrick nullptr,
239*f6aab3d8Srobert },
240061da546Spatrick {DEFINE_GPR(r8, nullptr),
241061da546Spatrick {ehframe_dwarf_gpr_r8, ehframe_dwarf_gpr_r8, LLDB_INVALID_REGNUM,
242061da546Spatrick LLDB_INVALID_REGNUM, gpr_r8},
243061da546Spatrick nullptr,
244061da546Spatrick nullptr,
245*f6aab3d8Srobert },
246061da546Spatrick {DEFINE_GPR(r9, nullptr),
247061da546Spatrick {ehframe_dwarf_gpr_r9, ehframe_dwarf_gpr_r9, LLDB_INVALID_REGNUM,
248061da546Spatrick LLDB_INVALID_REGNUM, gpr_r9},
249061da546Spatrick nullptr,
250061da546Spatrick nullptr,
251*f6aab3d8Srobert },
252061da546Spatrick {DEFINE_GPR(r10, nullptr),
253061da546Spatrick {ehframe_dwarf_gpr_r10, ehframe_dwarf_gpr_r10, LLDB_INVALID_REGNUM,
254061da546Spatrick LLDB_INVALID_REGNUM, gpr_r10},
255061da546Spatrick nullptr,
256061da546Spatrick nullptr,
257*f6aab3d8Srobert },
258061da546Spatrick {DEFINE_GPR(r11, nullptr),
259061da546Spatrick {ehframe_dwarf_gpr_r11, ehframe_dwarf_gpr_r11, LLDB_INVALID_REGNUM,
260061da546Spatrick LLDB_INVALID_REGNUM, gpr_r11},
261061da546Spatrick nullptr,
262061da546Spatrick nullptr,
263*f6aab3d8Srobert },
264061da546Spatrick {DEFINE_GPR(r12, nullptr),
265061da546Spatrick {ehframe_dwarf_gpr_r12, ehframe_dwarf_gpr_r12, LLDB_INVALID_REGNUM,
266061da546Spatrick LLDB_INVALID_REGNUM, gpr_r12},
267061da546Spatrick nullptr,
268061da546Spatrick nullptr,
269*f6aab3d8Srobert },
270061da546Spatrick {DEFINE_GPR(r13, nullptr),
271061da546Spatrick {ehframe_dwarf_gpr_r13, ehframe_dwarf_gpr_r13, LLDB_INVALID_REGNUM,
272061da546Spatrick LLDB_INVALID_REGNUM, gpr_r13},
273061da546Spatrick nullptr,
274061da546Spatrick nullptr,
275*f6aab3d8Srobert },
276061da546Spatrick {DEFINE_GPR(r14, nullptr),
277061da546Spatrick {ehframe_dwarf_gpr_r14, ehframe_dwarf_gpr_r14, LLDB_INVALID_REGNUM,
278061da546Spatrick LLDB_INVALID_REGNUM, gpr_r14},
279061da546Spatrick nullptr,
280061da546Spatrick nullptr,
281*f6aab3d8Srobert },
282061da546Spatrick {DEFINE_GPR(r15, nullptr),
283061da546Spatrick {ehframe_dwarf_gpr_r15, ehframe_dwarf_gpr_r15, LLDB_INVALID_REGNUM,
284061da546Spatrick LLDB_INVALID_REGNUM, gpr_r15},
285061da546Spatrick nullptr,
286061da546Spatrick nullptr,
287*f6aab3d8Srobert },
288061da546Spatrick {DEFINE_GPR(rip, "pc"),
289061da546Spatrick {ehframe_dwarf_gpr_rip, ehframe_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC,
290061da546Spatrick LLDB_INVALID_REGNUM, gpr_rip},
291061da546Spatrick nullptr,
292061da546Spatrick nullptr,
293*f6aab3d8Srobert },
294061da546Spatrick {DEFINE_GPR(rflags, "flags"),
295061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
296061da546Spatrick LLDB_INVALID_REGNUM, gpr_rflags},
297061da546Spatrick nullptr,
298061da546Spatrick nullptr,
299*f6aab3d8Srobert },
300061da546Spatrick {DEFINE_GPR(cs, nullptr),
301061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
302061da546Spatrick LLDB_INVALID_REGNUM, gpr_cs},
303061da546Spatrick nullptr,
304061da546Spatrick nullptr,
305*f6aab3d8Srobert },
306061da546Spatrick {DEFINE_GPR(fs, nullptr),
307061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
308061da546Spatrick LLDB_INVALID_REGNUM, gpr_fs},
309061da546Spatrick nullptr,
310061da546Spatrick nullptr,
311*f6aab3d8Srobert },
312061da546Spatrick {DEFINE_GPR(gs, nullptr),
313061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
314061da546Spatrick LLDB_INVALID_REGNUM, gpr_gs},
315061da546Spatrick nullptr,
316061da546Spatrick nullptr,
317*f6aab3d8Srobert },
318061da546Spatrick
319061da546Spatrick {DEFINE_FPU_UINT(fcw),
320061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
321061da546Spatrick LLDB_INVALID_REGNUM, fpu_fcw},
322061da546Spatrick nullptr,
323061da546Spatrick nullptr,
324*f6aab3d8Srobert },
325061da546Spatrick {DEFINE_FPU_UINT(fsw),
326061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
327061da546Spatrick LLDB_INVALID_REGNUM, fpu_fsw},
328061da546Spatrick nullptr,
329061da546Spatrick nullptr,
330*f6aab3d8Srobert },
331061da546Spatrick {DEFINE_FPU_UINT(ftw),
332061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
333061da546Spatrick LLDB_INVALID_REGNUM, fpu_ftw},
334061da546Spatrick nullptr,
335061da546Spatrick nullptr,
336*f6aab3d8Srobert },
337061da546Spatrick {DEFINE_FPU_UINT(fop),
338061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
339061da546Spatrick LLDB_INVALID_REGNUM, fpu_fop},
340061da546Spatrick nullptr,
341061da546Spatrick nullptr,
342*f6aab3d8Srobert },
343061da546Spatrick {DEFINE_FPU_UINT(ip),
344061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
345061da546Spatrick LLDB_INVALID_REGNUM, fpu_ip},
346061da546Spatrick nullptr,
347061da546Spatrick nullptr,
348*f6aab3d8Srobert },
349061da546Spatrick {DEFINE_FPU_UINT(cs),
350061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
351061da546Spatrick LLDB_INVALID_REGNUM, fpu_cs},
352061da546Spatrick nullptr,
353061da546Spatrick nullptr,
354*f6aab3d8Srobert },
355061da546Spatrick {DEFINE_FPU_UINT(dp),
356061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
357061da546Spatrick LLDB_INVALID_REGNUM, fpu_dp},
358061da546Spatrick nullptr,
359061da546Spatrick nullptr,
360*f6aab3d8Srobert },
361061da546Spatrick {DEFINE_FPU_UINT(ds),
362061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
363061da546Spatrick LLDB_INVALID_REGNUM, fpu_ds},
364061da546Spatrick nullptr,
365061da546Spatrick nullptr,
366*f6aab3d8Srobert },
367061da546Spatrick {DEFINE_FPU_UINT(mxcsr),
368061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
369061da546Spatrick LLDB_INVALID_REGNUM, fpu_mxcsr},
370061da546Spatrick nullptr,
371061da546Spatrick nullptr,
372*f6aab3d8Srobert },
373061da546Spatrick {DEFINE_FPU_UINT(mxcsrmask),
374061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
375061da546Spatrick LLDB_INVALID_REGNUM, fpu_mxcsrmask},
376061da546Spatrick nullptr,
377061da546Spatrick nullptr,
378*f6aab3d8Srobert },
379061da546Spatrick {DEFINE_FPU_VECT(stmm, 0)},
380061da546Spatrick {DEFINE_FPU_VECT(stmm, 1)},
381061da546Spatrick {DEFINE_FPU_VECT(stmm, 2)},
382061da546Spatrick {DEFINE_FPU_VECT(stmm, 3)},
383061da546Spatrick {DEFINE_FPU_VECT(stmm, 4)},
384061da546Spatrick {DEFINE_FPU_VECT(stmm, 5)},
385061da546Spatrick {DEFINE_FPU_VECT(stmm, 6)},
386061da546Spatrick {DEFINE_FPU_VECT(stmm, 7)},
387061da546Spatrick {DEFINE_FPU_VECT(xmm, 0)},
388061da546Spatrick {DEFINE_FPU_VECT(xmm, 1)},
389061da546Spatrick {DEFINE_FPU_VECT(xmm, 2)},
390061da546Spatrick {DEFINE_FPU_VECT(xmm, 3)},
391061da546Spatrick {DEFINE_FPU_VECT(xmm, 4)},
392061da546Spatrick {DEFINE_FPU_VECT(xmm, 5)},
393061da546Spatrick {DEFINE_FPU_VECT(xmm, 6)},
394061da546Spatrick {DEFINE_FPU_VECT(xmm, 7)},
395061da546Spatrick {DEFINE_FPU_VECT(xmm, 8)},
396061da546Spatrick {DEFINE_FPU_VECT(xmm, 9)},
397061da546Spatrick {DEFINE_FPU_VECT(xmm, 10)},
398061da546Spatrick {DEFINE_FPU_VECT(xmm, 11)},
399061da546Spatrick {DEFINE_FPU_VECT(xmm, 12)},
400061da546Spatrick {DEFINE_FPU_VECT(xmm, 13)},
401061da546Spatrick {DEFINE_FPU_VECT(xmm, 14)},
402061da546Spatrick {DEFINE_FPU_VECT(xmm, 15)},
403061da546Spatrick
404061da546Spatrick {DEFINE_EXC(trapno),
405061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
406061da546Spatrick LLDB_INVALID_REGNUM, exc_trapno},
407061da546Spatrick nullptr,
408061da546Spatrick nullptr,
409*f6aab3d8Srobert },
410061da546Spatrick {DEFINE_EXC(err),
411061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
412061da546Spatrick LLDB_INVALID_REGNUM, exc_err},
413061da546Spatrick nullptr,
414061da546Spatrick nullptr,
415*f6aab3d8Srobert },
416061da546Spatrick {DEFINE_EXC(faultvaddr),
417061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
418061da546Spatrick LLDB_INVALID_REGNUM, exc_faultvaddr},
419061da546Spatrick nullptr,
420061da546Spatrick nullptr,
421*f6aab3d8Srobert }};
422061da546Spatrick
423*f6aab3d8Srobert static size_t k_num_register_infos = std::size(g_register_infos);
424061da546Spatrick
RegisterContextDarwin_x86_64(Thread & thread,uint32_t concrete_frame_idx)425061da546Spatrick RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64(
426061da546Spatrick Thread &thread, uint32_t concrete_frame_idx)
427061da546Spatrick : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
428061da546Spatrick uint32_t i;
429061da546Spatrick for (i = 0; i < kNumErrors; i++) {
430061da546Spatrick gpr_errs[i] = -1;
431061da546Spatrick fpu_errs[i] = -1;
432061da546Spatrick exc_errs[i] = -1;
433061da546Spatrick }
434061da546Spatrick }
435061da546Spatrick
436be691f3bSpatrick RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() = default;
437061da546Spatrick
InvalidateAllRegisters()438061da546Spatrick void RegisterContextDarwin_x86_64::InvalidateAllRegisters() {
439061da546Spatrick InvalidateAllRegisterStates();
440061da546Spatrick }
441061da546Spatrick
GetRegisterCount()442061da546Spatrick size_t RegisterContextDarwin_x86_64::GetRegisterCount() {
443061da546Spatrick assert(k_num_register_infos == k_num_registers);
444061da546Spatrick return k_num_registers;
445061da546Spatrick }
446061da546Spatrick
447061da546Spatrick const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)448061da546Spatrick RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex(size_t reg) {
449061da546Spatrick assert(k_num_register_infos == k_num_registers);
450061da546Spatrick if (reg < k_num_registers)
451061da546Spatrick return &g_register_infos[reg];
452061da546Spatrick return nullptr;
453061da546Spatrick }
454061da546Spatrick
GetRegisterInfosCount()455061da546Spatrick size_t RegisterContextDarwin_x86_64::GetRegisterInfosCount() {
456061da546Spatrick return k_num_register_infos;
457061da546Spatrick }
458061da546Spatrick
459061da546Spatrick const lldb_private::RegisterInfo *
GetRegisterInfos()460061da546Spatrick RegisterContextDarwin_x86_64::GetRegisterInfos() {
461061da546Spatrick return g_register_infos;
462061da546Spatrick }
463061da546Spatrick
464061da546Spatrick static uint32_t g_gpr_regnums[] = {
465061da546Spatrick gpr_rax, gpr_rbx, gpr_rcx, gpr_rdx, gpr_rdi, gpr_rsi, gpr_rbp,
466061da546Spatrick gpr_rsp, gpr_r8, gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_r13,
467061da546Spatrick gpr_r14, gpr_r15, gpr_rip, gpr_rflags, gpr_cs, gpr_fs, gpr_gs};
468061da546Spatrick
469061da546Spatrick static uint32_t g_fpu_regnums[] = {
470061da546Spatrick fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs,
471061da546Spatrick fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
472061da546Spatrick fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7,
473061da546Spatrick fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5,
474061da546Spatrick fpu_xmm6, fpu_xmm7, fpu_xmm8, fpu_xmm9, fpu_xmm10, fpu_xmm11,
475061da546Spatrick fpu_xmm12, fpu_xmm13, fpu_xmm14, fpu_xmm15};
476061da546Spatrick
477061da546Spatrick static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
478061da546Spatrick
479061da546Spatrick // Number of registers in each register set
480*f6aab3d8Srobert const size_t k_num_gpr_registers = std::size(g_gpr_regnums);
481*f6aab3d8Srobert const size_t k_num_fpu_registers = std::size(g_fpu_regnums);
482*f6aab3d8Srobert const size_t k_num_exc_registers = std::size(g_exc_regnums);
483061da546Spatrick
484061da546Spatrick // Register set definitions. The first definitions at register set index of
485061da546Spatrick // zero is for all registers, followed by other registers sets. The register
486061da546Spatrick // information for the all register set need not be filled in.
487061da546Spatrick static const RegisterSet g_reg_sets[] = {
488061da546Spatrick {
489061da546Spatrick "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
490061da546Spatrick },
491061da546Spatrick {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
492061da546Spatrick {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
493061da546Spatrick
494*f6aab3d8Srobert const size_t k_num_regsets = std::size(g_reg_sets);
495061da546Spatrick
GetRegisterSetCount()496061da546Spatrick size_t RegisterContextDarwin_x86_64::GetRegisterSetCount() {
497061da546Spatrick return k_num_regsets;
498061da546Spatrick }
499061da546Spatrick
500061da546Spatrick const RegisterSet *
GetRegisterSet(size_t reg_set)501061da546Spatrick RegisterContextDarwin_x86_64::GetRegisterSet(size_t reg_set) {
502061da546Spatrick if (reg_set < k_num_regsets)
503061da546Spatrick return &g_reg_sets[reg_set];
504061da546Spatrick return nullptr;
505061da546Spatrick }
506061da546Spatrick
GetSetForNativeRegNum(int reg_num)507061da546Spatrick int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num) {
508061da546Spatrick if (reg_num < fpu_fcw)
509061da546Spatrick return GPRRegSet;
510061da546Spatrick else if (reg_num < exc_trapno)
511061da546Spatrick return FPURegSet;
512061da546Spatrick else if (reg_num < k_num_registers)
513061da546Spatrick return EXCRegSet;
514061da546Spatrick return -1;
515061da546Spatrick }
516061da546Spatrick
ReadGPR(bool force)517061da546Spatrick int RegisterContextDarwin_x86_64::ReadGPR(bool force) {
518061da546Spatrick int set = GPRRegSet;
519061da546Spatrick if (force || !RegisterSetIsCached(set)) {
520061da546Spatrick SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
521061da546Spatrick }
522061da546Spatrick return GetError(GPRRegSet, Read);
523061da546Spatrick }
524061da546Spatrick
ReadFPU(bool force)525061da546Spatrick int RegisterContextDarwin_x86_64::ReadFPU(bool force) {
526061da546Spatrick int set = FPURegSet;
527061da546Spatrick if (force || !RegisterSetIsCached(set)) {
528061da546Spatrick SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
529061da546Spatrick }
530061da546Spatrick return GetError(FPURegSet, Read);
531061da546Spatrick }
532061da546Spatrick
ReadEXC(bool force)533061da546Spatrick int RegisterContextDarwin_x86_64::ReadEXC(bool force) {
534061da546Spatrick int set = EXCRegSet;
535061da546Spatrick if (force || !RegisterSetIsCached(set)) {
536061da546Spatrick SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
537061da546Spatrick }
538061da546Spatrick return GetError(EXCRegSet, Read);
539061da546Spatrick }
540061da546Spatrick
WriteGPR()541061da546Spatrick int RegisterContextDarwin_x86_64::WriteGPR() {
542061da546Spatrick int set = GPRRegSet;
543061da546Spatrick if (!RegisterSetIsCached(set)) {
544061da546Spatrick SetError(set, Write, -1);
545061da546Spatrick return -1;
546061da546Spatrick }
547061da546Spatrick SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
548061da546Spatrick SetError(set, Read, -1);
549061da546Spatrick return GetError(set, Write);
550061da546Spatrick }
551061da546Spatrick
WriteFPU()552061da546Spatrick int RegisterContextDarwin_x86_64::WriteFPU() {
553061da546Spatrick int set = FPURegSet;
554061da546Spatrick if (!RegisterSetIsCached(set)) {
555061da546Spatrick SetError(set, Write, -1);
556061da546Spatrick return -1;
557061da546Spatrick }
558061da546Spatrick SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
559061da546Spatrick SetError(set, Read, -1);
560061da546Spatrick return GetError(set, Write);
561061da546Spatrick }
562061da546Spatrick
WriteEXC()563061da546Spatrick int RegisterContextDarwin_x86_64::WriteEXC() {
564061da546Spatrick int set = EXCRegSet;
565061da546Spatrick if (!RegisterSetIsCached(set)) {
566061da546Spatrick SetError(set, Write, -1);
567061da546Spatrick return -1;
568061da546Spatrick }
569061da546Spatrick SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
570061da546Spatrick SetError(set, Read, -1);
571061da546Spatrick return GetError(set, Write);
572061da546Spatrick }
573061da546Spatrick
ReadRegisterSet(uint32_t set,bool force)574061da546Spatrick int RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force) {
575061da546Spatrick switch (set) {
576061da546Spatrick case GPRRegSet:
577061da546Spatrick return ReadGPR(force);
578061da546Spatrick case FPURegSet:
579061da546Spatrick return ReadFPU(force);
580061da546Spatrick case EXCRegSet:
581061da546Spatrick return ReadEXC(force);
582061da546Spatrick default:
583061da546Spatrick break;
584061da546Spatrick }
585061da546Spatrick return -1;
586061da546Spatrick }
587061da546Spatrick
WriteRegisterSet(uint32_t set)588061da546Spatrick int RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set) {
589061da546Spatrick // Make sure we have a valid context to set.
590061da546Spatrick switch (set) {
591061da546Spatrick case GPRRegSet:
592061da546Spatrick return WriteGPR();
593061da546Spatrick case FPURegSet:
594061da546Spatrick return WriteFPU();
595061da546Spatrick case EXCRegSet:
596061da546Spatrick return WriteEXC();
597061da546Spatrick default:
598061da546Spatrick break;
599061da546Spatrick }
600061da546Spatrick return -1;
601061da546Spatrick }
602061da546Spatrick
ReadRegister(const RegisterInfo * reg_info,RegisterValue & value)603061da546Spatrick bool RegisterContextDarwin_x86_64::ReadRegister(const RegisterInfo *reg_info,
604061da546Spatrick RegisterValue &value) {
605061da546Spatrick const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
606061da546Spatrick int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
607061da546Spatrick if (set == -1)
608061da546Spatrick return false;
609061da546Spatrick
610061da546Spatrick if (ReadRegisterSet(set, false) != 0)
611061da546Spatrick return false;
612061da546Spatrick
613061da546Spatrick switch (reg) {
614061da546Spatrick case gpr_rax:
615061da546Spatrick case gpr_rbx:
616061da546Spatrick case gpr_rcx:
617061da546Spatrick case gpr_rdx:
618061da546Spatrick case gpr_rdi:
619061da546Spatrick case gpr_rsi:
620061da546Spatrick case gpr_rbp:
621061da546Spatrick case gpr_rsp:
622061da546Spatrick case gpr_r8:
623061da546Spatrick case gpr_r9:
624061da546Spatrick case gpr_r10:
625061da546Spatrick case gpr_r11:
626061da546Spatrick case gpr_r12:
627061da546Spatrick case gpr_r13:
628061da546Spatrick case gpr_r14:
629061da546Spatrick case gpr_r15:
630061da546Spatrick case gpr_rip:
631061da546Spatrick case gpr_rflags:
632061da546Spatrick case gpr_cs:
633061da546Spatrick case gpr_fs:
634061da546Spatrick case gpr_gs:
635061da546Spatrick value = (&gpr.rax)[reg - gpr_rax];
636061da546Spatrick break;
637061da546Spatrick
638061da546Spatrick case fpu_fcw:
639061da546Spatrick value = fpu.fcw;
640061da546Spatrick break;
641061da546Spatrick
642061da546Spatrick case fpu_fsw:
643061da546Spatrick value = fpu.fsw;
644061da546Spatrick break;
645061da546Spatrick
646061da546Spatrick case fpu_ftw:
647061da546Spatrick value = fpu.ftw;
648061da546Spatrick break;
649061da546Spatrick
650061da546Spatrick case fpu_fop:
651061da546Spatrick value = fpu.fop;
652061da546Spatrick break;
653061da546Spatrick
654061da546Spatrick case fpu_ip:
655061da546Spatrick value = fpu.ip;
656061da546Spatrick break;
657061da546Spatrick
658061da546Spatrick case fpu_cs:
659061da546Spatrick value = fpu.cs;
660061da546Spatrick break;
661061da546Spatrick
662061da546Spatrick case fpu_dp:
663061da546Spatrick value = fpu.dp;
664061da546Spatrick break;
665061da546Spatrick
666061da546Spatrick case fpu_ds:
667061da546Spatrick value = fpu.ds;
668061da546Spatrick break;
669061da546Spatrick
670061da546Spatrick case fpu_mxcsr:
671061da546Spatrick value = fpu.mxcsr;
672061da546Spatrick break;
673061da546Spatrick
674061da546Spatrick case fpu_mxcsrmask:
675061da546Spatrick value = fpu.mxcsrmask;
676061da546Spatrick break;
677061da546Spatrick
678061da546Spatrick case fpu_stmm0:
679061da546Spatrick case fpu_stmm1:
680061da546Spatrick case fpu_stmm2:
681061da546Spatrick case fpu_stmm3:
682061da546Spatrick case fpu_stmm4:
683061da546Spatrick case fpu_stmm5:
684061da546Spatrick case fpu_stmm6:
685061da546Spatrick case fpu_stmm7:
686061da546Spatrick value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size,
687061da546Spatrick endian::InlHostByteOrder());
688061da546Spatrick break;
689061da546Spatrick
690061da546Spatrick case fpu_xmm0:
691061da546Spatrick case fpu_xmm1:
692061da546Spatrick case fpu_xmm2:
693061da546Spatrick case fpu_xmm3:
694061da546Spatrick case fpu_xmm4:
695061da546Spatrick case fpu_xmm5:
696061da546Spatrick case fpu_xmm6:
697061da546Spatrick case fpu_xmm7:
698061da546Spatrick case fpu_xmm8:
699061da546Spatrick case fpu_xmm9:
700061da546Spatrick case fpu_xmm10:
701061da546Spatrick case fpu_xmm11:
702061da546Spatrick case fpu_xmm12:
703061da546Spatrick case fpu_xmm13:
704061da546Spatrick case fpu_xmm14:
705061da546Spatrick case fpu_xmm15:
706061da546Spatrick value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size,
707061da546Spatrick endian::InlHostByteOrder());
708061da546Spatrick break;
709061da546Spatrick
710061da546Spatrick case exc_trapno:
711061da546Spatrick value = exc.trapno;
712061da546Spatrick break;
713061da546Spatrick
714061da546Spatrick case exc_err:
715061da546Spatrick value = exc.err;
716061da546Spatrick break;
717061da546Spatrick
718061da546Spatrick case exc_faultvaddr:
719061da546Spatrick value = exc.faultvaddr;
720061da546Spatrick break;
721061da546Spatrick
722061da546Spatrick default:
723061da546Spatrick return false;
724061da546Spatrick }
725061da546Spatrick return true;
726061da546Spatrick }
727061da546Spatrick
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & value)728061da546Spatrick bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo *reg_info,
729061da546Spatrick const RegisterValue &value) {
730061da546Spatrick const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
731061da546Spatrick int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
732061da546Spatrick
733061da546Spatrick if (set == -1)
734061da546Spatrick return false;
735061da546Spatrick
736061da546Spatrick if (ReadRegisterSet(set, false) != 0)
737061da546Spatrick return false;
738061da546Spatrick
739061da546Spatrick switch (reg) {
740061da546Spatrick case gpr_rax:
741061da546Spatrick case gpr_rbx:
742061da546Spatrick case gpr_rcx:
743061da546Spatrick case gpr_rdx:
744061da546Spatrick case gpr_rdi:
745061da546Spatrick case gpr_rsi:
746061da546Spatrick case gpr_rbp:
747061da546Spatrick case gpr_rsp:
748061da546Spatrick case gpr_r8:
749061da546Spatrick case gpr_r9:
750061da546Spatrick case gpr_r10:
751061da546Spatrick case gpr_r11:
752061da546Spatrick case gpr_r12:
753061da546Spatrick case gpr_r13:
754061da546Spatrick case gpr_r14:
755061da546Spatrick case gpr_r15:
756061da546Spatrick case gpr_rip:
757061da546Spatrick case gpr_rflags:
758061da546Spatrick case gpr_cs:
759061da546Spatrick case gpr_fs:
760061da546Spatrick case gpr_gs:
761061da546Spatrick (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
762061da546Spatrick break;
763061da546Spatrick
764061da546Spatrick case fpu_fcw:
765061da546Spatrick fpu.fcw = value.GetAsUInt16();
766061da546Spatrick break;
767061da546Spatrick
768061da546Spatrick case fpu_fsw:
769061da546Spatrick fpu.fsw = value.GetAsUInt16();
770061da546Spatrick break;
771061da546Spatrick
772061da546Spatrick case fpu_ftw:
773061da546Spatrick fpu.ftw = value.GetAsUInt8();
774061da546Spatrick break;
775061da546Spatrick
776061da546Spatrick case fpu_fop:
777061da546Spatrick fpu.fop = value.GetAsUInt16();
778061da546Spatrick break;
779061da546Spatrick
780061da546Spatrick case fpu_ip:
781061da546Spatrick fpu.ip = value.GetAsUInt32();
782061da546Spatrick break;
783061da546Spatrick
784061da546Spatrick case fpu_cs:
785061da546Spatrick fpu.cs = value.GetAsUInt16();
786061da546Spatrick break;
787061da546Spatrick
788061da546Spatrick case fpu_dp:
789061da546Spatrick fpu.dp = value.GetAsUInt32();
790061da546Spatrick break;
791061da546Spatrick
792061da546Spatrick case fpu_ds:
793061da546Spatrick fpu.ds = value.GetAsUInt16();
794061da546Spatrick break;
795061da546Spatrick
796061da546Spatrick case fpu_mxcsr:
797061da546Spatrick fpu.mxcsr = value.GetAsUInt32();
798061da546Spatrick break;
799061da546Spatrick
800061da546Spatrick case fpu_mxcsrmask:
801061da546Spatrick fpu.mxcsrmask = value.GetAsUInt32();
802061da546Spatrick break;
803061da546Spatrick
804061da546Spatrick case fpu_stmm0:
805061da546Spatrick case fpu_stmm1:
806061da546Spatrick case fpu_stmm2:
807061da546Spatrick case fpu_stmm3:
808061da546Spatrick case fpu_stmm4:
809061da546Spatrick case fpu_stmm5:
810061da546Spatrick case fpu_stmm6:
811061da546Spatrick case fpu_stmm7:
812061da546Spatrick ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
813061da546Spatrick value.GetByteSize());
814061da546Spatrick break;
815061da546Spatrick
816061da546Spatrick case fpu_xmm0:
817061da546Spatrick case fpu_xmm1:
818061da546Spatrick case fpu_xmm2:
819061da546Spatrick case fpu_xmm3:
820061da546Spatrick case fpu_xmm4:
821061da546Spatrick case fpu_xmm5:
822061da546Spatrick case fpu_xmm6:
823061da546Spatrick case fpu_xmm7:
824061da546Spatrick case fpu_xmm8:
825061da546Spatrick case fpu_xmm9:
826061da546Spatrick case fpu_xmm10:
827061da546Spatrick case fpu_xmm11:
828061da546Spatrick case fpu_xmm12:
829061da546Spatrick case fpu_xmm13:
830061da546Spatrick case fpu_xmm14:
831061da546Spatrick case fpu_xmm15:
832061da546Spatrick ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
833061da546Spatrick value.GetByteSize());
834061da546Spatrick return false;
835061da546Spatrick
836061da546Spatrick case exc_trapno:
837061da546Spatrick exc.trapno = value.GetAsUInt32();
838061da546Spatrick break;
839061da546Spatrick
840061da546Spatrick case exc_err:
841061da546Spatrick exc.err = value.GetAsUInt32();
842061da546Spatrick break;
843061da546Spatrick
844061da546Spatrick case exc_faultvaddr:
845061da546Spatrick exc.faultvaddr = value.GetAsUInt64();
846061da546Spatrick break;
847061da546Spatrick
848061da546Spatrick default:
849061da546Spatrick return false;
850061da546Spatrick }
851061da546Spatrick return WriteRegisterSet(set) == 0;
852061da546Spatrick }
853061da546Spatrick
ReadAllRegisterValues(lldb::WritableDataBufferSP & data_sp)854061da546Spatrick bool RegisterContextDarwin_x86_64::ReadAllRegisterValues(
855*f6aab3d8Srobert lldb::WritableDataBufferSP &data_sp) {
856061da546Spatrick data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);
857061da546Spatrick if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) {
858061da546Spatrick uint8_t *dst = data_sp->GetBytes();
859061da546Spatrick ::memcpy(dst, &gpr, sizeof(gpr));
860061da546Spatrick dst += sizeof(gpr);
861061da546Spatrick
862061da546Spatrick ::memcpy(dst, &fpu, sizeof(fpu));
863061da546Spatrick dst += sizeof(gpr);
864061da546Spatrick
865061da546Spatrick ::memcpy(dst, &exc, sizeof(exc));
866061da546Spatrick return true;
867061da546Spatrick }
868061da546Spatrick return false;
869061da546Spatrick }
870061da546Spatrick
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)871061da546Spatrick bool RegisterContextDarwin_x86_64::WriteAllRegisterValues(
872061da546Spatrick const lldb::DataBufferSP &data_sp) {
873061da546Spatrick if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
874061da546Spatrick const uint8_t *src = data_sp->GetBytes();
875061da546Spatrick ::memcpy(&gpr, src, sizeof(gpr));
876061da546Spatrick src += sizeof(gpr);
877061da546Spatrick
878061da546Spatrick ::memcpy(&fpu, src, sizeof(fpu));
879061da546Spatrick src += sizeof(gpr);
880061da546Spatrick
881061da546Spatrick ::memcpy(&exc, src, sizeof(exc));
882061da546Spatrick uint32_t success_count = 0;
883061da546Spatrick if (WriteGPR() == 0)
884061da546Spatrick ++success_count;
885061da546Spatrick if (WriteFPU() == 0)
886061da546Spatrick ++success_count;
887061da546Spatrick if (WriteEXC() == 0)
888061da546Spatrick ++success_count;
889061da546Spatrick return success_count == 3;
890061da546Spatrick }
891061da546Spatrick return false;
892061da546Spatrick }
893061da546Spatrick
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t reg)894061da546Spatrick uint32_t RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber(
895061da546Spatrick lldb::RegisterKind kind, uint32_t reg) {
896061da546Spatrick if (kind == eRegisterKindGeneric) {
897061da546Spatrick switch (reg) {
898061da546Spatrick case LLDB_REGNUM_GENERIC_PC:
899061da546Spatrick return gpr_rip;
900061da546Spatrick case LLDB_REGNUM_GENERIC_SP:
901061da546Spatrick return gpr_rsp;
902061da546Spatrick case LLDB_REGNUM_GENERIC_FP:
903061da546Spatrick return gpr_rbp;
904061da546Spatrick case LLDB_REGNUM_GENERIC_FLAGS:
905061da546Spatrick return gpr_rflags;
906061da546Spatrick case LLDB_REGNUM_GENERIC_RA:
907061da546Spatrick default:
908061da546Spatrick break;
909061da546Spatrick }
910061da546Spatrick } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
911061da546Spatrick switch (reg) {
912061da546Spatrick case ehframe_dwarf_gpr_rax:
913061da546Spatrick return gpr_rax;
914061da546Spatrick case ehframe_dwarf_gpr_rdx:
915061da546Spatrick return gpr_rdx;
916061da546Spatrick case ehframe_dwarf_gpr_rcx:
917061da546Spatrick return gpr_rcx;
918061da546Spatrick case ehframe_dwarf_gpr_rbx:
919061da546Spatrick return gpr_rbx;
920061da546Spatrick case ehframe_dwarf_gpr_rsi:
921061da546Spatrick return gpr_rsi;
922061da546Spatrick case ehframe_dwarf_gpr_rdi:
923061da546Spatrick return gpr_rdi;
924061da546Spatrick case ehframe_dwarf_gpr_rbp:
925061da546Spatrick return gpr_rbp;
926061da546Spatrick case ehframe_dwarf_gpr_rsp:
927061da546Spatrick return gpr_rsp;
928061da546Spatrick case ehframe_dwarf_gpr_r8:
929061da546Spatrick return gpr_r8;
930061da546Spatrick case ehframe_dwarf_gpr_r9:
931061da546Spatrick return gpr_r9;
932061da546Spatrick case ehframe_dwarf_gpr_r10:
933061da546Spatrick return gpr_r10;
934061da546Spatrick case ehframe_dwarf_gpr_r11:
935061da546Spatrick return gpr_r11;
936061da546Spatrick case ehframe_dwarf_gpr_r12:
937061da546Spatrick return gpr_r12;
938061da546Spatrick case ehframe_dwarf_gpr_r13:
939061da546Spatrick return gpr_r13;
940061da546Spatrick case ehframe_dwarf_gpr_r14:
941061da546Spatrick return gpr_r14;
942061da546Spatrick case ehframe_dwarf_gpr_r15:
943061da546Spatrick return gpr_r15;
944061da546Spatrick case ehframe_dwarf_gpr_rip:
945061da546Spatrick return gpr_rip;
946061da546Spatrick case ehframe_dwarf_fpu_xmm0:
947061da546Spatrick return fpu_xmm0;
948061da546Spatrick case ehframe_dwarf_fpu_xmm1:
949061da546Spatrick return fpu_xmm1;
950061da546Spatrick case ehframe_dwarf_fpu_xmm2:
951061da546Spatrick return fpu_xmm2;
952061da546Spatrick case ehframe_dwarf_fpu_xmm3:
953061da546Spatrick return fpu_xmm3;
954061da546Spatrick case ehframe_dwarf_fpu_xmm4:
955061da546Spatrick return fpu_xmm4;
956061da546Spatrick case ehframe_dwarf_fpu_xmm5:
957061da546Spatrick return fpu_xmm5;
958061da546Spatrick case ehframe_dwarf_fpu_xmm6:
959061da546Spatrick return fpu_xmm6;
960061da546Spatrick case ehframe_dwarf_fpu_xmm7:
961061da546Spatrick return fpu_xmm7;
962061da546Spatrick case ehframe_dwarf_fpu_xmm8:
963061da546Spatrick return fpu_xmm8;
964061da546Spatrick case ehframe_dwarf_fpu_xmm9:
965061da546Spatrick return fpu_xmm9;
966061da546Spatrick case ehframe_dwarf_fpu_xmm10:
967061da546Spatrick return fpu_xmm10;
968061da546Spatrick case ehframe_dwarf_fpu_xmm11:
969061da546Spatrick return fpu_xmm11;
970061da546Spatrick case ehframe_dwarf_fpu_xmm12:
971061da546Spatrick return fpu_xmm12;
972061da546Spatrick case ehframe_dwarf_fpu_xmm13:
973061da546Spatrick return fpu_xmm13;
974061da546Spatrick case ehframe_dwarf_fpu_xmm14:
975061da546Spatrick return fpu_xmm14;
976061da546Spatrick case ehframe_dwarf_fpu_xmm15:
977061da546Spatrick return fpu_xmm15;
978061da546Spatrick case ehframe_dwarf_fpu_stmm0:
979061da546Spatrick return fpu_stmm0;
980061da546Spatrick case ehframe_dwarf_fpu_stmm1:
981061da546Spatrick return fpu_stmm1;
982061da546Spatrick case ehframe_dwarf_fpu_stmm2:
983061da546Spatrick return fpu_stmm2;
984061da546Spatrick case ehframe_dwarf_fpu_stmm3:
985061da546Spatrick return fpu_stmm3;
986061da546Spatrick case ehframe_dwarf_fpu_stmm4:
987061da546Spatrick return fpu_stmm4;
988061da546Spatrick case ehframe_dwarf_fpu_stmm5:
989061da546Spatrick return fpu_stmm5;
990061da546Spatrick case ehframe_dwarf_fpu_stmm6:
991061da546Spatrick return fpu_stmm6;
992061da546Spatrick case ehframe_dwarf_fpu_stmm7:
993061da546Spatrick return fpu_stmm7;
994061da546Spatrick default:
995061da546Spatrick break;
996061da546Spatrick }
997061da546Spatrick } else if (kind == eRegisterKindLLDB) {
998061da546Spatrick return reg;
999061da546Spatrick }
1000061da546Spatrick return LLDB_INVALID_REGNUM;
1001061da546Spatrick }
1002061da546Spatrick
HardwareSingleStep(bool enable)1003061da546Spatrick bool RegisterContextDarwin_x86_64::HardwareSingleStep(bool enable) {
1004061da546Spatrick if (ReadGPR(true) != 0)
1005061da546Spatrick return false;
1006061da546Spatrick
1007061da546Spatrick const uint64_t trace_bit = 0x100ull;
1008061da546Spatrick if (enable) {
1009061da546Spatrick
1010061da546Spatrick if (gpr.rflags & trace_bit)
1011061da546Spatrick return true; // trace bit is already set, there is nothing to do
1012061da546Spatrick else
1013061da546Spatrick gpr.rflags |= trace_bit;
1014061da546Spatrick } else {
1015061da546Spatrick if (gpr.rflags & trace_bit)
1016061da546Spatrick gpr.rflags &= ~trace_bit;
1017061da546Spatrick else
1018061da546Spatrick return true; // trace bit is clear, there is nothing to do
1019061da546Spatrick }
1020061da546Spatrick
1021061da546Spatrick return WriteGPR() == 0;
1022061da546Spatrick }
1023