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