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