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