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