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