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