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