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