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