1 //===-- RegisterContextDarwin_i386.cpp --------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
21 // Support building against older versions of LLVM, this macro was added
23 #ifndef LLVM_EXTENSION
24 #define LLVM_EXTENSION
27 #include "RegisterContextDarwin_i386.h"
30 using namespace lldb_private;
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))
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
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) \
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, \
162 nullptr, nullptr, nullptr, 0
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))
172 static RegisterInfo g_register_infos[] = {
173 // Macro auto defines most stuff eh_frame DWARF
174 // GENERIC PROCESS PLUGIN LLDB
175 // =============================== =======================
176 // =================== ========================= ==================
178 {DEFINE_GPR(eax, NULL),
179 {ehframe_eax, dwarf_eax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
185 {DEFINE_GPR(ebx, NULL),
186 {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
192 {DEFINE_GPR(ecx, NULL),
193 {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
199 {DEFINE_GPR(edx, NULL),
200 {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
206 {DEFINE_GPR(edi, NULL),
207 {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
213 {DEFINE_GPR(esi, NULL),
214 {ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
220 {DEFINE_GPR(ebp, "fp"),
221 {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
227 {DEFINE_GPR(esp, "sp"),
228 {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
234 {DEFINE_GPR(ss, NULL),
235 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
236 LLDB_INVALID_REGNUM, gpr_ss},
241 {DEFINE_GPR(eflags, "flags"),
242 {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS,
243 LLDB_INVALID_REGNUM, gpr_eflags},
248 {DEFINE_GPR(eip, "pc"),
249 {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
255 {DEFINE_GPR(cs, NULL),
256 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
257 LLDB_INVALID_REGNUM, gpr_cs},
262 {DEFINE_GPR(ds, NULL),
263 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
264 LLDB_INVALID_REGNUM, gpr_ds},
269 {DEFINE_GPR(es, NULL),
270 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
271 LLDB_INVALID_REGNUM, gpr_es},
276 {DEFINE_GPR(fs, NULL),
277 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
278 LLDB_INVALID_REGNUM, gpr_fs},
283 {DEFINE_GPR(gs, NULL),
284 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
285 LLDB_INVALID_REGNUM, gpr_gs},
291 {DEFINE_FPU_UINT(fcw),
292 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
293 LLDB_INVALID_REGNUM, fpu_fcw},
298 {DEFINE_FPU_UINT(fsw),
299 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
300 LLDB_INVALID_REGNUM, fpu_fsw},
305 {DEFINE_FPU_UINT(ftw),
306 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
307 LLDB_INVALID_REGNUM, fpu_ftw},
312 {DEFINE_FPU_UINT(fop),
313 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
314 LLDB_INVALID_REGNUM, fpu_fop},
319 {DEFINE_FPU_UINT(ip),
320 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
321 LLDB_INVALID_REGNUM, fpu_ip},
326 {DEFINE_FPU_UINT(cs),
327 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
328 LLDB_INVALID_REGNUM, fpu_cs},
333 {DEFINE_FPU_UINT(dp),
334 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
335 LLDB_INVALID_REGNUM, fpu_dp},
340 {DEFINE_FPU_UINT(ds),
341 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
342 LLDB_INVALID_REGNUM, fpu_ds},
347 {DEFINE_FPU_UINT(mxcsr),
348 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
349 LLDB_INVALID_REGNUM, fpu_mxcsr},
354 {DEFINE_FPU_UINT(mxcsrmask),
355 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
356 LLDB_INVALID_REGNUM, fpu_mxcsrmask},
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)},
379 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
380 LLDB_INVALID_REGNUM, exc_trapno},
386 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
387 LLDB_INVALID_REGNUM, exc_err},
392 {DEFINE_EXC(faultvaddr),
393 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
394 LLDB_INVALID_REGNUM, exc_faultvaddr},
400 static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
402 RegisterContextDarwin_i386::RegisterContextDarwin_i386(
403 Thread &thread, uint32_t concrete_frame_idx)
404 : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
406 for (i = 0; i < kNumErrors; i++) {
413 RegisterContextDarwin_i386::~RegisterContextDarwin_i386() {}
415 void RegisterContextDarwin_i386::InvalidateAllRegisters() {
416 InvalidateAllRegisterStates();
419 size_t RegisterContextDarwin_i386::GetRegisterCount() {
420 assert(k_num_register_infos == k_num_registers);
421 return k_num_registers;
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];
432 size_t RegisterContextDarwin_i386::GetRegisterInfosCount() {
433 return k_num_register_infos;
436 const RegisterInfo *RegisterContextDarwin_i386::GetRegisterInfos() {
437 return g_register_infos;
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};
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,
453 // Exception registers
455 static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
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);
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[] = {
469 "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
471 {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
472 {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
474 const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
476 size_t RegisterContextDarwin_i386::GetRegisterSetCount() {
477 return k_num_regsets;
480 const RegisterSet *RegisterContextDarwin_i386::GetRegisterSet(size_t reg_set) {
481 if (reg_set < k_num_regsets)
482 return &g_reg_sets[reg_set];
486 //----------------------------------------------------------------------
487 // Register information definitions for 32 bit i386.
488 //----------------------------------------------------------------------
489 int RegisterContextDarwin_i386::GetSetForNativeRegNum(int reg_num) {
490 if (reg_num < fpu_fcw)
492 else if (reg_num < exc_trapno)
494 else if (reg_num < k_num_registers)
499 void RegisterContextDarwin_i386::LogGPR(Log *log, const char *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,
511 int RegisterContextDarwin_i386::ReadGPR(bool force) {
513 if (force || !RegisterSetIsCached(set)) {
514 SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
516 return GetError(set, Read);
519 int RegisterContextDarwin_i386::ReadFPU(bool force) {
521 if (force || !RegisterSetIsCached(set)) {
522 SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
524 return GetError(set, Read);
527 int RegisterContextDarwin_i386::ReadEXC(bool force) {
529 if (force || !RegisterSetIsCached(set)) {
530 SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
532 return GetError(set, Read);
535 int RegisterContextDarwin_i386::WriteGPR() {
537 if (!RegisterSetIsCached(set)) {
538 SetError(set, Write, -1);
541 SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
542 SetError(set, Read, -1);
543 return GetError(set, Write);
546 int RegisterContextDarwin_i386::WriteFPU() {
548 if (!RegisterSetIsCached(set)) {
549 SetError(set, Write, -1);
552 SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
553 SetError(set, Read, -1);
554 return GetError(set, Write);
557 int RegisterContextDarwin_i386::WriteEXC() {
559 if (!RegisterSetIsCached(set)) {
560 SetError(set, Write, -1);
563 SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
564 SetError(set, Read, -1);
565 return GetError(set, Write);
568 int RegisterContextDarwin_i386::ReadRegisterSet(uint32_t set, bool force) {
571 return ReadGPR(force);
573 return ReadFPU(force);
575 return ReadEXC(force);
582 int RegisterContextDarwin_i386::WriteRegisterSet(uint32_t set) {
583 // Make sure we have a valid context to set.
584 if (RegisterSetIsCached(set)) {
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);
607 if (ReadRegisterSet(set, false) != 0)
627 value = (&gpr.eax)[reg - gpr_eax];
667 value = fpu.mxcsrmask;
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,
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,
707 value = exc.faultvaddr;
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);
724 if (ReadRegisterSet(set, false) != 0)
744 (&gpr.eax)[reg - gpr_eax] = value.GetAsUInt32();
748 fpu.fcw = value.GetAsUInt16();
752 fpu.fsw = value.GetAsUInt16();
756 fpu.ftw = value.GetAsUInt8();
760 fpu.fop = value.GetAsUInt16();
764 fpu.ip = value.GetAsUInt32();
768 fpu.cs = value.GetAsUInt16();
772 fpu.dp = value.GetAsUInt32();
776 fpu.ds = value.GetAsUInt16();
780 fpu.mxcsr = value.GetAsUInt32();
784 fpu.mxcsrmask = value.GetAsUInt32();
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());
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());
816 exc.trapno = value.GetAsUInt32();
820 exc.err = value.GetAsUInt32();
824 exc.faultvaddr = value.GetAsUInt32();
830 return WriteRegisterSet(set) == 0;
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));
842 ::memcpy(dst, &fpu, sizeof(fpu));
845 ::memcpy(dst, &exc, sizeof(exc));
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));
858 ::memcpy(&fpu, src, sizeof(fpu));
861 ::memcpy(&exc, src, sizeof(exc));
862 uint32_t success_count = 0;
869 return success_count == 3;
874 uint32_t RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber(
875 lldb::RegisterKind kind, uint32_t reg) {
876 if (kind == eRegisterKindGeneric) {
878 case LLDB_REGNUM_GENERIC_PC:
880 case LLDB_REGNUM_GENERIC_SP:
882 case LLDB_REGNUM_GENERIC_FP:
884 case LLDB_REGNUM_GENERIC_FLAGS:
886 case LLDB_REGNUM_GENERIC_RA:
890 } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
947 } else if (kind == eRegisterKindLLDB) {
950 return LLDB_INVALID_REGNUM;
953 bool RegisterContextDarwin_i386::HardwareSingleStep(bool enable) {
954 if (ReadGPR(false) != 0)
957 const uint32_t trace_bit = 0x100u;
959 // If the trace bit is already set, there is nothing to do
960 if (gpr.eflags & trace_bit)
963 gpr.eflags |= trace_bit;
965 // If the trace bit is already cleared, there is nothing to do
966 if (gpr.eflags & trace_bit)
967 gpr.eflags &= ~trace_bit;
972 return WriteGPR() == 0;