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