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