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