xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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