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