1dda28197Spatrick //===-- RegisterContextDarwin_i386.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 "lldb/Utility/DataBufferHeap.h"
10061da546Spatrick #include "lldb/Utility/DataExtractor.h"
11061da546Spatrick #include "lldb/Utility/Endian.h"
12061da546Spatrick #include "lldb/Utility/Log.h"
13061da546Spatrick #include "lldb/Utility/RegisterValue.h"
14061da546Spatrick #include "lldb/Utility/Scalar.h"
15061da546Spatrick #include "llvm/ADT/STLExtras.h"
16061da546Spatrick #include "llvm/Support/Compiler.h"
17061da546Spatrick
18be691f3bSpatrick #include <cstddef>
19061da546Spatrick
20061da546Spatrick #include <memory>
21061da546Spatrick
22061da546Spatrick #include "RegisterContextDarwin_i386.h"
23061da546Spatrick
24061da546Spatrick using namespace lldb;
25061da546Spatrick using namespace lldb_private;
26061da546Spatrick
27061da546Spatrick enum {
28061da546Spatrick gpr_eax = 0,
29061da546Spatrick gpr_ebx,
30061da546Spatrick gpr_ecx,
31061da546Spatrick gpr_edx,
32061da546Spatrick gpr_edi,
33061da546Spatrick gpr_esi,
34061da546Spatrick gpr_ebp,
35061da546Spatrick gpr_esp,
36061da546Spatrick gpr_ss,
37061da546Spatrick gpr_eflags,
38061da546Spatrick gpr_eip,
39061da546Spatrick gpr_cs,
40061da546Spatrick gpr_ds,
41061da546Spatrick gpr_es,
42061da546Spatrick gpr_fs,
43061da546Spatrick gpr_gs,
44061da546Spatrick
45061da546Spatrick fpu_fcw,
46061da546Spatrick fpu_fsw,
47061da546Spatrick fpu_ftw,
48061da546Spatrick fpu_fop,
49061da546Spatrick fpu_ip,
50061da546Spatrick fpu_cs,
51061da546Spatrick fpu_dp,
52061da546Spatrick fpu_ds,
53061da546Spatrick fpu_mxcsr,
54061da546Spatrick fpu_mxcsrmask,
55061da546Spatrick fpu_stmm0,
56061da546Spatrick fpu_stmm1,
57061da546Spatrick fpu_stmm2,
58061da546Spatrick fpu_stmm3,
59061da546Spatrick fpu_stmm4,
60061da546Spatrick fpu_stmm5,
61061da546Spatrick fpu_stmm6,
62061da546Spatrick fpu_stmm7,
63061da546Spatrick fpu_xmm0,
64061da546Spatrick fpu_xmm1,
65061da546Spatrick fpu_xmm2,
66061da546Spatrick fpu_xmm3,
67061da546Spatrick fpu_xmm4,
68061da546Spatrick fpu_xmm5,
69061da546Spatrick fpu_xmm6,
70061da546Spatrick fpu_xmm7,
71061da546Spatrick
72061da546Spatrick exc_trapno,
73061da546Spatrick exc_err,
74061da546Spatrick exc_faultvaddr,
75061da546Spatrick
76061da546Spatrick k_num_registers,
77061da546Spatrick
78061da546Spatrick // Aliases
79061da546Spatrick fpu_fctrl = fpu_fcw,
80061da546Spatrick fpu_fstat = fpu_fsw,
81061da546Spatrick fpu_ftag = fpu_ftw,
82061da546Spatrick fpu_fiseg = fpu_cs,
83061da546Spatrick fpu_fioff = fpu_ip,
84061da546Spatrick fpu_foseg = fpu_ds,
85061da546Spatrick fpu_fooff = fpu_dp
86061da546Spatrick };
87061da546Spatrick
88061da546Spatrick enum {
89061da546Spatrick ehframe_eax = 0,
90061da546Spatrick ehframe_ecx,
91061da546Spatrick ehframe_edx,
92061da546Spatrick ehframe_ebx,
93061da546Spatrick ehframe_ebp,
94061da546Spatrick ehframe_esp,
95061da546Spatrick ehframe_esi,
96061da546Spatrick ehframe_edi,
97061da546Spatrick ehframe_eip,
98061da546Spatrick ehframe_eflags
99061da546Spatrick };
100061da546Spatrick
101061da546Spatrick enum {
102061da546Spatrick dwarf_eax = 0,
103061da546Spatrick dwarf_ecx,
104061da546Spatrick dwarf_edx,
105061da546Spatrick dwarf_ebx,
106061da546Spatrick dwarf_esp,
107061da546Spatrick dwarf_ebp,
108061da546Spatrick dwarf_esi,
109061da546Spatrick dwarf_edi,
110061da546Spatrick dwarf_eip,
111061da546Spatrick dwarf_eflags,
112061da546Spatrick dwarf_stmm0 = 11,
113061da546Spatrick dwarf_stmm1,
114061da546Spatrick dwarf_stmm2,
115061da546Spatrick dwarf_stmm3,
116061da546Spatrick dwarf_stmm4,
117061da546Spatrick dwarf_stmm5,
118061da546Spatrick dwarf_stmm6,
119061da546Spatrick dwarf_stmm7,
120061da546Spatrick dwarf_xmm0 = 21,
121061da546Spatrick dwarf_xmm1,
122061da546Spatrick dwarf_xmm2,
123061da546Spatrick dwarf_xmm3,
124061da546Spatrick dwarf_xmm4,
125061da546Spatrick dwarf_xmm5,
126061da546Spatrick dwarf_xmm6,
127061da546Spatrick dwarf_xmm7
128061da546Spatrick };
129061da546Spatrick
130061da546Spatrick #define GPR_OFFSET(reg) \
131061da546Spatrick (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::GPR, reg))
132061da546Spatrick #define FPU_OFFSET(reg) \
133061da546Spatrick (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::FPU, reg) + \
134061da546Spatrick sizeof(RegisterContextDarwin_i386::GPR))
135061da546Spatrick #define EXC_OFFSET(reg) \
136061da546Spatrick (LLVM_EXTENSION offsetof(RegisterContextDarwin_i386::EXC, reg) + \
137061da546Spatrick sizeof(RegisterContextDarwin_i386::GPR) + \
138061da546Spatrick sizeof(RegisterContextDarwin_i386::FPU))
139061da546Spatrick
140061da546Spatrick // These macros will auto define the register name, alt name, register size,
141061da546Spatrick // register offset, encoding, format and native register. This ensures that the
142061da546Spatrick // register state structures are defined correctly and have the correct sizes
143061da546Spatrick // and offsets.
144061da546Spatrick #define DEFINE_GPR(reg, alt) \
145061da546Spatrick #reg, alt, sizeof(((RegisterContextDarwin_i386::GPR *) NULL)->reg), \
146061da546Spatrick GPR_OFFSET(reg), eEncodingUint, eFormatHex
147061da546Spatrick #define DEFINE_FPU_UINT(reg) \
148061da546Spatrick #reg, NULL, sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg), \
149061da546Spatrick FPU_OFFSET(reg), eEncodingUint, eFormatHex
150061da546Spatrick #define DEFINE_FPU_VECT(reg, i) \
151061da546Spatrick #reg #i, NULL, \
152061da546Spatrick sizeof(((RegisterContextDarwin_i386::FPU *) NULL)->reg[i].bytes), \
153061da546Spatrick FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
154061da546Spatrick {LLDB_INVALID_REGNUM, dwarf_##reg##i, \
155061da546Spatrick LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
156061da546Spatrick fpu_##reg##i }, \
157*f6aab3d8Srobert nullptr, nullptr,
158061da546Spatrick
159061da546Spatrick #define DEFINE_EXC(reg) \
160061da546Spatrick #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *) NULL)->reg), \
161061da546Spatrick EXC_OFFSET(reg), eEncodingUint, eFormatHex
162061da546Spatrick #define REG_CONTEXT_SIZE \
163061da546Spatrick (sizeof(RegisterContextDarwin_i386::GPR) + \
164061da546Spatrick sizeof(RegisterContextDarwin_i386::FPU) + \
165061da546Spatrick sizeof(RegisterContextDarwin_i386::EXC))
166061da546Spatrick
167061da546Spatrick static RegisterInfo g_register_infos[] = {
168061da546Spatrick // Macro auto defines most stuff eh_frame DWARF
169061da546Spatrick // GENERIC PROCESS PLUGIN LLDB
170061da546Spatrick // =============================== =======================
171061da546Spatrick // =================== ========================= ==================
172061da546Spatrick // =================
173061da546Spatrick {DEFINE_GPR(eax, nullptr),
174061da546Spatrick {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
175061da546Spatrick gpr_eax},
176061da546Spatrick nullptr,
177061da546Spatrick nullptr,
178*f6aab3d8Srobert },
179061da546Spatrick {DEFINE_GPR(ebx, nullptr),
180061da546Spatrick {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
181061da546Spatrick gpr_ebx},
182061da546Spatrick nullptr,
183061da546Spatrick nullptr,
184*f6aab3d8Srobert },
185061da546Spatrick {DEFINE_GPR(ecx, nullptr),
186061da546Spatrick {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
187061da546Spatrick gpr_ecx},
188061da546Spatrick nullptr,
189061da546Spatrick nullptr,
190*f6aab3d8Srobert },
191061da546Spatrick {DEFINE_GPR(edx, nullptr),
192061da546Spatrick {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
193061da546Spatrick gpr_edx},
194061da546Spatrick nullptr,
195061da546Spatrick nullptr,
196*f6aab3d8Srobert },
197061da546Spatrick {DEFINE_GPR(edi, nullptr),
198061da546Spatrick {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
199061da546Spatrick gpr_edi},
200061da546Spatrick nullptr,
201061da546Spatrick nullptr,
202*f6aab3d8Srobert },
203061da546Spatrick {DEFINE_GPR(esi, nullptr),
204061da546Spatrick {ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
205061da546Spatrick gpr_esi},
206061da546Spatrick nullptr,
207061da546Spatrick nullptr,
208*f6aab3d8Srobert },
209061da546Spatrick {DEFINE_GPR(ebp, "fp"),
210061da546Spatrick {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
211061da546Spatrick gpr_ebp},
212061da546Spatrick nullptr,
213061da546Spatrick nullptr,
214*f6aab3d8Srobert },
215061da546Spatrick {DEFINE_GPR(esp, "sp"),
216061da546Spatrick {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
217061da546Spatrick gpr_esp},
218061da546Spatrick nullptr,
219061da546Spatrick nullptr,
220*f6aab3d8Srobert },
221061da546Spatrick {DEFINE_GPR(ss, nullptr),
222061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
223061da546Spatrick LLDB_INVALID_REGNUM, gpr_ss},
224061da546Spatrick nullptr,
225061da546Spatrick nullptr,
226*f6aab3d8Srobert },
227061da546Spatrick {DEFINE_GPR(eflags, "flags"),
228061da546Spatrick {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS,
229061da546Spatrick LLDB_INVALID_REGNUM, gpr_eflags},
230061da546Spatrick nullptr,
231061da546Spatrick nullptr,
232*f6aab3d8Srobert },
233061da546Spatrick {DEFINE_GPR(eip, "pc"),
234061da546Spatrick {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
235061da546Spatrick gpr_eip},
236061da546Spatrick nullptr,
237061da546Spatrick nullptr,
238*f6aab3d8Srobert },
239061da546Spatrick {DEFINE_GPR(cs, nullptr),
240061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
241061da546Spatrick LLDB_INVALID_REGNUM, gpr_cs},
242061da546Spatrick nullptr,
243061da546Spatrick nullptr,
244*f6aab3d8Srobert },
245061da546Spatrick {DEFINE_GPR(ds, nullptr),
246061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
247061da546Spatrick LLDB_INVALID_REGNUM, gpr_ds},
248061da546Spatrick nullptr,
249061da546Spatrick nullptr,
250*f6aab3d8Srobert },
251061da546Spatrick {DEFINE_GPR(es, nullptr),
252061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
253061da546Spatrick LLDB_INVALID_REGNUM, gpr_es},
254061da546Spatrick nullptr,
255061da546Spatrick nullptr,
256*f6aab3d8Srobert },
257061da546Spatrick {DEFINE_GPR(fs, nullptr),
258061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
259061da546Spatrick LLDB_INVALID_REGNUM, gpr_fs},
260061da546Spatrick nullptr,
261061da546Spatrick nullptr,
262*f6aab3d8Srobert },
263061da546Spatrick {DEFINE_GPR(gs, nullptr),
264061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
265061da546Spatrick LLDB_INVALID_REGNUM, gpr_gs},
266061da546Spatrick nullptr,
267061da546Spatrick nullptr,
268*f6aab3d8Srobert },
269061da546Spatrick
270061da546Spatrick {DEFINE_FPU_UINT(fcw),
271061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
272061da546Spatrick LLDB_INVALID_REGNUM, fpu_fcw},
273061da546Spatrick nullptr,
274061da546Spatrick nullptr,
275*f6aab3d8Srobert },
276061da546Spatrick {DEFINE_FPU_UINT(fsw),
277061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
278061da546Spatrick LLDB_INVALID_REGNUM, fpu_fsw},
279061da546Spatrick nullptr,
280061da546Spatrick nullptr,
281*f6aab3d8Srobert },
282061da546Spatrick {DEFINE_FPU_UINT(ftw),
283061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
284061da546Spatrick LLDB_INVALID_REGNUM, fpu_ftw},
285061da546Spatrick nullptr,
286061da546Spatrick nullptr,
287*f6aab3d8Srobert },
288061da546Spatrick {DEFINE_FPU_UINT(fop),
289061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
290061da546Spatrick LLDB_INVALID_REGNUM, fpu_fop},
291061da546Spatrick nullptr,
292061da546Spatrick nullptr,
293*f6aab3d8Srobert },
294061da546Spatrick {DEFINE_FPU_UINT(ip),
295061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
296061da546Spatrick LLDB_INVALID_REGNUM, fpu_ip},
297061da546Spatrick nullptr,
298061da546Spatrick nullptr,
299*f6aab3d8Srobert },
300061da546Spatrick {DEFINE_FPU_UINT(cs),
301061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
302061da546Spatrick LLDB_INVALID_REGNUM, fpu_cs},
303061da546Spatrick nullptr,
304061da546Spatrick nullptr,
305*f6aab3d8Srobert },
306061da546Spatrick {DEFINE_FPU_UINT(dp),
307061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
308061da546Spatrick LLDB_INVALID_REGNUM, fpu_dp},
309061da546Spatrick nullptr,
310061da546Spatrick nullptr,
311*f6aab3d8Srobert },
312061da546Spatrick {DEFINE_FPU_UINT(ds),
313061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
314061da546Spatrick LLDB_INVALID_REGNUM, fpu_ds},
315061da546Spatrick nullptr,
316061da546Spatrick nullptr,
317*f6aab3d8Srobert },
318061da546Spatrick {DEFINE_FPU_UINT(mxcsr),
319061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
320061da546Spatrick LLDB_INVALID_REGNUM, fpu_mxcsr},
321061da546Spatrick nullptr,
322061da546Spatrick nullptr,
323*f6aab3d8Srobert },
324061da546Spatrick {DEFINE_FPU_UINT(mxcsrmask),
325061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
326061da546Spatrick LLDB_INVALID_REGNUM, fpu_mxcsrmask},
327061da546Spatrick nullptr,
328061da546Spatrick nullptr,
329*f6aab3d8Srobert },
330061da546Spatrick {DEFINE_FPU_VECT(stmm, 0)},
331061da546Spatrick {DEFINE_FPU_VECT(stmm, 1)},
332061da546Spatrick {DEFINE_FPU_VECT(stmm, 2)},
333061da546Spatrick {DEFINE_FPU_VECT(stmm, 3)},
334061da546Spatrick {DEFINE_FPU_VECT(stmm, 4)},
335061da546Spatrick {DEFINE_FPU_VECT(stmm, 5)},
336061da546Spatrick {DEFINE_FPU_VECT(stmm, 6)},
337061da546Spatrick {DEFINE_FPU_VECT(stmm, 7)},
338061da546Spatrick {DEFINE_FPU_VECT(xmm, 0)},
339061da546Spatrick {DEFINE_FPU_VECT(xmm, 1)},
340061da546Spatrick {DEFINE_FPU_VECT(xmm, 2)},
341061da546Spatrick {DEFINE_FPU_VECT(xmm, 3)},
342061da546Spatrick {DEFINE_FPU_VECT(xmm, 4)},
343061da546Spatrick {DEFINE_FPU_VECT(xmm, 5)},
344061da546Spatrick {DEFINE_FPU_VECT(xmm, 6)},
345061da546Spatrick {DEFINE_FPU_VECT(xmm, 7)},
346061da546Spatrick
347061da546Spatrick {DEFINE_EXC(trapno),
348061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
349061da546Spatrick LLDB_INVALID_REGNUM, exc_trapno},
350061da546Spatrick nullptr,
351061da546Spatrick nullptr,
352*f6aab3d8Srobert },
353061da546Spatrick {DEFINE_EXC(err),
354061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
355061da546Spatrick LLDB_INVALID_REGNUM, exc_err},
356061da546Spatrick nullptr,
357061da546Spatrick nullptr,
358*f6aab3d8Srobert },
359061da546Spatrick {DEFINE_EXC(faultvaddr),
360061da546Spatrick {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
361061da546Spatrick LLDB_INVALID_REGNUM, exc_faultvaddr},
362061da546Spatrick nullptr,
363061da546Spatrick nullptr,
364*f6aab3d8Srobert }};
365061da546Spatrick
366*f6aab3d8Srobert static size_t k_num_register_infos = std::size(g_register_infos);
367061da546Spatrick
RegisterContextDarwin_i386(Thread & thread,uint32_t concrete_frame_idx)368061da546Spatrick RegisterContextDarwin_i386::RegisterContextDarwin_i386(
369061da546Spatrick Thread &thread, uint32_t concrete_frame_idx)
370061da546Spatrick : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
371061da546Spatrick uint32_t i;
372061da546Spatrick for (i = 0; i < kNumErrors; i++) {
373061da546Spatrick gpr_errs[i] = -1;
374061da546Spatrick fpu_errs[i] = -1;
375061da546Spatrick exc_errs[i] = -1;
376061da546Spatrick }
377061da546Spatrick }
378061da546Spatrick
379be691f3bSpatrick RegisterContextDarwin_i386::~RegisterContextDarwin_i386() = default;
380061da546Spatrick
InvalidateAllRegisters()381061da546Spatrick void RegisterContextDarwin_i386::InvalidateAllRegisters() {
382061da546Spatrick InvalidateAllRegisterStates();
383061da546Spatrick }
384061da546Spatrick
GetRegisterCount()385061da546Spatrick size_t RegisterContextDarwin_i386::GetRegisterCount() {
386061da546Spatrick assert(k_num_register_infos == k_num_registers);
387061da546Spatrick return k_num_registers;
388061da546Spatrick }
389061da546Spatrick
390061da546Spatrick const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)391061da546Spatrick RegisterContextDarwin_i386::GetRegisterInfoAtIndex(size_t reg) {
392061da546Spatrick assert(k_num_register_infos == k_num_registers);
393061da546Spatrick if (reg < k_num_registers)
394061da546Spatrick return &g_register_infos[reg];
395061da546Spatrick return nullptr;
396061da546Spatrick }
397061da546Spatrick
GetRegisterInfosCount()398061da546Spatrick size_t RegisterContextDarwin_i386::GetRegisterInfosCount() {
399061da546Spatrick return k_num_register_infos;
400061da546Spatrick }
401061da546Spatrick
GetRegisterInfos()402061da546Spatrick const RegisterInfo *RegisterContextDarwin_i386::GetRegisterInfos() {
403061da546Spatrick return g_register_infos;
404061da546Spatrick }
405061da546Spatrick
406061da546Spatrick // General purpose registers
407061da546Spatrick static uint32_t g_gpr_regnums[] = {
408061da546Spatrick gpr_eax, gpr_ebx, gpr_ecx, gpr_edx, gpr_edi, gpr_esi, gpr_ebp, gpr_esp,
409061da546Spatrick gpr_ss, gpr_eflags, gpr_eip, gpr_cs, gpr_ds, gpr_es, gpr_fs, gpr_gs};
410061da546Spatrick
411061da546Spatrick // Floating point registers
412061da546Spatrick static uint32_t g_fpu_regnums[] = {
413061da546Spatrick fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs,
414061da546Spatrick fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
415061da546Spatrick fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7,
416061da546Spatrick fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5,
417061da546Spatrick fpu_xmm6, fpu_xmm7};
418061da546Spatrick
419061da546Spatrick // Exception registers
420061da546Spatrick
421061da546Spatrick static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
422061da546Spatrick
423061da546Spatrick // Number of registers in each register set
424*f6aab3d8Srobert const size_t k_num_gpr_registers = std::size(g_gpr_regnums);
425*f6aab3d8Srobert const size_t k_num_fpu_registers = std::size(g_fpu_regnums);
426*f6aab3d8Srobert const size_t k_num_exc_registers = std::size(g_exc_regnums);
427061da546Spatrick
428061da546Spatrick // Register set definitions. The first definitions at register set index of
429061da546Spatrick // zero is for all registers, followed by other registers sets. The register
430061da546Spatrick // information for the all register set need not be filled in.
431061da546Spatrick static const RegisterSet g_reg_sets[] = {
432061da546Spatrick {
433061da546Spatrick "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
434061da546Spatrick },
435061da546Spatrick {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
436061da546Spatrick {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
437061da546Spatrick
438*f6aab3d8Srobert const size_t k_num_regsets = std::size(g_reg_sets);
439061da546Spatrick
GetRegisterSetCount()440061da546Spatrick size_t RegisterContextDarwin_i386::GetRegisterSetCount() {
441061da546Spatrick return k_num_regsets;
442061da546Spatrick }
443061da546Spatrick
GetRegisterSet(size_t reg_set)444061da546Spatrick const RegisterSet *RegisterContextDarwin_i386::GetRegisterSet(size_t reg_set) {
445061da546Spatrick if (reg_set < k_num_regsets)
446061da546Spatrick return &g_reg_sets[reg_set];
447061da546Spatrick return nullptr;
448061da546Spatrick }
449061da546Spatrick
450061da546Spatrick // Register information definitions for 32 bit i386.
GetSetForNativeRegNum(int reg_num)451061da546Spatrick int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) {
452061da546Spatrick if (reg_num < fpu_fcw)
453061da546Spatrick return GPRRegSet;
454061da546Spatrick else if (reg_num < exc_trapno)
455061da546Spatrick return FPURegSet;
456061da546Spatrick else if (reg_num < k_num_registers)
457061da546Spatrick return EXCRegSet;
458061da546Spatrick return -1;
459061da546Spatrick }
460061da546Spatrick
LogGPR(Log * log,const char * title)461061da546Spatrick void RegisterContextDarwin_i386::LogGPR(Log *log, const char *title) {
462061da546Spatrick if (log) {
463061da546Spatrick if (title)
464061da546Spatrick LLDB_LOGF(log, "%s", title);
465061da546Spatrick for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
466061da546Spatrick uint32_t reg = gpr_eax + i;
467061da546Spatrick LLDB_LOGF(log, "%12s = 0x%8.8x", g_register_infos[reg].name,
468061da546Spatrick (&gpr.eax)[reg]);
469061da546Spatrick }
470061da546Spatrick }
471061da546Spatrick }
472061da546Spatrick
ReadGPR(bool force)473061da546Spatrick int RegisterContextDarwin_i386::ReadGPR(bool force) {
474061da546Spatrick int set = GPRRegSet;
475061da546Spatrick if (force || !RegisterSetIsCached(set)) {
476061da546Spatrick SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
477061da546Spatrick }
478061da546Spatrick return GetError(set, Read);
479061da546Spatrick }
480061da546Spatrick
ReadFPU(bool force)481061da546Spatrick int RegisterContextDarwin_i386::ReadFPU(bool force) {
482061da546Spatrick int set = FPURegSet;
483061da546Spatrick if (force || !RegisterSetIsCached(set)) {
484061da546Spatrick SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
485061da546Spatrick }
486061da546Spatrick return GetError(set, Read);
487061da546Spatrick }
488061da546Spatrick
ReadEXC(bool force)489061da546Spatrick int RegisterContextDarwin_i386::ReadEXC(bool force) {
490061da546Spatrick int set = EXCRegSet;
491061da546Spatrick if (force || !RegisterSetIsCached(set)) {
492061da546Spatrick SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
493061da546Spatrick }
494061da546Spatrick return GetError(set, Read);
495061da546Spatrick }
496061da546Spatrick
WriteGPR()497061da546Spatrick int RegisterContextDarwin_i386::WriteGPR() {
498061da546Spatrick int set = GPRRegSet;
499061da546Spatrick if (!RegisterSetIsCached(set)) {
500061da546Spatrick SetError(set, Write, -1);
501061da546Spatrick return -1;
502061da546Spatrick }
503061da546Spatrick SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
504061da546Spatrick SetError(set, Read, -1);
505061da546Spatrick return GetError(set, Write);
506061da546Spatrick }
507061da546Spatrick
WriteFPU()508061da546Spatrick int RegisterContextDarwin_i386::WriteFPU() {
509061da546Spatrick int set = FPURegSet;
510061da546Spatrick if (!RegisterSetIsCached(set)) {
511061da546Spatrick SetError(set, Write, -1);
512061da546Spatrick return -1;
513061da546Spatrick }
514061da546Spatrick SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
515061da546Spatrick SetError(set, Read, -1);
516061da546Spatrick return GetError(set, Write);
517061da546Spatrick }
518061da546Spatrick
WriteEXC()519061da546Spatrick int RegisterContextDarwin_i386::WriteEXC() {
520061da546Spatrick int set = EXCRegSet;
521061da546Spatrick if (!RegisterSetIsCached(set)) {
522061da546Spatrick SetError(set, Write, -1);
523061da546Spatrick return -1;
524061da546Spatrick }
525061da546Spatrick SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
526061da546Spatrick SetError(set, Read, -1);
527061da546Spatrick return GetError(set, Write);
528061da546Spatrick }
529061da546Spatrick
ReadRegisterSet(uint32_t set,bool force)530061da546Spatrick int RegisterContextDarwin_i386::ReadRegisterSet(uint32_t set, bool force) {
531061da546Spatrick switch (set) {
532061da546Spatrick case GPRRegSet:
533061da546Spatrick return ReadGPR(force);
534061da546Spatrick case FPURegSet:
535061da546Spatrick return ReadFPU(force);
536061da546Spatrick case EXCRegSet:
537061da546Spatrick return ReadEXC(force);
538061da546Spatrick default:
539061da546Spatrick break;
540061da546Spatrick }
541061da546Spatrick return -1;
542061da546Spatrick }
543061da546Spatrick
WriteRegisterSet(uint32_t set)544061da546Spatrick int RegisterContextDarwin_i386::WriteRegisterSet(uint32_t set) {
545061da546Spatrick // Make sure we have a valid context to set.
546061da546Spatrick if (RegisterSetIsCached(set)) {
547061da546Spatrick switch (set) {
548061da546Spatrick case GPRRegSet:
549061da546Spatrick return WriteGPR();
550061da546Spatrick case FPURegSet:
551061da546Spatrick return WriteFPU();
552061da546Spatrick case EXCRegSet:
553061da546Spatrick return WriteEXC();
554061da546Spatrick default:
555061da546Spatrick break;
556061da546Spatrick }
557061da546Spatrick }
558061da546Spatrick return -1;
559061da546Spatrick }
560061da546Spatrick
ReadRegister(const RegisterInfo * reg_info,RegisterValue & value)561061da546Spatrick bool RegisterContextDarwin_i386::ReadRegister(const RegisterInfo *reg_info,
562061da546Spatrick RegisterValue &value) {
563061da546Spatrick const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
564061da546Spatrick int set = RegisterContextDarwin_i386::GetSetForNativeRegNum(reg);
565061da546Spatrick
566061da546Spatrick if (set == -1)
567061da546Spatrick return false;
568061da546Spatrick
569061da546Spatrick if (ReadRegisterSet(set, false) != 0)
570061da546Spatrick return false;
571061da546Spatrick
572061da546Spatrick switch (reg) {
573061da546Spatrick case gpr_eax:
574061da546Spatrick case gpr_ebx:
575061da546Spatrick case gpr_ecx:
576061da546Spatrick case gpr_edx:
577061da546Spatrick case gpr_edi:
578061da546Spatrick case gpr_esi:
579061da546Spatrick case gpr_ebp:
580061da546Spatrick case gpr_esp:
581061da546Spatrick case gpr_ss:
582061da546Spatrick case gpr_eflags:
583061da546Spatrick case gpr_eip:
584061da546Spatrick case gpr_cs:
585061da546Spatrick case gpr_ds:
586061da546Spatrick case gpr_es:
587061da546Spatrick case gpr_fs:
588061da546Spatrick case gpr_gs:
589061da546Spatrick value = (&gpr.eax)[reg - gpr_eax];
590061da546Spatrick break;
591061da546Spatrick
592061da546Spatrick case fpu_fcw:
593061da546Spatrick value = fpu.fcw;
594061da546Spatrick break;
595061da546Spatrick
596061da546Spatrick case fpu_fsw:
597061da546Spatrick value = fpu.fsw;
598061da546Spatrick break;
599061da546Spatrick
600061da546Spatrick case fpu_ftw:
601061da546Spatrick value = fpu.ftw;
602061da546Spatrick break;
603061da546Spatrick
604061da546Spatrick case fpu_fop:
605061da546Spatrick value = fpu.fop;
606061da546Spatrick break;
607061da546Spatrick
608061da546Spatrick case fpu_ip:
609061da546Spatrick value = fpu.ip;
610061da546Spatrick break;
611061da546Spatrick
612061da546Spatrick case fpu_cs:
613061da546Spatrick value = fpu.cs;
614061da546Spatrick break;
615061da546Spatrick
616061da546Spatrick case fpu_dp:
617061da546Spatrick value = fpu.dp;
618061da546Spatrick break;
619061da546Spatrick
620061da546Spatrick case fpu_ds:
621061da546Spatrick value = fpu.ds;
622061da546Spatrick break;
623061da546Spatrick
624061da546Spatrick case fpu_mxcsr:
625061da546Spatrick value = fpu.mxcsr;
626061da546Spatrick break;
627061da546Spatrick
628061da546Spatrick case fpu_mxcsrmask:
629061da546Spatrick value = fpu.mxcsrmask;
630061da546Spatrick break;
631061da546Spatrick
632061da546Spatrick case fpu_stmm0:
633061da546Spatrick case fpu_stmm1:
634061da546Spatrick case fpu_stmm2:
635061da546Spatrick case fpu_stmm3:
636061da546Spatrick case fpu_stmm4:
637061da546Spatrick case fpu_stmm5:
638061da546Spatrick case fpu_stmm6:
639061da546Spatrick case fpu_stmm7:
640061da546Spatrick // These values don't fit into scalar types,
641061da546Spatrick // RegisterContext::ReadRegisterBytes() must be used for these registers
642061da546Spatrick //::memcpy (reg_value.value.vector.uint8, fpu.stmm[reg - fpu_stmm0].bytes,
643061da546Spatrick //10);
644061da546Spatrick return false;
645061da546Spatrick
646061da546Spatrick case fpu_xmm0:
647061da546Spatrick case fpu_xmm1:
648061da546Spatrick case fpu_xmm2:
649061da546Spatrick case fpu_xmm3:
650061da546Spatrick case fpu_xmm4:
651061da546Spatrick case fpu_xmm5:
652061da546Spatrick case fpu_xmm6:
653061da546Spatrick case fpu_xmm7:
654061da546Spatrick // These values don't fit into scalar types,
655061da546Spatrick // RegisterContext::ReadRegisterBytes() must be used for these registers
656061da546Spatrick //::memcpy (reg_value.value.vector.uint8, fpu.xmm[reg - fpu_xmm0].bytes,
657061da546Spatrick //16);
658061da546Spatrick return false;
659061da546Spatrick
660061da546Spatrick case exc_trapno:
661061da546Spatrick value = exc.trapno;
662061da546Spatrick break;
663061da546Spatrick
664061da546Spatrick case exc_err:
665061da546Spatrick value = exc.err;
666061da546Spatrick break;
667061da546Spatrick
668061da546Spatrick case exc_faultvaddr:
669061da546Spatrick value = exc.faultvaddr;
670061da546Spatrick break;
671061da546Spatrick
672061da546Spatrick default:
673061da546Spatrick return false;
674061da546Spatrick }
675061da546Spatrick return true;
676061da546Spatrick }
677061da546Spatrick
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & value)678061da546Spatrick bool RegisterContextDarwin_i386::WriteRegister(const RegisterInfo *reg_info,
679061da546Spatrick const RegisterValue &value) {
680061da546Spatrick const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
681061da546Spatrick int set = GetSetForNativeRegNum(reg);
682061da546Spatrick
683061da546Spatrick if (set == -1)
684061da546Spatrick return false;
685061da546Spatrick
686061da546Spatrick if (ReadRegisterSet(set, false) != 0)
687061da546Spatrick return false;
688061da546Spatrick
689061da546Spatrick switch (reg) {
690061da546Spatrick case gpr_eax:
691061da546Spatrick case gpr_ebx:
692061da546Spatrick case gpr_ecx:
693061da546Spatrick case gpr_edx:
694061da546Spatrick case gpr_edi:
695061da546Spatrick case gpr_esi:
696061da546Spatrick case gpr_ebp:
697061da546Spatrick case gpr_esp:
698061da546Spatrick case gpr_ss:
699061da546Spatrick case gpr_eflags:
700061da546Spatrick case gpr_eip:
701061da546Spatrick case gpr_cs:
702061da546Spatrick case gpr_ds:
703061da546Spatrick case gpr_es:
704061da546Spatrick case gpr_fs:
705061da546Spatrick case gpr_gs:
706061da546Spatrick (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();
707061da546Spatrick break;
708061da546Spatrick
709061da546Spatrick case fpu_fcw:
710061da546Spatrick fpu.fcw = value.GetAsUInt16();
711061da546Spatrick break;
712061da546Spatrick
713061da546Spatrick case fpu_fsw:
714061da546Spatrick fpu.fsw = value.GetAsUInt16();
715061da546Spatrick break;
716061da546Spatrick
717061da546Spatrick case fpu_ftw:
718061da546Spatrick fpu.ftw = value.GetAsUInt8();
719061da546Spatrick break;
720061da546Spatrick
721061da546Spatrick case fpu_fop:
722061da546Spatrick fpu.fop = value.GetAsUInt16();
723061da546Spatrick break;
724061da546Spatrick
725061da546Spatrick case fpu_ip:
726061da546Spatrick fpu.ip = value.GetAsUInt32();
727061da546Spatrick break;
728061da546Spatrick
729061da546Spatrick case fpu_cs:
730061da546Spatrick fpu.cs = value.GetAsUInt16();
731061da546Spatrick break;
732061da546Spatrick
733061da546Spatrick case fpu_dp:
734061da546Spatrick fpu.dp = value.GetAsUInt32();
735061da546Spatrick break;
736061da546Spatrick
737061da546Spatrick case fpu_ds:
738061da546Spatrick fpu.ds = value.GetAsUInt16();
739061da546Spatrick break;
740061da546Spatrick
741061da546Spatrick case fpu_mxcsr:
742061da546Spatrick fpu.mxcsr = value.GetAsUInt32();
743061da546Spatrick break;
744061da546Spatrick
745061da546Spatrick case fpu_mxcsrmask:
746061da546Spatrick fpu.mxcsrmask = value.GetAsUInt32();
747061da546Spatrick break;
748061da546Spatrick
749061da546Spatrick case fpu_stmm0:
750061da546Spatrick case fpu_stmm1:
751061da546Spatrick case fpu_stmm2:
752061da546Spatrick case fpu_stmm3:
753061da546Spatrick case fpu_stmm4:
754061da546Spatrick case fpu_stmm5:
755061da546Spatrick case fpu_stmm6:
756061da546Spatrick case fpu_stmm7:
757061da546Spatrick // These values don't fit into scalar types,
758061da546Spatrick // RegisterContext::ReadRegisterBytes() must be used for these registers
759061da546Spatrick ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
760061da546Spatrick value.GetByteSize());
761061da546Spatrick return false;
762061da546Spatrick
763061da546Spatrick case fpu_xmm0:
764061da546Spatrick case fpu_xmm1:
765061da546Spatrick case fpu_xmm2:
766061da546Spatrick case fpu_xmm3:
767061da546Spatrick case fpu_xmm4:
768061da546Spatrick case fpu_xmm5:
769061da546Spatrick case fpu_xmm6:
770061da546Spatrick case fpu_xmm7:
771061da546Spatrick // These values don't fit into scalar types,
772061da546Spatrick // RegisterContext::ReadRegisterBytes() must be used for these registers
773061da546Spatrick ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
774061da546Spatrick value.GetByteSize());
775061da546Spatrick return false;
776061da546Spatrick
777061da546Spatrick case exc_trapno:
778061da546Spatrick exc.trapno = value.GetAsUInt32();
779061da546Spatrick break;
780061da546Spatrick
781061da546Spatrick case exc_err:
782061da546Spatrick exc.err = value.GetAsUInt32();
783061da546Spatrick break;
784061da546Spatrick
785061da546Spatrick case exc_faultvaddr:
786061da546Spatrick exc.faultvaddr = value.GetAsUInt32();
787061da546Spatrick break;
788061da546Spatrick
789061da546Spatrick default:
790061da546Spatrick return false;
791061da546Spatrick }
792061da546Spatrick return WriteRegisterSet(set) == 0;
793061da546Spatrick }
794061da546Spatrick
ReadAllRegisterValues(lldb::WritableDataBufferSP & data_sp)795061da546Spatrick bool RegisterContextDarwin_i386::ReadAllRegisterValues(
796*f6aab3d8Srobert lldb::WritableDataBufferSP &data_sp) {
797061da546Spatrick data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);
798061da546Spatrick if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) {
799061da546Spatrick uint8_t *dst = data_sp->GetBytes();
800061da546Spatrick ::memcpy(dst, &gpr, sizeof(gpr));
801061da546Spatrick dst += sizeof(gpr);
802061da546Spatrick
803061da546Spatrick ::memcpy(dst, &fpu, sizeof(fpu));
804061da546Spatrick dst += sizeof(gpr);
805061da546Spatrick
806061da546Spatrick ::memcpy(dst, &exc, sizeof(exc));
807061da546Spatrick return true;
808061da546Spatrick }
809061da546Spatrick return false;
810061da546Spatrick }
811061da546Spatrick
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)812061da546Spatrick bool RegisterContextDarwin_i386::WriteAllRegisterValues(
813061da546Spatrick const lldb::DataBufferSP &data_sp) {
814061da546Spatrick if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
815061da546Spatrick const uint8_t *src = data_sp->GetBytes();
816061da546Spatrick ::memcpy(&gpr, src, sizeof(gpr));
817061da546Spatrick src += sizeof(gpr);
818061da546Spatrick
819061da546Spatrick ::memcpy(&fpu, src, sizeof(fpu));
820061da546Spatrick src += sizeof(gpr);
821061da546Spatrick
822061da546Spatrick ::memcpy(&exc, src, sizeof(exc));
823061da546Spatrick uint32_t success_count = 0;
824061da546Spatrick if (WriteGPR() == 0)
825061da546Spatrick ++success_count;
826061da546Spatrick if (WriteFPU() == 0)
827061da546Spatrick ++success_count;
828061da546Spatrick if (WriteEXC() == 0)
829061da546Spatrick ++success_count;
830061da546Spatrick return success_count == 3;
831061da546Spatrick }
832061da546Spatrick return false;
833061da546Spatrick }
834061da546Spatrick
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t reg)835061da546Spatrick uint32_t RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber(
836061da546Spatrick lldb::RegisterKind kind, uint32_t reg) {
837061da546Spatrick if (kind == eRegisterKindGeneric) {
838061da546Spatrick switch (reg) {
839061da546Spatrick case LLDB_REGNUM_GENERIC_PC:
840061da546Spatrick return gpr_eip;
841061da546Spatrick case LLDB_REGNUM_GENERIC_SP:
842061da546Spatrick return gpr_esp;
843061da546Spatrick case LLDB_REGNUM_GENERIC_FP:
844061da546Spatrick return gpr_ebp;
845061da546Spatrick case LLDB_REGNUM_GENERIC_FLAGS:
846061da546Spatrick return gpr_eflags;
847061da546Spatrick case LLDB_REGNUM_GENERIC_RA:
848061da546Spatrick default:
849061da546Spatrick break;
850061da546Spatrick }
851061da546Spatrick } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
852061da546Spatrick switch (reg) {
853061da546Spatrick case dwarf_eax:
854061da546Spatrick return gpr_eax;
855061da546Spatrick case dwarf_ecx:
856061da546Spatrick return gpr_ecx;
857061da546Spatrick case dwarf_edx:
858061da546Spatrick return gpr_edx;
859061da546Spatrick case dwarf_ebx:
860061da546Spatrick return gpr_ebx;
861061da546Spatrick case dwarf_esp:
862061da546Spatrick return gpr_esp;
863061da546Spatrick case dwarf_ebp:
864061da546Spatrick return gpr_ebp;
865061da546Spatrick case dwarf_esi:
866061da546Spatrick return gpr_esi;
867061da546Spatrick case dwarf_edi:
868061da546Spatrick return gpr_edi;
869061da546Spatrick case dwarf_eip:
870061da546Spatrick return gpr_eip;
871061da546Spatrick case dwarf_eflags:
872061da546Spatrick return gpr_eflags;
873061da546Spatrick case dwarf_stmm0:
874061da546Spatrick return fpu_stmm0;
875061da546Spatrick case dwarf_stmm1:
876061da546Spatrick return fpu_stmm1;
877061da546Spatrick case dwarf_stmm2:
878061da546Spatrick return fpu_stmm2;
879061da546Spatrick case dwarf_stmm3:
880061da546Spatrick return fpu_stmm3;
881061da546Spatrick case dwarf_stmm4:
882061da546Spatrick return fpu_stmm4;
883061da546Spatrick case dwarf_stmm5:
884061da546Spatrick return fpu_stmm5;
885061da546Spatrick case dwarf_stmm6:
886061da546Spatrick return fpu_stmm6;
887061da546Spatrick case dwarf_stmm7:
888061da546Spatrick return fpu_stmm7;
889061da546Spatrick case dwarf_xmm0:
890061da546Spatrick return fpu_xmm0;
891061da546Spatrick case dwarf_xmm1:
892061da546Spatrick return fpu_xmm1;
893061da546Spatrick case dwarf_xmm2:
894061da546Spatrick return fpu_xmm2;
895061da546Spatrick case dwarf_xmm3:
896061da546Spatrick return fpu_xmm3;
897061da546Spatrick case dwarf_xmm4:
898061da546Spatrick return fpu_xmm4;
899061da546Spatrick case dwarf_xmm5:
900061da546Spatrick return fpu_xmm5;
901061da546Spatrick case dwarf_xmm6:
902061da546Spatrick return fpu_xmm6;
903061da546Spatrick case dwarf_xmm7:
904061da546Spatrick return fpu_xmm7;
905061da546Spatrick default:
906061da546Spatrick break;
907061da546Spatrick }
908061da546Spatrick } else if (kind == eRegisterKindLLDB) {
909061da546Spatrick return reg;
910061da546Spatrick }
911061da546Spatrick return LLDB_INVALID_REGNUM;
912061da546Spatrick }
913061da546Spatrick
HardwareSingleStep(bool enable)914061da546Spatrick bool RegisterContextDarwin_i386::HardwareSingleStep(bool enable) {
915061da546Spatrick if (ReadGPR(false) != 0)
916061da546Spatrick return false;
917061da546Spatrick
918061da546Spatrick const uint32_t trace_bit = 0x100u;
919061da546Spatrick if (enable) {
920061da546Spatrick // If the trace bit is already set, there is nothing to do
921061da546Spatrick if (gpr.eflags & trace_bit)
922061da546Spatrick return true;
923061da546Spatrick else
924061da546Spatrick gpr.eflags |= trace_bit;
925061da546Spatrick } else {
926061da546Spatrick // If the trace bit is already cleared, there is nothing to do
927061da546Spatrick if (gpr.eflags & trace_bit)
928061da546Spatrick gpr.eflags &= ~trace_bit;
929061da546Spatrick else
930061da546Spatrick return true;
931061da546Spatrick }
932061da546Spatrick
933061da546Spatrick return WriteGPR() == 0;
934061da546Spatrick }
935