1254721Semaste//===-- RegisterContextDarwin_x86_64.cpp ------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste
11254721Semaste// C Includes
12254721Semaste#include <stdarg.h>
13254721Semaste#include <stddef.h>  // offsetof
14254721Semaste
15254721Semaste// C++ Includes
16254721Semaste// Other libraries and framework includes
17254721Semaste#include "lldb/Core/DataBufferHeap.h"
18254721Semaste#include "lldb/Core/DataExtractor.h"
19254721Semaste#include "lldb/Core/Log.h"
20254721Semaste#include "lldb/Core/RegisterValue.h"
21254721Semaste#include "lldb/Core/Scalar.h"
22254721Semaste#include "lldb/Host/Endian.h"
23254721Semaste#include "llvm/Support/Compiler.h"
24254721Semaste
25254721Semaste// Support building against older versions of LLVM, this macro was added
26254721Semaste// recently.
27254721Semaste#ifndef LLVM_EXTENSION
28254721Semaste#define LLVM_EXTENSION
29254721Semaste#endif
30254721Semaste
31254721Semaste// Project includes
32254721Semaste#include "RegisterContextDarwin_x86_64.h"
33254721Semaste
34254721Semasteusing namespace lldb;
35254721Semasteusing namespace lldb_private;
36254721Semaste
37254721Semasteenum
38254721Semaste{
39254721Semaste    gpr_rax = 0,
40254721Semaste    gpr_rbx,
41254721Semaste    gpr_rcx,
42254721Semaste    gpr_rdx,
43254721Semaste    gpr_rdi,
44254721Semaste    gpr_rsi,
45254721Semaste    gpr_rbp,
46254721Semaste    gpr_rsp,
47254721Semaste    gpr_r8,
48254721Semaste    gpr_r9,
49254721Semaste    gpr_r10,
50254721Semaste    gpr_r11,
51254721Semaste    gpr_r12,
52254721Semaste    gpr_r13,
53254721Semaste    gpr_r14,
54254721Semaste    gpr_r15,
55254721Semaste    gpr_rip,
56254721Semaste    gpr_rflags,
57254721Semaste    gpr_cs,
58254721Semaste    gpr_fs,
59254721Semaste    gpr_gs,
60254721Semaste
61254721Semaste    fpu_fcw,
62254721Semaste    fpu_fsw,
63254721Semaste    fpu_ftw,
64254721Semaste    fpu_fop,
65254721Semaste    fpu_ip,
66254721Semaste    fpu_cs,
67254721Semaste    fpu_dp,
68254721Semaste    fpu_ds,
69254721Semaste    fpu_mxcsr,
70254721Semaste    fpu_mxcsrmask,
71254721Semaste    fpu_stmm0,
72254721Semaste    fpu_stmm1,
73254721Semaste    fpu_stmm2,
74254721Semaste    fpu_stmm3,
75254721Semaste    fpu_stmm4,
76254721Semaste    fpu_stmm5,
77254721Semaste    fpu_stmm6,
78254721Semaste    fpu_stmm7,
79254721Semaste    fpu_xmm0,
80254721Semaste    fpu_xmm1,
81254721Semaste    fpu_xmm2,
82254721Semaste    fpu_xmm3,
83254721Semaste    fpu_xmm4,
84254721Semaste    fpu_xmm5,
85254721Semaste    fpu_xmm6,
86254721Semaste    fpu_xmm7,
87254721Semaste    fpu_xmm8,
88254721Semaste    fpu_xmm9,
89254721Semaste    fpu_xmm10,
90254721Semaste    fpu_xmm11,
91254721Semaste    fpu_xmm12,
92254721Semaste    fpu_xmm13,
93254721Semaste    fpu_xmm14,
94254721Semaste    fpu_xmm15,
95254721Semaste
96254721Semaste    exc_trapno,
97254721Semaste    exc_err,
98254721Semaste    exc_faultvaddr,
99254721Semaste
100254721Semaste    k_num_registers,
101254721Semaste
102254721Semaste    // Aliases
103254721Semaste    fpu_fctrl = fpu_fcw,
104254721Semaste    fpu_fstat = fpu_fsw,
105254721Semaste    fpu_ftag  = fpu_ftw,
106254721Semaste    fpu_fiseg = fpu_cs,
107254721Semaste    fpu_fioff = fpu_ip,
108254721Semaste    fpu_foseg = fpu_ds,
109254721Semaste    fpu_fooff = fpu_dp
110254721Semaste};
111254721Semaste
112254721Semasteenum gcc_dwarf_regnums
113254721Semaste{
114254721Semaste    gcc_dwarf_gpr_rax = 0,
115254721Semaste    gcc_dwarf_gpr_rdx,
116254721Semaste    gcc_dwarf_gpr_rcx,
117254721Semaste    gcc_dwarf_gpr_rbx,
118254721Semaste    gcc_dwarf_gpr_rsi,
119254721Semaste    gcc_dwarf_gpr_rdi,
120254721Semaste    gcc_dwarf_gpr_rbp,
121254721Semaste    gcc_dwarf_gpr_rsp,
122254721Semaste    gcc_dwarf_gpr_r8,
123254721Semaste    gcc_dwarf_gpr_r9,
124254721Semaste    gcc_dwarf_gpr_r10,
125254721Semaste    gcc_dwarf_gpr_r11,
126254721Semaste    gcc_dwarf_gpr_r12,
127254721Semaste    gcc_dwarf_gpr_r13,
128254721Semaste    gcc_dwarf_gpr_r14,
129254721Semaste    gcc_dwarf_gpr_r15,
130254721Semaste    gcc_dwarf_gpr_rip,
131254721Semaste    gcc_dwarf_fpu_xmm0,
132254721Semaste    gcc_dwarf_fpu_xmm1,
133254721Semaste    gcc_dwarf_fpu_xmm2,
134254721Semaste    gcc_dwarf_fpu_xmm3,
135254721Semaste    gcc_dwarf_fpu_xmm4,
136254721Semaste    gcc_dwarf_fpu_xmm5,
137254721Semaste    gcc_dwarf_fpu_xmm6,
138254721Semaste    gcc_dwarf_fpu_xmm7,
139254721Semaste    gcc_dwarf_fpu_xmm8,
140254721Semaste    gcc_dwarf_fpu_xmm9,
141254721Semaste    gcc_dwarf_fpu_xmm10,
142254721Semaste    gcc_dwarf_fpu_xmm11,
143254721Semaste    gcc_dwarf_fpu_xmm12,
144254721Semaste    gcc_dwarf_fpu_xmm13,
145254721Semaste    gcc_dwarf_fpu_xmm14,
146254721Semaste    gcc_dwarf_fpu_xmm15,
147254721Semaste    gcc_dwarf_fpu_stmm0,
148254721Semaste    gcc_dwarf_fpu_stmm1,
149254721Semaste    gcc_dwarf_fpu_stmm2,
150254721Semaste    gcc_dwarf_fpu_stmm3,
151254721Semaste    gcc_dwarf_fpu_stmm4,
152254721Semaste    gcc_dwarf_fpu_stmm5,
153254721Semaste    gcc_dwarf_fpu_stmm6,
154254721Semaste    gcc_dwarf_fpu_stmm7
155254721Semaste
156254721Semaste};
157254721Semaste
158254721Semasteenum gdb_regnums
159254721Semaste{
160254721Semaste    gdb_gpr_rax     =   0,
161254721Semaste    gdb_gpr_rbx     =   1,
162254721Semaste    gdb_gpr_rcx     =   2,
163254721Semaste    gdb_gpr_rdx     =   3,
164254721Semaste    gdb_gpr_rsi     =   4,
165254721Semaste    gdb_gpr_rdi     =   5,
166254721Semaste    gdb_gpr_rbp     =   6,
167254721Semaste    gdb_gpr_rsp     =   7,
168254721Semaste    gdb_gpr_r8      =   8,
169254721Semaste    gdb_gpr_r9      =   9,
170254721Semaste    gdb_gpr_r10     =  10,
171254721Semaste    gdb_gpr_r11     =  11,
172254721Semaste    gdb_gpr_r12     =  12,
173254721Semaste    gdb_gpr_r13     =  13,
174254721Semaste    gdb_gpr_r14     =  14,
175254721Semaste    gdb_gpr_r15     =  15,
176254721Semaste    gdb_gpr_rip     =  16,
177254721Semaste    gdb_gpr_rflags  =  17,
178254721Semaste    gdb_gpr_cs      =  18,
179254721Semaste    gdb_gpr_ss      =  19,
180254721Semaste    gdb_gpr_ds      =  20,
181254721Semaste    gdb_gpr_es      =  21,
182254721Semaste    gdb_gpr_fs      =  22,
183254721Semaste    gdb_gpr_gs      =  23,
184254721Semaste    gdb_fpu_stmm0   =  24,
185254721Semaste    gdb_fpu_stmm1   =  25,
186254721Semaste    gdb_fpu_stmm2   =  26,
187254721Semaste    gdb_fpu_stmm3   =  27,
188254721Semaste    gdb_fpu_stmm4   =  28,
189254721Semaste    gdb_fpu_stmm5   =  29,
190254721Semaste    gdb_fpu_stmm6   =  30,
191254721Semaste    gdb_fpu_stmm7   =  31,
192254721Semaste    gdb_fpu_fctrl   =  32,  gdb_fpu_fcw = gdb_fpu_fctrl,
193254721Semaste    gdb_fpu_fstat   =  33,  gdb_fpu_fsw = gdb_fpu_fstat,
194254721Semaste    gdb_fpu_ftag    =  34,  gdb_fpu_ftw = gdb_fpu_ftag,
195254721Semaste    gdb_fpu_fiseg   =  35,  gdb_fpu_cs  = gdb_fpu_fiseg,
196254721Semaste    gdb_fpu_fioff   =  36,  gdb_fpu_ip  = gdb_fpu_fioff,
197254721Semaste    gdb_fpu_foseg   =  37,  gdb_fpu_ds  = gdb_fpu_foseg,
198254721Semaste    gdb_fpu_fooff   =  38,  gdb_fpu_dp  = gdb_fpu_fooff,
199254721Semaste    gdb_fpu_fop     =  39,
200254721Semaste    gdb_fpu_xmm0    =  40,
201254721Semaste    gdb_fpu_xmm1    =  41,
202254721Semaste    gdb_fpu_xmm2    =  42,
203254721Semaste    gdb_fpu_xmm3    =  43,
204254721Semaste    gdb_fpu_xmm4    =  44,
205254721Semaste    gdb_fpu_xmm5    =  45,
206254721Semaste    gdb_fpu_xmm6    =  46,
207254721Semaste    gdb_fpu_xmm7    =  47,
208254721Semaste    gdb_fpu_xmm8    =  48,
209254721Semaste    gdb_fpu_xmm9    =  49,
210254721Semaste    gdb_fpu_xmm10   =  50,
211254721Semaste    gdb_fpu_xmm11   =  51,
212254721Semaste    gdb_fpu_xmm12   =  52,
213254721Semaste    gdb_fpu_xmm13   =  53,
214254721Semaste    gdb_fpu_xmm14   =  54,
215254721Semaste    gdb_fpu_xmm15   =  55,
216254721Semaste    gdb_fpu_mxcsr   =  56
217254721Semaste};
218254721Semaste
219254721SemasteRegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64 (Thread &thread, uint32_t concrete_frame_idx) :
220254721Semaste    RegisterContext (thread, concrete_frame_idx),
221254721Semaste    gpr(),
222254721Semaste    fpu(),
223254721Semaste    exc()
224254721Semaste{
225254721Semaste    uint32_t i;
226254721Semaste    for (i=0; i<kNumErrors; i++)
227254721Semaste    {
228254721Semaste        gpr_errs[i] = -1;
229254721Semaste        fpu_errs[i] = -1;
230254721Semaste        exc_errs[i] = -1;
231254721Semaste    }
232254721Semaste}
233254721Semaste
234254721SemasteRegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64()
235254721Semaste{
236254721Semaste}
237254721Semaste
238254721Semaste#define GPR_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::GPR, reg))
239254721Semaste#define FPU_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::FPU, reg) + sizeof (RegisterContextDarwin_x86_64::GPR))
240254721Semaste#define EXC_OFFSET(reg) (LLVM_EXTENSION offsetof (RegisterContextDarwin_x86_64::EXC, reg) + sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU))
241254721Semaste
242254721Semaste// These macros will auto define the register name, alt name, register size,
243254721Semaste// register offset, encoding, format and native register. This ensures that
244254721Semaste// the register state structures are defined correctly and have the correct
245254721Semaste// sizes and offsets.
246254721Semaste#define DEFINE_GPR(reg, alt)    #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *)NULL)->reg), GPR_OFFSET(reg), eEncodingUint, eFormatHex
247254721Semaste#define DEFINE_FPU_UINT(reg)    #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *)NULL)->reg), FPU_OFFSET(reg), eEncodingUint, eFormatHex
248254721Semaste#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
249254721Semaste#define DEFINE_EXC(reg)         #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *)NULL)->reg), EXC_OFFSET(reg), eEncodingUint, eFormatHex
250254721Semaste
251254721Semaste#define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_x86_64::GPR) + sizeof (RegisterContextDarwin_x86_64::FPU) + sizeof (RegisterContextDarwin_x86_64::EXC))
252254721Semaste
253254721Semaste// General purpose registers for 64 bit
254254721Semastestatic RegisterInfo g_register_infos[] =
255254721Semaste{
256254721Semaste//  Macro auto defines most stuff   GCC                    DWARF                GENERIC                    GDB                  LLDB                VALUE REGS    INVALIDATE REGS
257254721Semaste//  =============================== ====================== ===================  ========================== ==================== =================== ==========    ===============
258254721Semaste    { DEFINE_GPR (rax   , NULL)     , { gcc_dwarf_gpr_rax  , gcc_dwarf_gpr_rax  , LLDB_INVALID_REGNUM      , gdb_gpr_rax        , gpr_rax       },       NULL,              NULL},
259254721Semaste    { DEFINE_GPR (rbx   , NULL)     , { gcc_dwarf_gpr_rbx  , gcc_dwarf_gpr_rbx  , LLDB_INVALID_REGNUM      , gdb_gpr_rbx        , gpr_rbx       },       NULL,              NULL},
260254721Semaste    { DEFINE_GPR (rcx   , NULL)     , { gcc_dwarf_gpr_rcx  , gcc_dwarf_gpr_rcx  , LLDB_INVALID_REGNUM      , gdb_gpr_rcx        , gpr_rcx       },       NULL,              NULL},
261254721Semaste    { DEFINE_GPR (rdx   , NULL)     , { gcc_dwarf_gpr_rdx  , gcc_dwarf_gpr_rdx  , LLDB_INVALID_REGNUM      , gdb_gpr_rdx        , gpr_rdx       },       NULL,              NULL},
262254721Semaste    { DEFINE_GPR (rdi   , NULL)     , { gcc_dwarf_gpr_rdi  , gcc_dwarf_gpr_rdi  , LLDB_INVALID_REGNUM      , gdb_gpr_rdi        , gpr_rdi       },       NULL,              NULL},
263254721Semaste    { DEFINE_GPR (rsi   , NULL)     , { gcc_dwarf_gpr_rsi  , gcc_dwarf_gpr_rsi  , LLDB_INVALID_REGNUM      , gdb_gpr_rsi        , gpr_rsi       },       NULL,              NULL},
264254721Semaste    { DEFINE_GPR (rbp   , "fp")     , { gcc_dwarf_gpr_rbp  , gcc_dwarf_gpr_rbp  , LLDB_REGNUM_GENERIC_FP   , gdb_gpr_rbp        , gpr_rbp       },       NULL,              NULL},
265254721Semaste    { DEFINE_GPR (rsp   , "sp")     , { gcc_dwarf_gpr_rsp  , gcc_dwarf_gpr_rsp  , LLDB_REGNUM_GENERIC_SP   , gdb_gpr_rsp        , gpr_rsp       },       NULL,              NULL},
266254721Semaste    { DEFINE_GPR (r8    , NULL)     , { gcc_dwarf_gpr_r8   , gcc_dwarf_gpr_r8   , LLDB_INVALID_REGNUM      , gdb_gpr_r8         , gpr_r8        },       NULL,              NULL},
267254721Semaste    { DEFINE_GPR (r9    , NULL)     , { gcc_dwarf_gpr_r9   , gcc_dwarf_gpr_r9   , LLDB_INVALID_REGNUM      , gdb_gpr_r9         , gpr_r9        },       NULL,              NULL},
268254721Semaste    { DEFINE_GPR (r10   , NULL)     , { gcc_dwarf_gpr_r10  , gcc_dwarf_gpr_r10  , LLDB_INVALID_REGNUM      , gdb_gpr_r10        , gpr_r10       },       NULL,              NULL},
269254721Semaste    { DEFINE_GPR (r11   , NULL)     , { gcc_dwarf_gpr_r11  , gcc_dwarf_gpr_r11  , LLDB_INVALID_REGNUM      , gdb_gpr_r11        , gpr_r11       },       NULL,              NULL},
270254721Semaste    { DEFINE_GPR (r12   , NULL)     , { gcc_dwarf_gpr_r12  , gcc_dwarf_gpr_r12  , LLDB_INVALID_REGNUM      , gdb_gpr_r12        , gpr_r12       },       NULL,              NULL},
271254721Semaste    { DEFINE_GPR (r13   , NULL)     , { gcc_dwarf_gpr_r13  , gcc_dwarf_gpr_r13  , LLDB_INVALID_REGNUM      , gdb_gpr_r13        , gpr_r13       },       NULL,              NULL},
272254721Semaste    { DEFINE_GPR (r14   , NULL)     , { gcc_dwarf_gpr_r14  , gcc_dwarf_gpr_r14  , LLDB_INVALID_REGNUM      , gdb_gpr_r14        , gpr_r14       },       NULL,              NULL},
273254721Semaste    { DEFINE_GPR (r15   , NULL)     , { gcc_dwarf_gpr_r15  , gcc_dwarf_gpr_r15  , LLDB_INVALID_REGNUM      , gdb_gpr_r15        , gpr_r15       },       NULL,              NULL},
274254721Semaste    { DEFINE_GPR (rip   , "pc")     , { gcc_dwarf_gpr_rip  , gcc_dwarf_gpr_rip  , LLDB_REGNUM_GENERIC_PC   , gdb_gpr_rip        , gpr_rip       },       NULL,              NULL},
275254721Semaste    { DEFINE_GPR (rflags, "flags")  , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_gpr_rflags     , gpr_rflags    },       NULL,              NULL},
276254721Semaste    { DEFINE_GPR (cs    , NULL)     , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_gpr_cs         , gpr_cs        },       NULL,              NULL},
277254721Semaste    { DEFINE_GPR (fs    , NULL)     , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_gpr_fs         , gpr_fs        },       NULL,              NULL},
278254721Semaste    { DEFINE_GPR (gs    , NULL)     , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_gpr_gs         , gpr_gs        },       NULL,              NULL},
279254721Semaste
280254721Semaste    { DEFINE_FPU_UINT(fcw)          , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_fcw        , fpu_fcw       },       NULL,              NULL},
281254721Semaste    { DEFINE_FPU_UINT(fsw)          , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_fsw        , fpu_fsw       },       NULL,              NULL},
282254721Semaste    { DEFINE_FPU_UINT(ftw)          , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_ftw        , fpu_ftw       },       NULL,              NULL},
283254721Semaste    { DEFINE_FPU_UINT(fop)          , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_fop        , fpu_fop       },       NULL,              NULL},
284254721Semaste    { DEFINE_FPU_UINT(ip)           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_ip         , fpu_ip        },       NULL,              NULL},
285254721Semaste    { DEFINE_FPU_UINT(cs)           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_cs         , fpu_cs        },       NULL,              NULL},
286254721Semaste    { DEFINE_FPU_UINT(dp)           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_dp         , fpu_dp        },       NULL,              NULL},
287254721Semaste    { DEFINE_FPU_UINT(ds)           , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_ds         , fpu_ds        },       NULL,              NULL},
288254721Semaste    { DEFINE_FPU_UINT(mxcsr)        , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , gdb_fpu_mxcsr      , fpu_mxcsr     },       NULL,              NULL},
289254721Semaste    { DEFINE_FPU_UINT(mxcsrmask)    , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM, fpu_mxcsrmask },       NULL,              NULL},
290254721Semaste    { DEFINE_FPU_VECT(stmm,0)   },
291254721Semaste    { DEFINE_FPU_VECT(stmm,1)   },
292254721Semaste    { DEFINE_FPU_VECT(stmm,2)   },
293254721Semaste    { DEFINE_FPU_VECT(stmm,3)   },
294254721Semaste    { DEFINE_FPU_VECT(stmm,4)   },
295254721Semaste    { DEFINE_FPU_VECT(stmm,5)   },
296254721Semaste    { DEFINE_FPU_VECT(stmm,6)   },
297254721Semaste    { DEFINE_FPU_VECT(stmm,7)   },
298254721Semaste    { DEFINE_FPU_VECT(xmm,0)    },
299254721Semaste    { DEFINE_FPU_VECT(xmm,1)    },
300254721Semaste    { DEFINE_FPU_VECT(xmm,2)    },
301254721Semaste    { DEFINE_FPU_VECT(xmm,3)    },
302254721Semaste    { DEFINE_FPU_VECT(xmm,4)    },
303254721Semaste    { DEFINE_FPU_VECT(xmm,5)    },
304254721Semaste    { DEFINE_FPU_VECT(xmm,6)    },
305254721Semaste    { DEFINE_FPU_VECT(xmm,7)    },
306254721Semaste    { DEFINE_FPU_VECT(xmm,8)    },
307254721Semaste    { DEFINE_FPU_VECT(xmm,9)    },
308254721Semaste    { DEFINE_FPU_VECT(xmm,10)   },
309254721Semaste    { DEFINE_FPU_VECT(xmm,11)   },
310254721Semaste    { DEFINE_FPU_VECT(xmm,12)   },
311254721Semaste    { DEFINE_FPU_VECT(xmm,13)   },
312254721Semaste    { DEFINE_FPU_VECT(xmm,14)   },
313254721Semaste    { DEFINE_FPU_VECT(xmm,15)   },
314254721Semaste
315254721Semaste    { DEFINE_EXC(trapno)            , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM, exc_trapno     },      NULL,              NULL},
316254721Semaste    { DEFINE_EXC(err)               , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM, exc_err        },      NULL,              NULL},
317254721Semaste    { DEFINE_EXC(faultvaddr)        , { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM      , LLDB_INVALID_REGNUM, exc_faultvaddr },      NULL,              NULL}
318254721Semaste};
319254721Semaste
320254721Semastestatic size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
321254721Semaste
322254721Semaste
323254721Semastevoid
324254721SemasteRegisterContextDarwin_x86_64::InvalidateAllRegisters ()
325254721Semaste{
326254721Semaste    InvalidateAllRegisterStates();
327254721Semaste}
328254721Semaste
329254721Semaste
330254721Semastesize_t
331254721SemasteRegisterContextDarwin_x86_64::GetRegisterCount ()
332254721Semaste{
333254721Semaste    assert(k_num_register_infos == k_num_registers);
334254721Semaste    return k_num_registers;
335254721Semaste}
336254721Semaste
337254721Semaste
338254721Semasteconst RegisterInfo *
339254721SemasteRegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (size_t reg)
340254721Semaste{
341254721Semaste    assert(k_num_register_infos == k_num_registers);
342254721Semaste    if (reg < k_num_registers)
343254721Semaste        return &g_register_infos[reg];
344254721Semaste    return NULL;
345254721Semaste}
346254721Semaste
347254721Semaste
348254721Semastesize_t
349254721SemasteRegisterContextDarwin_x86_64::GetRegisterInfosCount ()
350254721Semaste{
351254721Semaste    return k_num_register_infos;
352254721Semaste}
353254721Semaste
354254721Semasteconst lldb_private::RegisterInfo *
355254721SemasteRegisterContextDarwin_x86_64::GetRegisterInfos ()
356254721Semaste{
357254721Semaste    return g_register_infos;
358254721Semaste}
359254721Semaste
360254721Semaste
361254721Semaste
362254721Semastestatic uint32_t g_gpr_regnums[] =
363254721Semaste{
364254721Semaste    gpr_rax,
365254721Semaste    gpr_rbx,
366254721Semaste    gpr_rcx,
367254721Semaste    gpr_rdx,
368254721Semaste    gpr_rdi,
369254721Semaste    gpr_rsi,
370254721Semaste    gpr_rbp,
371254721Semaste    gpr_rsp,
372254721Semaste    gpr_r8,
373254721Semaste    gpr_r9,
374254721Semaste    gpr_r10,
375254721Semaste    gpr_r11,
376254721Semaste    gpr_r12,
377254721Semaste    gpr_r13,
378254721Semaste    gpr_r14,
379254721Semaste    gpr_r15,
380254721Semaste    gpr_rip,
381254721Semaste    gpr_rflags,
382254721Semaste    gpr_cs,
383254721Semaste    gpr_fs,
384254721Semaste    gpr_gs
385254721Semaste};
386254721Semaste
387254721Semastestatic uint32_t g_fpu_regnums[] =
388254721Semaste{
389254721Semaste    fpu_fcw,
390254721Semaste    fpu_fsw,
391254721Semaste    fpu_ftw,
392254721Semaste    fpu_fop,
393254721Semaste    fpu_ip,
394254721Semaste    fpu_cs,
395254721Semaste    fpu_dp,
396254721Semaste    fpu_ds,
397254721Semaste    fpu_mxcsr,
398254721Semaste    fpu_mxcsrmask,
399254721Semaste    fpu_stmm0,
400254721Semaste    fpu_stmm1,
401254721Semaste    fpu_stmm2,
402254721Semaste    fpu_stmm3,
403254721Semaste    fpu_stmm4,
404254721Semaste    fpu_stmm5,
405254721Semaste    fpu_stmm6,
406254721Semaste    fpu_stmm7,
407254721Semaste    fpu_xmm0,
408254721Semaste    fpu_xmm1,
409254721Semaste    fpu_xmm2,
410254721Semaste    fpu_xmm3,
411254721Semaste    fpu_xmm4,
412254721Semaste    fpu_xmm5,
413254721Semaste    fpu_xmm6,
414254721Semaste    fpu_xmm7,
415254721Semaste    fpu_xmm8,
416254721Semaste    fpu_xmm9,
417254721Semaste    fpu_xmm10,
418254721Semaste    fpu_xmm11,
419254721Semaste    fpu_xmm12,
420254721Semaste    fpu_xmm13,
421254721Semaste    fpu_xmm14,
422254721Semaste    fpu_xmm15
423254721Semaste};
424254721Semaste
425254721Semastestatic uint32_t
426254721Semasteg_exc_regnums[] =
427254721Semaste{
428254721Semaste    exc_trapno,
429254721Semaste    exc_err,
430254721Semaste    exc_faultvaddr
431254721Semaste};
432254721Semaste
433254721Semaste// Number of registers in each register set
434254721Semasteconst size_t k_num_gpr_registers = sizeof(g_gpr_regnums) / sizeof(uint32_t);
435254721Semasteconst size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t);
436254721Semasteconst size_t k_num_exc_registers = sizeof(g_exc_regnums) / sizeof(uint32_t);
437254721Semaste
438254721Semaste//----------------------------------------------------------------------
439254721Semaste// Register set definitions. The first definitions at register set index
440254721Semaste// of zero is for all registers, followed by other registers sets. The
441254721Semaste// register information for the all register set need not be filled in.
442254721Semaste//----------------------------------------------------------------------
443254721Semastestatic const RegisterSet g_reg_sets[] =
444254721Semaste{
445254721Semaste    { "General Purpose Registers",  "gpr",  k_num_gpr_registers,    g_gpr_regnums,      },
446254721Semaste    { "Floating Point Registers",   "fpu",  k_num_fpu_registers,    g_fpu_regnums       },
447254721Semaste    { "Exception State Registers",  "exc",  k_num_exc_registers,    g_exc_regnums       }
448254721Semaste};
449254721Semaste
450254721Semasteconst size_t k_num_regsets = sizeof(g_reg_sets) / sizeof(RegisterSet);
451254721Semaste
452254721Semaste
453254721Semastesize_t
454254721SemasteRegisterContextDarwin_x86_64::GetRegisterSetCount ()
455254721Semaste{
456254721Semaste    return k_num_regsets;
457254721Semaste}
458254721Semaste
459254721Semasteconst RegisterSet *
460254721SemasteRegisterContextDarwin_x86_64::GetRegisterSet (size_t reg_set)
461254721Semaste{
462254721Semaste    if (reg_set < k_num_regsets)
463254721Semaste        return &g_reg_sets[reg_set];
464254721Semaste    return NULL;
465254721Semaste}
466254721Semaste
467254721Semasteint
468254721SemasteRegisterContextDarwin_x86_64::GetSetForNativeRegNum (int reg_num)
469254721Semaste{
470254721Semaste    if (reg_num < fpu_fcw)
471254721Semaste        return GPRRegSet;
472254721Semaste    else if (reg_num < exc_trapno)
473254721Semaste        return FPURegSet;
474254721Semaste    else if (reg_num < k_num_registers)
475254721Semaste        return EXCRegSet;
476254721Semaste    return -1;
477254721Semaste}
478254721Semaste
479254721Semastevoid
480254721SemasteRegisterContextDarwin_x86_64::LogGPR(Log *log, const char *format, ...)
481254721Semaste{
482254721Semaste    if (log)
483254721Semaste    {
484254721Semaste        if (format)
485254721Semaste        {
486254721Semaste            va_list args;
487254721Semaste            va_start (args, format);
488254721Semaste            log->VAPrintf (format, args);
489254721Semaste            va_end (args);
490254721Semaste        }
491254721Semaste        for (uint32_t i=0; i<k_num_gpr_registers; i++)
492254721Semaste        {
493254721Semaste            uint32_t reg = gpr_rax + i;
494254721Semaste            log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name, (&gpr.rax)[reg]);
495254721Semaste        }
496254721Semaste    }
497254721Semaste}
498254721Semaste
499254721Semasteint
500254721SemasteRegisterContextDarwin_x86_64::ReadGPR (bool force)
501254721Semaste{
502254721Semaste    int set = GPRRegSet;
503254721Semaste    if (force || !RegisterSetIsCached(set))
504254721Semaste    {
505254721Semaste        SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
506254721Semaste    }
507254721Semaste    return GetError(GPRRegSet, Read);
508254721Semaste}
509254721Semaste
510254721Semasteint
511254721SemasteRegisterContextDarwin_x86_64::ReadFPU (bool force)
512254721Semaste{
513254721Semaste    int set = FPURegSet;
514254721Semaste    if (force || !RegisterSetIsCached(set))
515254721Semaste    {
516254721Semaste        SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
517254721Semaste    }
518254721Semaste    return GetError(FPURegSet, Read);
519254721Semaste}
520254721Semaste
521254721Semasteint
522254721SemasteRegisterContextDarwin_x86_64::ReadEXC (bool force)
523254721Semaste{
524254721Semaste    int set = EXCRegSet;
525254721Semaste    if (force || !RegisterSetIsCached(set))
526254721Semaste    {
527254721Semaste        SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
528254721Semaste    }
529254721Semaste    return GetError(EXCRegSet, Read);
530254721Semaste}
531254721Semaste
532254721Semasteint
533254721SemasteRegisterContextDarwin_x86_64::WriteGPR ()
534254721Semaste{
535254721Semaste    int set = GPRRegSet;
536254721Semaste    if (!RegisterSetIsCached(set))
537254721Semaste    {
538254721Semaste        SetError (set, Write, -1);
539254721Semaste        return -1;
540254721Semaste    }
541254721Semaste    SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
542254721Semaste    SetError (set, Read, -1);
543254721Semaste    return GetError (set, Write);
544254721Semaste}
545254721Semaste
546254721Semasteint
547254721SemasteRegisterContextDarwin_x86_64::WriteFPU ()
548254721Semaste{
549254721Semaste    int set = FPURegSet;
550254721Semaste    if (!RegisterSetIsCached(set))
551254721Semaste    {
552254721Semaste        SetError (set, Write, -1);
553254721Semaste        return -1;
554254721Semaste    }
555254721Semaste    SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
556254721Semaste    SetError (set, Read, -1);
557254721Semaste    return GetError (set, Write);
558254721Semaste}
559254721Semaste
560254721Semasteint
561254721SemasteRegisterContextDarwin_x86_64::WriteEXC ()
562254721Semaste{
563254721Semaste    int set = EXCRegSet;
564254721Semaste    if (!RegisterSetIsCached(set))
565254721Semaste    {
566254721Semaste        SetError (set, Write, -1);
567254721Semaste        return -1;
568254721Semaste    }
569254721Semaste    SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
570254721Semaste    SetError (set, Read, -1);
571254721Semaste    return GetError (set, Write);
572254721Semaste}
573254721Semaste
574254721Semasteint
575254721SemasteRegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force)
576254721Semaste{
577254721Semaste    switch (set)
578254721Semaste    {
579254721Semaste    case GPRRegSet:    return ReadGPR (force);
580254721Semaste    case FPURegSet:    return ReadFPU (force);
581254721Semaste    case EXCRegSet:    return ReadEXC (force);
582254721Semaste    default: break;
583254721Semaste    }
584254721Semaste    return -1;
585254721Semaste}
586254721Semaste
587254721Semasteint
588254721SemasteRegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set)
589254721Semaste{
590254721Semaste    // Make sure we have a valid context to set.
591254721Semaste    switch (set)
592254721Semaste    {
593254721Semaste    case GPRRegSet:    return WriteGPR ();
594254721Semaste    case FPURegSet:    return WriteFPU ();
595254721Semaste    case EXCRegSet:    return WriteEXC ();
596254721Semaste    default: break;
597254721Semaste    }
598254721Semaste    return -1;
599254721Semaste}
600254721Semaste
601254721Semaste
602254721Semastebool
603254721SemasteRegisterContextDarwin_x86_64::ReadRegister (const RegisterInfo *reg_info,
604254721Semaste                                          RegisterValue &value)
605254721Semaste{
606254721Semaste    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
607254721Semaste    int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg);
608254721Semaste    if (set == -1)
609254721Semaste        return false;
610254721Semaste
611254721Semaste    if (ReadRegisterSet(set, false) != 0)
612254721Semaste        return false;
613254721Semaste
614254721Semaste    switch (reg)
615254721Semaste    {
616254721Semaste    case gpr_rax:
617254721Semaste    case gpr_rbx:
618254721Semaste    case gpr_rcx:
619254721Semaste    case gpr_rdx:
620254721Semaste    case gpr_rdi:
621254721Semaste    case gpr_rsi:
622254721Semaste    case gpr_rbp:
623254721Semaste    case gpr_rsp:
624254721Semaste    case gpr_r8:
625254721Semaste    case gpr_r9:
626254721Semaste    case gpr_r10:
627254721Semaste    case gpr_r11:
628254721Semaste    case gpr_r12:
629254721Semaste    case gpr_r13:
630254721Semaste    case gpr_r14:
631254721Semaste    case gpr_r15:
632254721Semaste    case gpr_rip:
633254721Semaste    case gpr_rflags:
634254721Semaste    case gpr_cs:
635254721Semaste    case gpr_fs:
636254721Semaste    case gpr_gs:
637254721Semaste        value = (&gpr.rax)[reg - gpr_rax];
638254721Semaste        break;
639254721Semaste
640254721Semaste    case fpu_fcw:
641254721Semaste        value = fpu.fcw;
642254721Semaste        break;
643254721Semaste
644254721Semaste    case fpu_fsw:
645254721Semaste        value = fpu.fsw;
646254721Semaste        break;
647254721Semaste
648254721Semaste    case fpu_ftw:
649254721Semaste        value = fpu.ftw;
650254721Semaste        break;
651254721Semaste
652254721Semaste    case fpu_fop:
653254721Semaste        value = fpu.fop;
654254721Semaste        break;
655254721Semaste
656254721Semaste    case fpu_ip:
657254721Semaste        value = fpu.ip;
658254721Semaste        break;
659254721Semaste
660254721Semaste    case fpu_cs:
661254721Semaste        value = fpu.cs;
662254721Semaste        break;
663254721Semaste
664254721Semaste    case fpu_dp:
665254721Semaste        value = fpu.dp;
666254721Semaste        break;
667254721Semaste
668254721Semaste    case fpu_ds:
669254721Semaste        value = fpu.ds;
670254721Semaste        break;
671254721Semaste
672254721Semaste    case fpu_mxcsr:
673254721Semaste        value = fpu.mxcsr;
674254721Semaste        break;
675254721Semaste
676254721Semaste    case fpu_mxcsrmask:
677254721Semaste        value = fpu.mxcsrmask;
678254721Semaste        break;
679254721Semaste
680254721Semaste    case fpu_stmm0:
681254721Semaste    case fpu_stmm1:
682254721Semaste    case fpu_stmm2:
683254721Semaste    case fpu_stmm3:
684254721Semaste    case fpu_stmm4:
685254721Semaste    case fpu_stmm5:
686254721Semaste    case fpu_stmm6:
687254721Semaste    case fpu_stmm7:
688254721Semaste        value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
689254721Semaste        break;
690254721Semaste
691254721Semaste    case fpu_xmm0:
692254721Semaste    case fpu_xmm1:
693254721Semaste    case fpu_xmm2:
694254721Semaste    case fpu_xmm3:
695254721Semaste    case fpu_xmm4:
696254721Semaste    case fpu_xmm5:
697254721Semaste    case fpu_xmm6:
698254721Semaste    case fpu_xmm7:
699254721Semaste    case fpu_xmm8:
700254721Semaste    case fpu_xmm9:
701254721Semaste    case fpu_xmm10:
702254721Semaste    case fpu_xmm11:
703254721Semaste    case fpu_xmm12:
704254721Semaste    case fpu_xmm13:
705254721Semaste    case fpu_xmm14:
706254721Semaste    case fpu_xmm15:
707254721Semaste        value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, lldb::endian::InlHostByteOrder());
708254721Semaste        break;
709254721Semaste
710254721Semaste    case exc_trapno:
711254721Semaste        value = exc.trapno;
712254721Semaste        break;
713254721Semaste
714254721Semaste    case exc_err:
715254721Semaste        value = exc.err;
716254721Semaste        break;
717254721Semaste
718254721Semaste    case exc_faultvaddr:
719254721Semaste        value = exc.faultvaddr;
720254721Semaste        break;
721254721Semaste
722254721Semaste    default:
723254721Semaste        return false;
724254721Semaste    }
725254721Semaste    return true;
726254721Semaste}
727254721Semaste
728254721Semaste
729254721Semastebool
730254721SemasteRegisterContextDarwin_x86_64::WriteRegister (const RegisterInfo *reg_info,
731254721Semaste                                           const RegisterValue &value)
732254721Semaste{
733254721Semaste    const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
734254721Semaste    int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum (reg);
735254721Semaste
736254721Semaste    if (set == -1)
737254721Semaste        return false;
738254721Semaste
739254721Semaste    if (ReadRegisterSet(set, false) != 0)
740254721Semaste        return false;
741254721Semaste
742254721Semaste    switch (reg)
743254721Semaste    {
744254721Semaste    case gpr_rax:
745254721Semaste    case gpr_rbx:
746254721Semaste    case gpr_rcx:
747254721Semaste    case gpr_rdx:
748254721Semaste    case gpr_rdi:
749254721Semaste    case gpr_rsi:
750254721Semaste    case gpr_rbp:
751254721Semaste    case gpr_rsp:
752254721Semaste    case gpr_r8:
753254721Semaste    case gpr_r9:
754254721Semaste    case gpr_r10:
755254721Semaste    case gpr_r11:
756254721Semaste    case gpr_r12:
757254721Semaste    case gpr_r13:
758254721Semaste    case gpr_r14:
759254721Semaste    case gpr_r15:
760254721Semaste    case gpr_rip:
761254721Semaste    case gpr_rflags:
762254721Semaste    case gpr_cs:
763254721Semaste    case gpr_fs:
764254721Semaste    case gpr_gs:
765254721Semaste        (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
766254721Semaste        break;
767254721Semaste
768254721Semaste    case fpu_fcw:
769254721Semaste        fpu.fcw = value.GetAsUInt16();
770254721Semaste        break;
771254721Semaste
772254721Semaste    case fpu_fsw:
773254721Semaste        fpu.fsw = value.GetAsUInt16();
774254721Semaste        break;
775254721Semaste
776254721Semaste    case fpu_ftw:
777254721Semaste        fpu.ftw = value.GetAsUInt8();
778254721Semaste        break;
779254721Semaste
780254721Semaste    case fpu_fop:
781254721Semaste        fpu.fop = value.GetAsUInt16();
782254721Semaste        break;
783254721Semaste
784254721Semaste    case fpu_ip:
785254721Semaste        fpu.ip = value.GetAsUInt32();
786254721Semaste        break;
787254721Semaste
788254721Semaste    case fpu_cs:
789254721Semaste        fpu.cs = value.GetAsUInt16();
790254721Semaste        break;
791254721Semaste
792254721Semaste    case fpu_dp:
793254721Semaste        fpu.dp = value.GetAsUInt32();
794254721Semaste        break;
795254721Semaste
796254721Semaste    case fpu_ds:
797254721Semaste        fpu.ds = value.GetAsUInt16();
798254721Semaste        break;
799254721Semaste
800254721Semaste    case fpu_mxcsr:
801254721Semaste        fpu.mxcsr = value.GetAsUInt32();
802254721Semaste        break;
803254721Semaste
804254721Semaste    case fpu_mxcsrmask:
805254721Semaste        fpu.mxcsrmask = value.GetAsUInt32();
806254721Semaste        break;
807254721Semaste
808254721Semaste    case fpu_stmm0:
809254721Semaste    case fpu_stmm1:
810254721Semaste    case fpu_stmm2:
811254721Semaste    case fpu_stmm3:
812254721Semaste    case fpu_stmm4:
813254721Semaste    case fpu_stmm5:
814254721Semaste    case fpu_stmm6:
815254721Semaste    case fpu_stmm7:
816254721Semaste        ::memcpy (fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
817254721Semaste        break;
818254721Semaste
819254721Semaste    case fpu_xmm0:
820254721Semaste    case fpu_xmm1:
821254721Semaste    case fpu_xmm2:
822254721Semaste    case fpu_xmm3:
823254721Semaste    case fpu_xmm4:
824254721Semaste    case fpu_xmm5:
825254721Semaste    case fpu_xmm6:
826254721Semaste    case fpu_xmm7:
827254721Semaste    case fpu_xmm8:
828254721Semaste    case fpu_xmm9:
829254721Semaste    case fpu_xmm10:
830254721Semaste    case fpu_xmm11:
831254721Semaste    case fpu_xmm12:
832254721Semaste    case fpu_xmm13:
833254721Semaste    case fpu_xmm14:
834254721Semaste    case fpu_xmm15:
835254721Semaste        ::memcpy (fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
836254721Semaste        return false;
837254721Semaste
838254721Semaste    case exc_trapno:
839254721Semaste        exc.trapno = value.GetAsUInt32();
840254721Semaste        break;
841254721Semaste
842254721Semaste    case exc_err:
843254721Semaste        exc.err = value.GetAsUInt32();
844254721Semaste        break;
845254721Semaste
846254721Semaste    case exc_faultvaddr:
847254721Semaste        exc.faultvaddr = value.GetAsUInt64();
848254721Semaste        break;
849254721Semaste
850254721Semaste    default:
851254721Semaste        return false;
852254721Semaste    }
853254721Semaste    return WriteRegisterSet(set) == 0;
854254721Semaste}
855254721Semaste
856254721Semastebool
857254721SemasteRegisterContextDarwin_x86_64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
858254721Semaste{
859254721Semaste    data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
860254721Semaste    if (data_sp &&
861254721Semaste        ReadGPR (false) == 0 &&
862254721Semaste        ReadFPU (false) == 0 &&
863254721Semaste        ReadEXC (false) == 0)
864254721Semaste    {
865254721Semaste        uint8_t *dst = data_sp->GetBytes();
866254721Semaste        ::memcpy (dst, &gpr, sizeof(gpr));
867254721Semaste        dst += sizeof(gpr);
868254721Semaste
869254721Semaste        ::memcpy (dst, &fpu, sizeof(fpu));
870254721Semaste        dst += sizeof(gpr);
871254721Semaste
872254721Semaste        ::memcpy (dst, &exc, sizeof(exc));
873254721Semaste        return true;
874254721Semaste    }
875254721Semaste    return false;
876254721Semaste}
877254721Semaste
878254721Semastebool
879254721SemasteRegisterContextDarwin_x86_64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
880254721Semaste{
881254721Semaste    if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
882254721Semaste    {
883254721Semaste        const uint8_t *src = data_sp->GetBytes();
884254721Semaste        ::memcpy (&gpr, src, sizeof(gpr));
885254721Semaste        src += sizeof(gpr);
886254721Semaste
887254721Semaste        ::memcpy (&fpu, src, sizeof(fpu));
888254721Semaste        src += sizeof(gpr);
889254721Semaste
890254721Semaste        ::memcpy (&exc, src, sizeof(exc));
891254721Semaste        uint32_t success_count = 0;
892254721Semaste        if (WriteGPR() == 0)
893254721Semaste            ++success_count;
894254721Semaste        if (WriteFPU() == 0)
895254721Semaste            ++success_count;
896254721Semaste        if (WriteEXC() == 0)
897254721Semaste            ++success_count;
898254721Semaste        return success_count == 3;
899254721Semaste    }
900254721Semaste    return false;
901254721Semaste}
902254721Semaste
903254721Semaste
904254721Semasteuint32_t
905254721SemasteRegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t reg)
906254721Semaste{
907254721Semaste    if (kind == eRegisterKindGeneric)
908254721Semaste    {
909254721Semaste        switch (reg)
910254721Semaste        {
911254721Semaste        case LLDB_REGNUM_GENERIC_PC:    return gpr_rip;
912254721Semaste        case LLDB_REGNUM_GENERIC_SP:    return gpr_rsp;
913254721Semaste        case LLDB_REGNUM_GENERIC_FP:    return gpr_rbp;
914254721Semaste        case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
915254721Semaste        case LLDB_REGNUM_GENERIC_RA:
916254721Semaste        default:
917254721Semaste            break;
918254721Semaste        }
919254721Semaste    }
920254721Semaste    else if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
921254721Semaste    {
922254721Semaste        switch (reg)
923254721Semaste        {
924254721Semaste        case gcc_dwarf_gpr_rax:  return gpr_rax;
925254721Semaste        case gcc_dwarf_gpr_rdx:  return gpr_rdx;
926254721Semaste        case gcc_dwarf_gpr_rcx:  return gpr_rcx;
927254721Semaste        case gcc_dwarf_gpr_rbx:  return gpr_rbx;
928254721Semaste        case gcc_dwarf_gpr_rsi:  return gpr_rsi;
929254721Semaste        case gcc_dwarf_gpr_rdi:  return gpr_rdi;
930254721Semaste        case gcc_dwarf_gpr_rbp:  return gpr_rbp;
931254721Semaste        case gcc_dwarf_gpr_rsp:  return gpr_rsp;
932254721Semaste        case gcc_dwarf_gpr_r8:   return gpr_r8;
933254721Semaste        case gcc_dwarf_gpr_r9:   return gpr_r9;
934254721Semaste        case gcc_dwarf_gpr_r10:  return gpr_r10;
935254721Semaste        case gcc_dwarf_gpr_r11:  return gpr_r11;
936254721Semaste        case gcc_dwarf_gpr_r12:  return gpr_r12;
937254721Semaste        case gcc_dwarf_gpr_r13:  return gpr_r13;
938254721Semaste        case gcc_dwarf_gpr_r14:  return gpr_r14;
939254721Semaste        case gcc_dwarf_gpr_r15:  return gpr_r15;
940254721Semaste        case gcc_dwarf_gpr_rip:  return gpr_rip;
941254721Semaste        case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
942254721Semaste        case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
943254721Semaste        case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
944254721Semaste        case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
945254721Semaste        case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
946254721Semaste        case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
947254721Semaste        case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
948254721Semaste        case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
949254721Semaste        case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
950254721Semaste        case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
951254721Semaste        case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
952254721Semaste        case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
953254721Semaste        case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
954254721Semaste        case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
955254721Semaste        case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
956254721Semaste        case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
957254721Semaste        case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
958254721Semaste        case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
959254721Semaste        case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
960254721Semaste        case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
961254721Semaste        case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
962254721Semaste        case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
963254721Semaste        case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
964254721Semaste        case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
965254721Semaste        default:
966254721Semaste            break;
967254721Semaste        }
968254721Semaste    }
969254721Semaste    else if (kind == eRegisterKindGDB)
970254721Semaste    {
971254721Semaste        switch (reg)
972254721Semaste        {
973254721Semaste        case gdb_gpr_rax     : return gpr_rax;
974254721Semaste        case gdb_gpr_rbx     : return gpr_rbx;
975254721Semaste        case gdb_gpr_rcx     : return gpr_rcx;
976254721Semaste        case gdb_gpr_rdx     : return gpr_rdx;
977254721Semaste        case gdb_gpr_rsi     : return gpr_rsi;
978254721Semaste        case gdb_gpr_rdi     : return gpr_rdi;
979254721Semaste        case gdb_gpr_rbp     : return gpr_rbp;
980254721Semaste        case gdb_gpr_rsp     : return gpr_rsp;
981254721Semaste        case gdb_gpr_r8      : return gpr_r8;
982254721Semaste        case gdb_gpr_r9      : return gpr_r9;
983254721Semaste        case gdb_gpr_r10     : return gpr_r10;
984254721Semaste        case gdb_gpr_r11     : return gpr_r11;
985254721Semaste        case gdb_gpr_r12     : return gpr_r12;
986254721Semaste        case gdb_gpr_r13     : return gpr_r13;
987254721Semaste        case gdb_gpr_r14     : return gpr_r14;
988254721Semaste        case gdb_gpr_r15     : return gpr_r15;
989254721Semaste        case gdb_gpr_rip     : return gpr_rip;
990254721Semaste        case gdb_gpr_rflags  : return gpr_rflags;
991254721Semaste        case gdb_gpr_cs      : return gpr_cs;
992254721Semaste        case gdb_gpr_ss      : return gpr_gs;   // HACK: For now for "ss", just copy what is in "gs"
993254721Semaste        case gdb_gpr_ds      : return gpr_gs;   // HACK: For now for "ds", just copy what is in "gs"
994254721Semaste        case gdb_gpr_es      : return gpr_gs;   // HACK: For now for "es", just copy what is in "gs"
995254721Semaste        case gdb_gpr_fs      : return gpr_fs;
996254721Semaste        case gdb_gpr_gs      : return gpr_gs;
997254721Semaste        case gdb_fpu_stmm0   : return fpu_stmm0;
998254721Semaste        case gdb_fpu_stmm1   : return fpu_stmm1;
999254721Semaste        case gdb_fpu_stmm2   : return fpu_stmm2;
1000254721Semaste        case gdb_fpu_stmm3   : return fpu_stmm3;
1001254721Semaste        case gdb_fpu_stmm4   : return fpu_stmm4;
1002254721Semaste        case gdb_fpu_stmm5   : return fpu_stmm5;
1003254721Semaste        case gdb_fpu_stmm6   : return fpu_stmm6;
1004254721Semaste        case gdb_fpu_stmm7   : return fpu_stmm7;
1005254721Semaste        case gdb_fpu_fctrl   : return fpu_fctrl;
1006254721Semaste        case gdb_fpu_fstat   : return fpu_fstat;
1007254721Semaste        case gdb_fpu_ftag    : return fpu_ftag;
1008254721Semaste        case gdb_fpu_fiseg   : return fpu_fiseg;
1009254721Semaste        case gdb_fpu_fioff   : return fpu_fioff;
1010254721Semaste        case gdb_fpu_foseg   : return fpu_foseg;
1011254721Semaste        case gdb_fpu_fooff   : return fpu_fooff;
1012254721Semaste        case gdb_fpu_fop     : return fpu_fop;
1013254721Semaste        case gdb_fpu_xmm0    : return fpu_xmm0;
1014254721Semaste        case gdb_fpu_xmm1    : return fpu_xmm1;
1015254721Semaste        case gdb_fpu_xmm2    : return fpu_xmm2;
1016254721Semaste        case gdb_fpu_xmm3    : return fpu_xmm3;
1017254721Semaste        case gdb_fpu_xmm4    : return fpu_xmm4;
1018254721Semaste        case gdb_fpu_xmm5    : return fpu_xmm5;
1019254721Semaste        case gdb_fpu_xmm6    : return fpu_xmm6;
1020254721Semaste        case gdb_fpu_xmm7    : return fpu_xmm7;
1021254721Semaste        case gdb_fpu_xmm8    : return fpu_xmm8;
1022254721Semaste        case gdb_fpu_xmm9    : return fpu_xmm9;
1023254721Semaste        case gdb_fpu_xmm10   : return fpu_xmm10;
1024254721Semaste        case gdb_fpu_xmm11   : return fpu_xmm11;
1025254721Semaste        case gdb_fpu_xmm12   : return fpu_xmm12;
1026254721Semaste        case gdb_fpu_xmm13   : return fpu_xmm13;
1027254721Semaste        case gdb_fpu_xmm14   : return fpu_xmm14;
1028254721Semaste        case gdb_fpu_xmm15   : return fpu_xmm15;
1029254721Semaste        case gdb_fpu_mxcsr   : return fpu_mxcsr;
1030254721Semaste        default:
1031254721Semaste            break;
1032254721Semaste        }
1033254721Semaste    }
1034254721Semaste    else if (kind == eRegisterKindLLDB)
1035254721Semaste    {
1036254721Semaste        return reg;
1037254721Semaste    }
1038254721Semaste    return LLDB_INVALID_REGNUM;
1039254721Semaste}
1040254721Semaste
1041254721Semastebool
1042254721SemasteRegisterContextDarwin_x86_64::HardwareSingleStep (bool enable)
1043254721Semaste{
1044254721Semaste    if (ReadGPR(true) != 0)
1045254721Semaste        return false;
1046254721Semaste
1047254721Semaste    const uint64_t trace_bit = 0x100ull;
1048254721Semaste    if (enable)
1049254721Semaste    {
1050254721Semaste
1051254721Semaste        if (gpr.rflags & trace_bit)
1052254721Semaste            return true;    // trace bit is already set, there is nothing to do
1053254721Semaste        else
1054254721Semaste            gpr.rflags |= trace_bit;
1055254721Semaste    }
1056254721Semaste    else
1057254721Semaste    {
1058254721Semaste        if (gpr.rflags & trace_bit)
1059254721Semaste            gpr.rflags &= ~trace_bit;
1060254721Semaste        else
1061254721Semaste            return true;    // trace bit is clear, there is nothing to do
1062254721Semaste    }
1063254721Semaste
1064254721Semaste    return WriteGPR() == 0;
1065254721Semaste}
1066254721Semaste
1067