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
34using namespace lldb;
35using namespace lldb_private;
36
37enum
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
112enum 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
158enum 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
219RegisterContextDarwin_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
234RegisterContextDarwin_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
254static 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
320static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
321
322
323void
324RegisterContextDarwin_x86_64::InvalidateAllRegisters ()
325{
326    InvalidateAllRegisterStates();
327}
328
329
330size_t
331RegisterContextDarwin_x86_64::GetRegisterCount ()
332{
333    assert(k_num_register_infos == k_num_registers);
334    return k_num_registers;
335}
336
337
338const RegisterInfo *
339RegisterContextDarwin_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
348size_t
349RegisterContextDarwin_x86_64::GetRegisterInfosCount ()
350{
351    return k_num_register_infos;
352}
353
354const lldb_private::RegisterInfo *
355RegisterContextDarwin_x86_64::GetRegisterInfos ()
356{
357    return g_register_infos;
358}
359
360
361
362static 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
387static 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
425static uint32_t
426g_exc_regnums[] =
427{
428    exc_trapno,
429    exc_err,
430    exc_faultvaddr
431};
432
433// Number of registers in each register set
434const size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t);
435const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t);
436const 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//----------------------------------------------------------------------
443static 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
450const size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet);
451
452
453size_t
454RegisterContextDarwin_x86_64::GetRegisterSetCount ()
455{
456    return k_num_regsets;
457}
458
459const RegisterSet *
460RegisterContextDarwin_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
467int
468RegisterContextDarwin_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
479void
480RegisterContextDarwin_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
499int
500RegisterContextDarwin_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
510int
511RegisterContextDarwin_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
521int
522RegisterContextDarwin_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
532int
533RegisterContextDarwin_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
546int
547RegisterContextDarwin_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
560int
561RegisterContextDarwin_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
574int
575RegisterContextDarwin_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
587int
588RegisterContextDarwin_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
602bool
603RegisterContextDarwin_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
729bool
730RegisterContextDarwin_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
856bool
857RegisterContextDarwin_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
878bool
879RegisterContextDarwin_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
904uint32_t
905RegisterContextDarwin_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
1041bool
1042RegisterContextDarwin_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
1067