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