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 void RegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...) {
558   if (log) {
559     if (format) {
560       va_list args;
561       va_start(args, format);
562       log->VAPrintf(format, args);
563       va_end(args);
564     }
565     for (uint32_t i = 0; i < k_num_gpr_registers; i++) {
566       uint32_t reg = gpr_rax + i;
567       log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name,
568                   (&gpr.rax)[reg]);
569     }
570   }
571 }
572 
573 int RegisterContextDarwin_x86_64::ReadGPR(bool force) {
574   int set = GPRRegSet;
575   if (force || !RegisterSetIsCached(set)) {
576     SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
577   }
578   return GetError(GPRRegSet, Read);
579 }
580 
581 int RegisterContextDarwin_x86_64::ReadFPU(bool force) {
582   int set = FPURegSet;
583   if (force || !RegisterSetIsCached(set)) {
584     SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
585   }
586   return GetError(FPURegSet, Read);
587 }
588 
589 int RegisterContextDarwin_x86_64::ReadEXC(bool force) {
590   int set = EXCRegSet;
591   if (force || !RegisterSetIsCached(set)) {
592     SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
593   }
594   return GetError(EXCRegSet, Read);
595 }
596 
597 int RegisterContextDarwin_x86_64::WriteGPR() {
598   int set = GPRRegSet;
599   if (!RegisterSetIsCached(set)) {
600     SetError(set, Write, -1);
601     return -1;
602   }
603   SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
604   SetError(set, Read, -1);
605   return GetError(set, Write);
606 }
607 
608 int RegisterContextDarwin_x86_64::WriteFPU() {
609   int set = FPURegSet;
610   if (!RegisterSetIsCached(set)) {
611     SetError(set, Write, -1);
612     return -1;
613   }
614   SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
615   SetError(set, Read, -1);
616   return GetError(set, Write);
617 }
618 
619 int RegisterContextDarwin_x86_64::WriteEXC() {
620   int set = EXCRegSet;
621   if (!RegisterSetIsCached(set)) {
622     SetError(set, Write, -1);
623     return -1;
624   }
625   SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
626   SetError(set, Read, -1);
627   return GetError(set, Write);
628 }
629 
630 int RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force) {
631   switch (set) {
632   case GPRRegSet:
633     return ReadGPR(force);
634   case FPURegSet:
635     return ReadFPU(force);
636   case EXCRegSet:
637     return ReadEXC(force);
638   default:
639     break;
640   }
641   return -1;
642 }
643 
644 int RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set) {
645   // Make sure we have a valid context to set.
646   switch (set) {
647   case GPRRegSet:
648     return WriteGPR();
649   case FPURegSet:
650     return WriteFPU();
651   case EXCRegSet:
652     return WriteEXC();
653   default:
654     break;
655   }
656   return -1;
657 }
658 
659 bool RegisterContextDarwin_x86_64::ReadRegister(const RegisterInfo *reg_info,
660                                                 RegisterValue &value) {
661   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
662   int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
663   if (set == -1)
664     return false;
665 
666   if (ReadRegisterSet(set, false) != 0)
667     return false;
668 
669   switch (reg) {
670   case gpr_rax:
671   case gpr_rbx:
672   case gpr_rcx:
673   case gpr_rdx:
674   case gpr_rdi:
675   case gpr_rsi:
676   case gpr_rbp:
677   case gpr_rsp:
678   case gpr_r8:
679   case gpr_r9:
680   case gpr_r10:
681   case gpr_r11:
682   case gpr_r12:
683   case gpr_r13:
684   case gpr_r14:
685   case gpr_r15:
686   case gpr_rip:
687   case gpr_rflags:
688   case gpr_cs:
689   case gpr_fs:
690   case gpr_gs:
691     value = (&gpr.rax)[reg - gpr_rax];
692     break;
693 
694   case fpu_fcw:
695     value = fpu.fcw;
696     break;
697 
698   case fpu_fsw:
699     value = fpu.fsw;
700     break;
701 
702   case fpu_ftw:
703     value = fpu.ftw;
704     break;
705 
706   case fpu_fop:
707     value = fpu.fop;
708     break;
709 
710   case fpu_ip:
711     value = fpu.ip;
712     break;
713 
714   case fpu_cs:
715     value = fpu.cs;
716     break;
717 
718   case fpu_dp:
719     value = fpu.dp;
720     break;
721 
722   case fpu_ds:
723     value = fpu.ds;
724     break;
725 
726   case fpu_mxcsr:
727     value = fpu.mxcsr;
728     break;
729 
730   case fpu_mxcsrmask:
731     value = fpu.mxcsrmask;
732     break;
733 
734   case fpu_stmm0:
735   case fpu_stmm1:
736   case fpu_stmm2:
737   case fpu_stmm3:
738   case fpu_stmm4:
739   case fpu_stmm5:
740   case fpu_stmm6:
741   case fpu_stmm7:
742     value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size,
743                    endian::InlHostByteOrder());
744     break;
745 
746   case fpu_xmm0:
747   case fpu_xmm1:
748   case fpu_xmm2:
749   case fpu_xmm3:
750   case fpu_xmm4:
751   case fpu_xmm5:
752   case fpu_xmm6:
753   case fpu_xmm7:
754   case fpu_xmm8:
755   case fpu_xmm9:
756   case fpu_xmm10:
757   case fpu_xmm11:
758   case fpu_xmm12:
759   case fpu_xmm13:
760   case fpu_xmm14:
761   case fpu_xmm15:
762     value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size,
763                    endian::InlHostByteOrder());
764     break;
765 
766   case exc_trapno:
767     value = exc.trapno;
768     break;
769 
770   case exc_err:
771     value = exc.err;
772     break;
773 
774   case exc_faultvaddr:
775     value = exc.faultvaddr;
776     break;
777 
778   default:
779     return false;
780   }
781   return true;
782 }
783 
784 bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo *reg_info,
785                                                  const RegisterValue &value) {
786   const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
787   int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
788 
789   if (set == -1)
790     return false;
791 
792   if (ReadRegisterSet(set, false) != 0)
793     return false;
794 
795   switch (reg) {
796   case gpr_rax:
797   case gpr_rbx:
798   case gpr_rcx:
799   case gpr_rdx:
800   case gpr_rdi:
801   case gpr_rsi:
802   case gpr_rbp:
803   case gpr_rsp:
804   case gpr_r8:
805   case gpr_r9:
806   case gpr_r10:
807   case gpr_r11:
808   case gpr_r12:
809   case gpr_r13:
810   case gpr_r14:
811   case gpr_r15:
812   case gpr_rip:
813   case gpr_rflags:
814   case gpr_cs:
815   case gpr_fs:
816   case gpr_gs:
817     (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
818     break;
819 
820   case fpu_fcw:
821     fpu.fcw = value.GetAsUInt16();
822     break;
823 
824   case fpu_fsw:
825     fpu.fsw = value.GetAsUInt16();
826     break;
827 
828   case fpu_ftw:
829     fpu.ftw = value.GetAsUInt8();
830     break;
831 
832   case fpu_fop:
833     fpu.fop = value.GetAsUInt16();
834     break;
835 
836   case fpu_ip:
837     fpu.ip = value.GetAsUInt32();
838     break;
839 
840   case fpu_cs:
841     fpu.cs = value.GetAsUInt16();
842     break;
843 
844   case fpu_dp:
845     fpu.dp = value.GetAsUInt32();
846     break;
847 
848   case fpu_ds:
849     fpu.ds = value.GetAsUInt16();
850     break;
851 
852   case fpu_mxcsr:
853     fpu.mxcsr = value.GetAsUInt32();
854     break;
855 
856   case fpu_mxcsrmask:
857     fpu.mxcsrmask = value.GetAsUInt32();
858     break;
859 
860   case fpu_stmm0:
861   case fpu_stmm1:
862   case fpu_stmm2:
863   case fpu_stmm3:
864   case fpu_stmm4:
865   case fpu_stmm5:
866   case fpu_stmm6:
867   case fpu_stmm7:
868     ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
869              value.GetByteSize());
870     break;
871 
872   case fpu_xmm0:
873   case fpu_xmm1:
874   case fpu_xmm2:
875   case fpu_xmm3:
876   case fpu_xmm4:
877   case fpu_xmm5:
878   case fpu_xmm6:
879   case fpu_xmm7:
880   case fpu_xmm8:
881   case fpu_xmm9:
882   case fpu_xmm10:
883   case fpu_xmm11:
884   case fpu_xmm12:
885   case fpu_xmm13:
886   case fpu_xmm14:
887   case fpu_xmm15:
888     ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
889              value.GetByteSize());
890     return false;
891 
892   case exc_trapno:
893     exc.trapno = value.GetAsUInt32();
894     break;
895 
896   case exc_err:
897     exc.err = value.GetAsUInt32();
898     break;
899 
900   case exc_faultvaddr:
901     exc.faultvaddr = value.GetAsUInt64();
902     break;
903 
904   default:
905     return false;
906   }
907   return WriteRegisterSet(set) == 0;
908 }
909 
910 bool RegisterContextDarwin_x86_64::ReadAllRegisterValues(
911     lldb::DataBufferSP &data_sp) {
912   data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);
913   if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) {
914     uint8_t *dst = data_sp->GetBytes();
915     ::memcpy(dst, &gpr, sizeof(gpr));
916     dst += sizeof(gpr);
917 
918     ::memcpy(dst, &fpu, sizeof(fpu));
919     dst += sizeof(gpr);
920 
921     ::memcpy(dst, &exc, sizeof(exc));
922     return true;
923   }
924   return false;
925 }
926 
927 bool RegisterContextDarwin_x86_64::WriteAllRegisterValues(
928     const lldb::DataBufferSP &data_sp) {
929   if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
930     const uint8_t *src = data_sp->GetBytes();
931     ::memcpy(&gpr, src, sizeof(gpr));
932     src += sizeof(gpr);
933 
934     ::memcpy(&fpu, src, sizeof(fpu));
935     src += sizeof(gpr);
936 
937     ::memcpy(&exc, src, sizeof(exc));
938     uint32_t success_count = 0;
939     if (WriteGPR() == 0)
940       ++success_count;
941     if (WriteFPU() == 0)
942       ++success_count;
943     if (WriteEXC() == 0)
944       ++success_count;
945     return success_count == 3;
946   }
947   return false;
948 }
949 
950 uint32_t RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber(
951     lldb::RegisterKind kind, uint32_t reg) {
952   if (kind == eRegisterKindGeneric) {
953     switch (reg) {
954     case LLDB_REGNUM_GENERIC_PC:
955       return gpr_rip;
956     case LLDB_REGNUM_GENERIC_SP:
957       return gpr_rsp;
958     case LLDB_REGNUM_GENERIC_FP:
959       return gpr_rbp;
960     case LLDB_REGNUM_GENERIC_FLAGS:
961       return gpr_rflags;
962     case LLDB_REGNUM_GENERIC_RA:
963     default:
964       break;
965     }
966   } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
967     switch (reg) {
968     case ehframe_dwarf_gpr_rax:
969       return gpr_rax;
970     case ehframe_dwarf_gpr_rdx:
971       return gpr_rdx;
972     case ehframe_dwarf_gpr_rcx:
973       return gpr_rcx;
974     case ehframe_dwarf_gpr_rbx:
975       return gpr_rbx;
976     case ehframe_dwarf_gpr_rsi:
977       return gpr_rsi;
978     case ehframe_dwarf_gpr_rdi:
979       return gpr_rdi;
980     case ehframe_dwarf_gpr_rbp:
981       return gpr_rbp;
982     case ehframe_dwarf_gpr_rsp:
983       return gpr_rsp;
984     case ehframe_dwarf_gpr_r8:
985       return gpr_r8;
986     case ehframe_dwarf_gpr_r9:
987       return gpr_r9;
988     case ehframe_dwarf_gpr_r10:
989       return gpr_r10;
990     case ehframe_dwarf_gpr_r11:
991       return gpr_r11;
992     case ehframe_dwarf_gpr_r12:
993       return gpr_r12;
994     case ehframe_dwarf_gpr_r13:
995       return gpr_r13;
996     case ehframe_dwarf_gpr_r14:
997       return gpr_r14;
998     case ehframe_dwarf_gpr_r15:
999       return gpr_r15;
1000     case ehframe_dwarf_gpr_rip:
1001       return gpr_rip;
1002     case ehframe_dwarf_fpu_xmm0:
1003       return fpu_xmm0;
1004     case ehframe_dwarf_fpu_xmm1:
1005       return fpu_xmm1;
1006     case ehframe_dwarf_fpu_xmm2:
1007       return fpu_xmm2;
1008     case ehframe_dwarf_fpu_xmm3:
1009       return fpu_xmm3;
1010     case ehframe_dwarf_fpu_xmm4:
1011       return fpu_xmm4;
1012     case ehframe_dwarf_fpu_xmm5:
1013       return fpu_xmm5;
1014     case ehframe_dwarf_fpu_xmm6:
1015       return fpu_xmm6;
1016     case ehframe_dwarf_fpu_xmm7:
1017       return fpu_xmm7;
1018     case ehframe_dwarf_fpu_xmm8:
1019       return fpu_xmm8;
1020     case ehframe_dwarf_fpu_xmm9:
1021       return fpu_xmm9;
1022     case ehframe_dwarf_fpu_xmm10:
1023       return fpu_xmm10;
1024     case ehframe_dwarf_fpu_xmm11:
1025       return fpu_xmm11;
1026     case ehframe_dwarf_fpu_xmm12:
1027       return fpu_xmm12;
1028     case ehframe_dwarf_fpu_xmm13:
1029       return fpu_xmm13;
1030     case ehframe_dwarf_fpu_xmm14:
1031       return fpu_xmm14;
1032     case ehframe_dwarf_fpu_xmm15:
1033       return fpu_xmm15;
1034     case ehframe_dwarf_fpu_stmm0:
1035       return fpu_stmm0;
1036     case ehframe_dwarf_fpu_stmm1:
1037       return fpu_stmm1;
1038     case ehframe_dwarf_fpu_stmm2:
1039       return fpu_stmm2;
1040     case ehframe_dwarf_fpu_stmm3:
1041       return fpu_stmm3;
1042     case ehframe_dwarf_fpu_stmm4:
1043       return fpu_stmm4;
1044     case ehframe_dwarf_fpu_stmm5:
1045       return fpu_stmm5;
1046     case ehframe_dwarf_fpu_stmm6:
1047       return fpu_stmm6;
1048     case ehframe_dwarf_fpu_stmm7:
1049       return fpu_stmm7;
1050     default:
1051       break;
1052     }
1053   } else if (kind == eRegisterKindLLDB) {
1054     return reg;
1055   }
1056   return LLDB_INVALID_REGNUM;
1057 }
1058 
1059 bool RegisterContextDarwin_x86_64::HardwareSingleStep(bool enable) {
1060   if (ReadGPR(true) != 0)
1061     return false;
1062 
1063   const uint64_t trace_bit = 0x100ull;
1064   if (enable) {
1065 
1066     if (gpr.rflags & trace_bit)
1067       return true; // trace bit is already set, there is nothing to do
1068     else
1069       gpr.rflags |= trace_bit;
1070   } else {
1071     if (gpr.rflags & trace_bit)
1072       gpr.rflags &= ~trace_bit;
1073     else
1074       return true; // trace bit is clear, there is nothing to do
1075   }
1076 
1077   return WriteGPR() == 0;
1078 }
1079