1 //===-- RegisterContextDarwin_x86_64.cpp ----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <cinttypes>
10 #include <cstdarg>
11 #include <cstddef>
12 
13 #include <memory>
14 
15 #include "lldb/Utility/DataBufferHeap.h"
16 #include "lldb/Utility/DataExtractor.h"
17 #include "lldb/Utility/Endian.h"
18 #include "lldb/Utility/Log.h"
19 #include "lldb/Utility/RegisterValue.h"
20 #include "lldb/Utility/Scalar.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/Support/Compiler.h"
23 
24 #include "RegisterContextDarwin_x86_64.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 enum {
30   gpr_rax = 0,
31   gpr_rbx,
32   gpr_rcx,
33   gpr_rdx,
34   gpr_rdi,
35   gpr_rsi,
36   gpr_rbp,
37   gpr_rsp,
38   gpr_r8,
39   gpr_r9,
40   gpr_r10,
41   gpr_r11,
42   gpr_r12,
43   gpr_r13,
44   gpr_r14,
45   gpr_r15,
46   gpr_rip,
47   gpr_rflags,
48   gpr_cs,
49   gpr_fs,
50   gpr_gs,
51 
52   fpu_fcw,
53   fpu_fsw,
54   fpu_ftw,
55   fpu_fop,
56   fpu_ip,
57   fpu_cs,
58   fpu_dp,
59   fpu_ds,
60   fpu_mxcsr,
61   fpu_mxcsrmask,
62   fpu_stmm0,
63   fpu_stmm1,
64   fpu_stmm2,
65   fpu_stmm3,
66   fpu_stmm4,
67   fpu_stmm5,
68   fpu_stmm6,
69   fpu_stmm7,
70   fpu_xmm0,
71   fpu_xmm1,
72   fpu_xmm2,
73   fpu_xmm3,
74   fpu_xmm4,
75   fpu_xmm5,
76   fpu_xmm6,
77   fpu_xmm7,
78   fpu_xmm8,
79   fpu_xmm9,
80   fpu_xmm10,
81   fpu_xmm11,
82   fpu_xmm12,
83   fpu_xmm13,
84   fpu_xmm14,
85   fpu_xmm15,
86 
87   exc_trapno,
88   exc_err,
89   exc_faultvaddr,
90 
91   k_num_registers,
92 
93   // Aliases
94   fpu_fctrl = fpu_fcw,
95   fpu_fstat = fpu_fsw,
96   fpu_ftag = fpu_ftw,
97   fpu_fiseg = fpu_cs,
98   fpu_fioff = fpu_ip,
99   fpu_foseg = fpu_ds,
100   fpu_fooff = fpu_dp
101 };
102 
103 enum ehframe_dwarf_regnums {
104   ehframe_dwarf_gpr_rax = 0,
105   ehframe_dwarf_gpr_rdx,
106   ehframe_dwarf_gpr_rcx,
107   ehframe_dwarf_gpr_rbx,
108   ehframe_dwarf_gpr_rsi,
109   ehframe_dwarf_gpr_rdi,
110   ehframe_dwarf_gpr_rbp,
111   ehframe_dwarf_gpr_rsp,
112   ehframe_dwarf_gpr_r8,
113   ehframe_dwarf_gpr_r9,
114   ehframe_dwarf_gpr_r10,
115   ehframe_dwarf_gpr_r11,
116   ehframe_dwarf_gpr_r12,
117   ehframe_dwarf_gpr_r13,
118   ehframe_dwarf_gpr_r14,
119   ehframe_dwarf_gpr_r15,
120   ehframe_dwarf_gpr_rip,
121   ehframe_dwarf_fpu_xmm0,
122   ehframe_dwarf_fpu_xmm1,
123   ehframe_dwarf_fpu_xmm2,
124   ehframe_dwarf_fpu_xmm3,
125   ehframe_dwarf_fpu_xmm4,
126   ehframe_dwarf_fpu_xmm5,
127   ehframe_dwarf_fpu_xmm6,
128   ehframe_dwarf_fpu_xmm7,
129   ehframe_dwarf_fpu_xmm8,
130   ehframe_dwarf_fpu_xmm9,
131   ehframe_dwarf_fpu_xmm10,
132   ehframe_dwarf_fpu_xmm11,
133   ehframe_dwarf_fpu_xmm12,
134   ehframe_dwarf_fpu_xmm13,
135   ehframe_dwarf_fpu_xmm14,
136   ehframe_dwarf_fpu_xmm15,
137   ehframe_dwarf_fpu_stmm0,
138   ehframe_dwarf_fpu_stmm1,
139   ehframe_dwarf_fpu_stmm2,
140   ehframe_dwarf_fpu_stmm3,
141   ehframe_dwarf_fpu_stmm4,
142   ehframe_dwarf_fpu_stmm5,
143   ehframe_dwarf_fpu_stmm6,
144   ehframe_dwarf_fpu_stmm7
145 
146 };
147 
148 #define GPR_OFFSET(reg)                                                        \
149   (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::GPR, reg))
150 #define FPU_OFFSET(reg)                                                        \
151   (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::FPU, reg) +           \
152    sizeof(RegisterContextDarwin_x86_64::GPR))
153 #define EXC_OFFSET(reg)                                                        \
154   (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::EXC, reg) +           \
155    sizeof(RegisterContextDarwin_x86_64::GPR) +                                 \
156    sizeof(RegisterContextDarwin_x86_64::FPU))
157 
158 // These macros will auto define the register name, alt name, register size,
159 // register offset, encoding, format and native register. This ensures that the
160 // register state structures are defined correctly and have the correct sizes
161 // and offsets.
162 #define DEFINE_GPR(reg, alt)                                                   \
163   #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *) NULL)->reg),        \
164                     GPR_OFFSET(reg), eEncodingUint, eFormatHex
165 #define DEFINE_FPU_UINT(reg)                                                   \
166   #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg),       \
167                      FPU_OFFSET(reg), eEncodingUint, eFormatHex
168 #define DEFINE_FPU_VECT(reg, i)                                                \
169   #reg #i, NULL,                                                               \
170       sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg[i].bytes),      \
171               FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8,       \
172                          {ehframe_dwarf_fpu_##reg##i,                          \
173                           ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM,     \
174                           LLDB_INVALID_REGNUM, fpu_##reg##i },                 \
175                           nullptr, nullptr,
176 #define DEFINE_EXC(reg)                                                        \
177   #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *) NULL)->reg),       \
178                      EXC_OFFSET(reg), eEncodingUint, eFormatHex
179 
180 #define REG_CONTEXT_SIZE                                                       \
181   (sizeof(RegisterContextDarwin_x86_64::GPR) +                                 \
182    sizeof(RegisterContextDarwin_x86_64::FPU) +                                 \
183    sizeof(RegisterContextDarwin_x86_64::EXC))
184 
185 // General purpose registers for 64 bit
186 static RegisterInfo g_register_infos[] = {
187     //  Macro auto defines most stuff   EH_FRAME                    DWARF
188     //  GENERIC                    PROCESS PLUGIN       LLDB
189     //  =============================== ======================
190     //  ===================      ========================== ====================
191     //  ===================
192     {DEFINE_GPR(rax, nullptr),
193      {ehframe_dwarf_gpr_rax, ehframe_dwarf_gpr_rax, LLDB_INVALID_REGNUM,
194       LLDB_INVALID_REGNUM, gpr_rax},
195      nullptr,
196      nullptr,
197     },
198     {DEFINE_GPR(rbx, nullptr),
199      {ehframe_dwarf_gpr_rbx, ehframe_dwarf_gpr_rbx, LLDB_INVALID_REGNUM,
200       LLDB_INVALID_REGNUM, gpr_rbx},
201      nullptr,
202      nullptr,
203     },
204     {DEFINE_GPR(rcx, nullptr),
205      {ehframe_dwarf_gpr_rcx, ehframe_dwarf_gpr_rcx, LLDB_INVALID_REGNUM,
206       LLDB_INVALID_REGNUM, gpr_rcx},
207      nullptr,
208      nullptr,
209     },
210     {DEFINE_GPR(rdx, nullptr),
211      {ehframe_dwarf_gpr_rdx, ehframe_dwarf_gpr_rdx, LLDB_INVALID_REGNUM,
212       LLDB_INVALID_REGNUM, gpr_rdx},
213      nullptr,
214      nullptr,
215     },
216     {DEFINE_GPR(rdi, nullptr),
217      {ehframe_dwarf_gpr_rdi, ehframe_dwarf_gpr_rdi, LLDB_INVALID_REGNUM,
218       LLDB_INVALID_REGNUM, gpr_rdi},
219      nullptr,
220      nullptr,
221     },
222     {DEFINE_GPR(rsi, nullptr),
223      {ehframe_dwarf_gpr_rsi, ehframe_dwarf_gpr_rsi, LLDB_INVALID_REGNUM,
224       LLDB_INVALID_REGNUM, gpr_rsi},
225      nullptr,
226      nullptr,
227     },
228     {DEFINE_GPR(rbp, "fp"),
229      {ehframe_dwarf_gpr_rbp, ehframe_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP,
230       LLDB_INVALID_REGNUM, gpr_rbp},
231      nullptr,
232      nullptr,
233     },
234     {DEFINE_GPR(rsp, "sp"),
235      {ehframe_dwarf_gpr_rsp, ehframe_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP,
236       LLDB_INVALID_REGNUM, gpr_rsp},
237      nullptr,
238      nullptr,
239     },
240     {DEFINE_GPR(r8, nullptr),
241      {ehframe_dwarf_gpr_r8, ehframe_dwarf_gpr_r8, LLDB_INVALID_REGNUM,
242       LLDB_INVALID_REGNUM, gpr_r8},
243      nullptr,
244      nullptr,
245     },
246     {DEFINE_GPR(r9, nullptr),
247      {ehframe_dwarf_gpr_r9, ehframe_dwarf_gpr_r9, LLDB_INVALID_REGNUM,
248       LLDB_INVALID_REGNUM, gpr_r9},
249      nullptr,
250      nullptr,
251     },
252     {DEFINE_GPR(r10, nullptr),
253      {ehframe_dwarf_gpr_r10, ehframe_dwarf_gpr_r10, LLDB_INVALID_REGNUM,
254       LLDB_INVALID_REGNUM, gpr_r10},
255      nullptr,
256      nullptr,
257     },
258     {DEFINE_GPR(r11, nullptr),
259      {ehframe_dwarf_gpr_r11, ehframe_dwarf_gpr_r11, LLDB_INVALID_REGNUM,
260       LLDB_INVALID_REGNUM, gpr_r11},
261      nullptr,
262      nullptr,
263     },
264     {DEFINE_GPR(r12, nullptr),
265      {ehframe_dwarf_gpr_r12, ehframe_dwarf_gpr_r12, LLDB_INVALID_REGNUM,
266       LLDB_INVALID_REGNUM, gpr_r12},
267      nullptr,
268      nullptr,
269     },
270     {DEFINE_GPR(r13, nullptr),
271      {ehframe_dwarf_gpr_r13, ehframe_dwarf_gpr_r13, LLDB_INVALID_REGNUM,
272       LLDB_INVALID_REGNUM, gpr_r13},
273      nullptr,
274      nullptr,
275     },
276     {DEFINE_GPR(r14, nullptr),
277      {ehframe_dwarf_gpr_r14, ehframe_dwarf_gpr_r14, LLDB_INVALID_REGNUM,
278       LLDB_INVALID_REGNUM, gpr_r14},
279      nullptr,
280      nullptr,
281     },
282     {DEFINE_GPR(r15, nullptr),
283      {ehframe_dwarf_gpr_r15, ehframe_dwarf_gpr_r15, LLDB_INVALID_REGNUM,
284       LLDB_INVALID_REGNUM, gpr_r15},
285      nullptr,
286      nullptr,
287     },
288     {DEFINE_GPR(rip, "pc"),
289      {ehframe_dwarf_gpr_rip, ehframe_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC,
290       LLDB_INVALID_REGNUM, gpr_rip},
291      nullptr,
292      nullptr,
293     },
294     {DEFINE_GPR(rflags, "flags"),
295      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
296       LLDB_INVALID_REGNUM, gpr_rflags},
297      nullptr,
298      nullptr,
299     },
300     {DEFINE_GPR(cs, nullptr),
301      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
302       LLDB_INVALID_REGNUM, gpr_cs},
303      nullptr,
304      nullptr,
305     },
306     {DEFINE_GPR(fs, nullptr),
307      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
308       LLDB_INVALID_REGNUM, gpr_fs},
309      nullptr,
310      nullptr,
311     },
312     {DEFINE_GPR(gs, nullptr),
313      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
314       LLDB_INVALID_REGNUM, gpr_gs},
315      nullptr,
316      nullptr,
317     },
318 
319     {DEFINE_FPU_UINT(fcw),
320      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
321       LLDB_INVALID_REGNUM, fpu_fcw},
322      nullptr,
323      nullptr,
324     },
325     {DEFINE_FPU_UINT(fsw),
326      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
327       LLDB_INVALID_REGNUM, fpu_fsw},
328      nullptr,
329      nullptr,
330     },
331     {DEFINE_FPU_UINT(ftw),
332      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
333       LLDB_INVALID_REGNUM, fpu_ftw},
334      nullptr,
335      nullptr,
336     },
337     {DEFINE_FPU_UINT(fop),
338      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
339       LLDB_INVALID_REGNUM, fpu_fop},
340      nullptr,
341      nullptr,
342     },
343     {DEFINE_FPU_UINT(ip),
344      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
345       LLDB_INVALID_REGNUM, fpu_ip},
346      nullptr,
347      nullptr,
348     },
349     {DEFINE_FPU_UINT(cs),
350      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
351       LLDB_INVALID_REGNUM, fpu_cs},
352      nullptr,
353      nullptr,
354     },
355     {DEFINE_FPU_UINT(dp),
356      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
357       LLDB_INVALID_REGNUM, fpu_dp},
358      nullptr,
359      nullptr,
360     },
361     {DEFINE_FPU_UINT(ds),
362      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
363       LLDB_INVALID_REGNUM, fpu_ds},
364      nullptr,
365      nullptr,
366     },
367     {DEFINE_FPU_UINT(mxcsr),
368      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
369       LLDB_INVALID_REGNUM, fpu_mxcsr},
370      nullptr,
371      nullptr,
372     },
373     {DEFINE_FPU_UINT(mxcsrmask),
374      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
375       LLDB_INVALID_REGNUM, fpu_mxcsrmask},
376      nullptr,
377      nullptr,
378     },
379     {DEFINE_FPU_VECT(stmm, 0)},
380     {DEFINE_FPU_VECT(stmm, 1)},
381     {DEFINE_FPU_VECT(stmm, 2)},
382     {DEFINE_FPU_VECT(stmm, 3)},
383     {DEFINE_FPU_VECT(stmm, 4)},
384     {DEFINE_FPU_VECT(stmm, 5)},
385     {DEFINE_FPU_VECT(stmm, 6)},
386     {DEFINE_FPU_VECT(stmm, 7)},
387     {DEFINE_FPU_VECT(xmm, 0)},
388     {DEFINE_FPU_VECT(xmm, 1)},
389     {DEFINE_FPU_VECT(xmm, 2)},
390     {DEFINE_FPU_VECT(xmm, 3)},
391     {DEFINE_FPU_VECT(xmm, 4)},
392     {DEFINE_FPU_VECT(xmm, 5)},
393     {DEFINE_FPU_VECT(xmm, 6)},
394     {DEFINE_FPU_VECT(xmm, 7)},
395     {DEFINE_FPU_VECT(xmm, 8)},
396     {DEFINE_FPU_VECT(xmm, 9)},
397     {DEFINE_FPU_VECT(xmm, 10)},
398     {DEFINE_FPU_VECT(xmm, 11)},
399     {DEFINE_FPU_VECT(xmm, 12)},
400     {DEFINE_FPU_VECT(xmm, 13)},
401     {DEFINE_FPU_VECT(xmm, 14)},
402     {DEFINE_FPU_VECT(xmm, 15)},
403 
404     {DEFINE_EXC(trapno),
405      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
406       LLDB_INVALID_REGNUM, exc_trapno},
407      nullptr,
408      nullptr,
409     },
410     {DEFINE_EXC(err),
411      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
412       LLDB_INVALID_REGNUM, exc_err},
413      nullptr,
414      nullptr,
415     },
416     {DEFINE_EXC(faultvaddr),
417      {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
418       LLDB_INVALID_REGNUM, exc_faultvaddr},
419      nullptr,
420      nullptr,
421      }};
422 
423 static size_t k_num_register_infos = std::size(g_register_infos);
424 
425 RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64(
426     Thread &thread, uint32_t concrete_frame_idx)
427     : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
428   uint32_t i;
429   for (i = 0; i < kNumErrors; i++) {
430     gpr_errs[i] = -1;
431     fpu_errs[i] = -1;
432     exc_errs[i] = -1;
433   }
434 }
435 
436 RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() = default;
437 
438 void RegisterContextDarwin_x86_64::InvalidateAllRegisters() {
439   InvalidateAllRegisterStates();
440 }
441 
442 size_t RegisterContextDarwin_x86_64::GetRegisterCount() {
443   assert(k_num_register_infos == k_num_registers);
444   return k_num_registers;
445 }
446 
447 const RegisterInfo *
448 RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex(size_t reg) {
449   assert(k_num_register_infos == k_num_registers);
450   if (reg < k_num_registers)
451     return &g_register_infos[reg];
452   return nullptr;
453 }
454 
455 size_t RegisterContextDarwin_x86_64::GetRegisterInfosCount() {
456   return k_num_register_infos;
457 }
458 
459 const lldb_private::RegisterInfo *
460 RegisterContextDarwin_x86_64::GetRegisterInfos() {
461   return g_register_infos;
462 }
463 
464 static uint32_t g_gpr_regnums[] = {
465     gpr_rax, gpr_rbx, gpr_rcx, gpr_rdx,    gpr_rdi, gpr_rsi, gpr_rbp,
466     gpr_rsp, gpr_r8,  gpr_r9,  gpr_r10,    gpr_r11, gpr_r12, gpr_r13,
467     gpr_r14, gpr_r15, gpr_rip, gpr_rflags, gpr_cs,  gpr_fs,  gpr_gs};
468 
469 static uint32_t g_fpu_regnums[] = {
470     fpu_fcw,   fpu_fsw,   fpu_ftw,   fpu_fop,       fpu_ip,    fpu_cs,
471     fpu_dp,    fpu_ds,    fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
472     fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5,     fpu_stmm6, fpu_stmm7,
473     fpu_xmm0,  fpu_xmm1,  fpu_xmm2,  fpu_xmm3,      fpu_xmm4,  fpu_xmm5,
474     fpu_xmm6,  fpu_xmm7,  fpu_xmm8,  fpu_xmm9,      fpu_xmm10, fpu_xmm11,
475     fpu_xmm12, fpu_xmm13, fpu_xmm14, fpu_xmm15};
476 
477 static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
478 
479 // Number of registers in each register set
480 const size_t k_num_gpr_registers = std::size(g_gpr_regnums);
481 const size_t k_num_fpu_registers = std::size(g_fpu_regnums);
482 const size_t k_num_exc_registers = std::size(g_exc_regnums);
483 
484 // Register set definitions. The first definitions at register set index of
485 // zero is for all registers, followed by other registers sets. The register
486 // information for the all register set need not be filled in.
487 static const RegisterSet g_reg_sets[] = {
488     {
489         "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
490     },
491     {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
492     {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
493 
494 const size_t k_num_regsets = std::size(g_reg_sets);
495 
496 size_t RegisterContextDarwin_x86_64::GetRegisterSetCount() {
497   return k_num_regsets;
498 }
499 
500 const RegisterSet *
501 RegisterContextDarwin_x86_64::GetRegisterSet(size_t reg_set) {
502   if (reg_set < k_num_regsets)
503     return &g_reg_sets[reg_set];
504   return nullptr;
505 }
506 
507 int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num) {
508   if (reg_num < fpu_fcw)
509     return GPRRegSet;
510   else if (reg_num < exc_trapno)
511     return FPURegSet;
512   else if (reg_num < k_num_registers)
513     return EXCRegSet;
514   return -1;
515 }
516 
517 int RegisterContextDarwin_x86_64::ReadGPR(bool force) {
518   int set = GPRRegSet;
519   if (force || !RegisterSetIsCached(set)) {
520     SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
521   }
522   return GetError(GPRRegSet, Read);
523 }
524 
525 int RegisterContextDarwin_x86_64::ReadFPU(bool force) {
526   int set = FPURegSet;
527   if (force || !RegisterSetIsCached(set)) {
528     SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
529   }
530   return GetError(FPURegSet, Read);
531 }
532 
533 int RegisterContextDarwin_x86_64::ReadEXC(bool force) {
534   int set = EXCRegSet;
535   if (force || !RegisterSetIsCached(set)) {
536     SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
537   }
538   return GetError(EXCRegSet, Read);
539 }
540 
541 int RegisterContextDarwin_x86_64::WriteGPR() {
542   int set = GPRRegSet;
543   if (!RegisterSetIsCached(set)) {
544     SetError(set, Write, -1);
545     return -1;
546   }
547   SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
548   SetError(set, Read, -1);
549   return GetError(set, Write);
550 }
551 
552 int RegisterContextDarwin_x86_64::WriteFPU() {
553   int set = FPURegSet;
554   if (!RegisterSetIsCached(set)) {
555     SetError(set, Write, -1);
556     return -1;
557   }
558   SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
559   SetError(set, Read, -1);
560   return GetError(set, Write);
561 }
562 
563 int RegisterContextDarwin_x86_64::WriteEXC() {
564   int set = EXCRegSet;
565   if (!RegisterSetIsCached(set)) {
566     SetError(set, Write, -1);
567     return -1;
568   }
569   SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
570   SetError(set, Read, -1);
571   return GetError(set, Write);
572 }
573 
574 int RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force) {
575   switch (set) {
576   case GPRRegSet:
577     return ReadGPR(force);
578   case FPURegSet:
579     return ReadFPU(force);
580   case EXCRegSet:
581     return ReadEXC(force);
582   default:
583     break;
584   }
585   return -1;
586 }
587 
588 int RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set) {
589   // Make sure we have a valid context to set.
590   switch (set) {
591   case GPRRegSet:
592     return WriteGPR();
593   case FPURegSet:
594     return WriteFPU();
595   case EXCRegSet:
596     return WriteEXC();
597   default:
598     break;
599   }
600   return -1;
601 }
602 
603 bool RegisterContextDarwin_x86_64::ReadRegister(const RegisterInfo *reg_info,
604                                                 RegisterValue &value) {
605   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
606   int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
607   if (set == -1)
608     return false;
609 
610   if (ReadRegisterSet(set, false) != 0)
611     return false;
612 
613   switch (reg) {
614   case gpr_rax:
615   case gpr_rbx:
616   case gpr_rcx:
617   case gpr_rdx:
618   case gpr_rdi:
619   case gpr_rsi:
620   case gpr_rbp:
621   case gpr_rsp:
622   case gpr_r8:
623   case gpr_r9:
624   case gpr_r10:
625   case gpr_r11:
626   case gpr_r12:
627   case gpr_r13:
628   case gpr_r14:
629   case gpr_r15:
630   case gpr_rip:
631   case gpr_rflags:
632   case gpr_cs:
633   case gpr_fs:
634   case gpr_gs:
635     value = (&gpr.rax)[reg - gpr_rax];
636     break;
637 
638   case fpu_fcw:
639     value = fpu.fcw;
640     break;
641 
642   case fpu_fsw:
643     value = fpu.fsw;
644     break;
645 
646   case fpu_ftw:
647     value = fpu.ftw;
648     break;
649 
650   case fpu_fop:
651     value = fpu.fop;
652     break;
653 
654   case fpu_ip:
655     value = fpu.ip;
656     break;
657 
658   case fpu_cs:
659     value = fpu.cs;
660     break;
661 
662   case fpu_dp:
663     value = fpu.dp;
664     break;
665 
666   case fpu_ds:
667     value = fpu.ds;
668     break;
669 
670   case fpu_mxcsr:
671     value = fpu.mxcsr;
672     break;
673 
674   case fpu_mxcsrmask:
675     value = fpu.mxcsrmask;
676     break;
677 
678   case fpu_stmm0:
679   case fpu_stmm1:
680   case fpu_stmm2:
681   case fpu_stmm3:
682   case fpu_stmm4:
683   case fpu_stmm5:
684   case fpu_stmm6:
685   case fpu_stmm7:
686     value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size,
687                    endian::InlHostByteOrder());
688     break;
689 
690   case fpu_xmm0:
691   case fpu_xmm1:
692   case fpu_xmm2:
693   case fpu_xmm3:
694   case fpu_xmm4:
695   case fpu_xmm5:
696   case fpu_xmm6:
697   case fpu_xmm7:
698   case fpu_xmm8:
699   case fpu_xmm9:
700   case fpu_xmm10:
701   case fpu_xmm11:
702   case fpu_xmm12:
703   case fpu_xmm13:
704   case fpu_xmm14:
705   case fpu_xmm15:
706     value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size,
707                    endian::InlHostByteOrder());
708     break;
709 
710   case exc_trapno:
711     value = exc.trapno;
712     break;
713 
714   case exc_err:
715     value = exc.err;
716     break;
717 
718   case exc_faultvaddr:
719     value = exc.faultvaddr;
720     break;
721 
722   default:
723     return false;
724   }
725   return true;
726 }
727 
728 bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo *reg_info,
729                                                  const RegisterValue &value) {
730   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
731   int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
732 
733   if (set == -1)
734     return false;
735 
736   if (ReadRegisterSet(set, false) != 0)
737     return false;
738 
739   switch (reg) {
740   case gpr_rax:
741   case gpr_rbx:
742   case gpr_rcx:
743   case gpr_rdx:
744   case gpr_rdi:
745   case gpr_rsi:
746   case gpr_rbp:
747   case gpr_rsp:
748   case gpr_r8:
749   case gpr_r9:
750   case gpr_r10:
751   case gpr_r11:
752   case gpr_r12:
753   case gpr_r13:
754   case gpr_r14:
755   case gpr_r15:
756   case gpr_rip:
757   case gpr_rflags:
758   case gpr_cs:
759   case gpr_fs:
760   case gpr_gs:
761     (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
762     break;
763 
764   case fpu_fcw:
765     fpu.fcw = value.GetAsUInt16();
766     break;
767 
768   case fpu_fsw:
769     fpu.fsw = value.GetAsUInt16();
770     break;
771 
772   case fpu_ftw:
773     fpu.ftw = value.GetAsUInt8();
774     break;
775 
776   case fpu_fop:
777     fpu.fop = value.GetAsUInt16();
778     break;
779 
780   case fpu_ip:
781     fpu.ip = value.GetAsUInt32();
782     break;
783 
784   case fpu_cs:
785     fpu.cs = value.GetAsUInt16();
786     break;
787 
788   case fpu_dp:
789     fpu.dp = value.GetAsUInt32();
790     break;
791 
792   case fpu_ds:
793     fpu.ds = value.GetAsUInt16();
794     break;
795 
796   case fpu_mxcsr:
797     fpu.mxcsr = value.GetAsUInt32();
798     break;
799 
800   case fpu_mxcsrmask:
801     fpu.mxcsrmask = value.GetAsUInt32();
802     break;
803 
804   case fpu_stmm0:
805   case fpu_stmm1:
806   case fpu_stmm2:
807   case fpu_stmm3:
808   case fpu_stmm4:
809   case fpu_stmm5:
810   case fpu_stmm6:
811   case fpu_stmm7:
812     ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
813              value.GetByteSize());
814     break;
815 
816   case fpu_xmm0:
817   case fpu_xmm1:
818   case fpu_xmm2:
819   case fpu_xmm3:
820   case fpu_xmm4:
821   case fpu_xmm5:
822   case fpu_xmm6:
823   case fpu_xmm7:
824   case fpu_xmm8:
825   case fpu_xmm9:
826   case fpu_xmm10:
827   case fpu_xmm11:
828   case fpu_xmm12:
829   case fpu_xmm13:
830   case fpu_xmm14:
831   case fpu_xmm15:
832     ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
833              value.GetByteSize());
834     return false;
835 
836   case exc_trapno:
837     exc.trapno = value.GetAsUInt32();
838     break;
839 
840   case exc_err:
841     exc.err = value.GetAsUInt32();
842     break;
843 
844   case exc_faultvaddr:
845     exc.faultvaddr = value.GetAsUInt64();
846     break;
847 
848   default:
849     return false;
850   }
851   return WriteRegisterSet(set) == 0;
852 }
853 
854 bool RegisterContextDarwin_x86_64::ReadAllRegisterValues(
855     lldb::WritableDataBufferSP &data_sp) {
856   data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);
857   if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) {
858     uint8_t *dst = data_sp->GetBytes();
859     ::memcpy(dst, &gpr, sizeof(gpr));
860     dst += sizeof(gpr);
861 
862     ::memcpy(dst, &fpu, sizeof(fpu));
863     dst += sizeof(gpr);
864 
865     ::memcpy(dst, &exc, sizeof(exc));
866     return true;
867   }
868   return false;
869 }
870 
871 bool RegisterContextDarwin_x86_64::WriteAllRegisterValues(
872     const lldb::DataBufferSP &data_sp) {
873   if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
874     const uint8_t *src = data_sp->GetBytes();
875     ::memcpy(&gpr, src, sizeof(gpr));
876     src += sizeof(gpr);
877 
878     ::memcpy(&fpu, src, sizeof(fpu));
879     src += sizeof(gpr);
880 
881     ::memcpy(&exc, src, sizeof(exc));
882     uint32_t success_count = 0;
883     if (WriteGPR() == 0)
884       ++success_count;
885     if (WriteFPU() == 0)
886       ++success_count;
887     if (WriteEXC() == 0)
888       ++success_count;
889     return success_count == 3;
890   }
891   return false;
892 }
893 
894 uint32_t RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber(
895     lldb::RegisterKind kind, uint32_t reg) {
896   if (kind == eRegisterKindGeneric) {
897     switch (reg) {
898     case LLDB_REGNUM_GENERIC_PC:
899       return gpr_rip;
900     case LLDB_REGNUM_GENERIC_SP:
901       return gpr_rsp;
902     case LLDB_REGNUM_GENERIC_FP:
903       return gpr_rbp;
904     case LLDB_REGNUM_GENERIC_FLAGS:
905       return gpr_rflags;
906     case LLDB_REGNUM_GENERIC_RA:
907     default:
908       break;
909     }
910   } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
911     switch (reg) {
912     case ehframe_dwarf_gpr_rax:
913       return gpr_rax;
914     case ehframe_dwarf_gpr_rdx:
915       return gpr_rdx;
916     case ehframe_dwarf_gpr_rcx:
917       return gpr_rcx;
918     case ehframe_dwarf_gpr_rbx:
919       return gpr_rbx;
920     case ehframe_dwarf_gpr_rsi:
921       return gpr_rsi;
922     case ehframe_dwarf_gpr_rdi:
923       return gpr_rdi;
924     case ehframe_dwarf_gpr_rbp:
925       return gpr_rbp;
926     case ehframe_dwarf_gpr_rsp:
927       return gpr_rsp;
928     case ehframe_dwarf_gpr_r8:
929       return gpr_r8;
930     case ehframe_dwarf_gpr_r9:
931       return gpr_r9;
932     case ehframe_dwarf_gpr_r10:
933       return gpr_r10;
934     case ehframe_dwarf_gpr_r11:
935       return gpr_r11;
936     case ehframe_dwarf_gpr_r12:
937       return gpr_r12;
938     case ehframe_dwarf_gpr_r13:
939       return gpr_r13;
940     case ehframe_dwarf_gpr_r14:
941       return gpr_r14;
942     case ehframe_dwarf_gpr_r15:
943       return gpr_r15;
944     case ehframe_dwarf_gpr_rip:
945       return gpr_rip;
946     case ehframe_dwarf_fpu_xmm0:
947       return fpu_xmm0;
948     case ehframe_dwarf_fpu_xmm1:
949       return fpu_xmm1;
950     case ehframe_dwarf_fpu_xmm2:
951       return fpu_xmm2;
952     case ehframe_dwarf_fpu_xmm3:
953       return fpu_xmm3;
954     case ehframe_dwarf_fpu_xmm4:
955       return fpu_xmm4;
956     case ehframe_dwarf_fpu_xmm5:
957       return fpu_xmm5;
958     case ehframe_dwarf_fpu_xmm6:
959       return fpu_xmm6;
960     case ehframe_dwarf_fpu_xmm7:
961       return fpu_xmm7;
962     case ehframe_dwarf_fpu_xmm8:
963       return fpu_xmm8;
964     case ehframe_dwarf_fpu_xmm9:
965       return fpu_xmm9;
966     case ehframe_dwarf_fpu_xmm10:
967       return fpu_xmm10;
968     case ehframe_dwarf_fpu_xmm11:
969       return fpu_xmm11;
970     case ehframe_dwarf_fpu_xmm12:
971       return fpu_xmm12;
972     case ehframe_dwarf_fpu_xmm13:
973       return fpu_xmm13;
974     case ehframe_dwarf_fpu_xmm14:
975       return fpu_xmm14;
976     case ehframe_dwarf_fpu_xmm15:
977       return fpu_xmm15;
978     case ehframe_dwarf_fpu_stmm0:
979       return fpu_stmm0;
980     case ehframe_dwarf_fpu_stmm1:
981       return fpu_stmm1;
982     case ehframe_dwarf_fpu_stmm2:
983       return fpu_stmm2;
984     case ehframe_dwarf_fpu_stmm3:
985       return fpu_stmm3;
986     case ehframe_dwarf_fpu_stmm4:
987       return fpu_stmm4;
988     case ehframe_dwarf_fpu_stmm5:
989       return fpu_stmm5;
990     case ehframe_dwarf_fpu_stmm6:
991       return fpu_stmm6;
992     case ehframe_dwarf_fpu_stmm7:
993       return fpu_stmm7;
994     default:
995       break;
996     }
997   } else if (kind == eRegisterKindLLDB) {
998     return reg;
999   }
1000   return LLDB_INVALID_REGNUM;
1001 }
1002 
1003 bool RegisterContextDarwin_x86_64::HardwareSingleStep(bool enable) {
1004   if (ReadGPR(true) != 0)
1005     return false;
1006 
1007   const uint64_t trace_bit = 0x100ull;
1008   if (enable) {
1009 
1010     if (gpr.rflags & trace_bit)
1011       return true; // trace bit is already set, there is nothing to do
1012     else
1013       gpr.rflags |= trace_bit;
1014   } else {
1015     if (gpr.rflags & trace_bit)
1016       gpr.rflags &= ~trace_bit;
1017     else
1018       return true; // trace bit is clear, there is nothing to do
1019   }
1020 
1021   return WriteGPR() == 0;
1022 }
1023