DNBArchImplI386.h revision 24943d2ee8bfaa7cf5893e4709143924157a5c1e
1//===-- DNBArchImplI386.h ---------------------------------------*- 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// Created by Greg Clayton on 6/25/07. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef __DNBArchImplI386_h__ 15#define __DNBArchImplI386_h__ 16 17#if defined (__i386__) 18 19#include "DNBArch.h" 20#include <mach/mach_types.h> 21#include <mach/thread_status.h> 22 23 24class MachThread; 25 26class DNBArchImplI386 : public DNBArchProtocol 27{ 28public: 29 DNBArchImplI386(MachThread *thread) : 30 m_thread(thread), 31 m_state() 32 { 33 } 34 virtual ~DNBArchImplI386() 35 { 36 } 37 38 static const DNBRegisterSetInfo * 39 GetRegisterSetInfo(nub_size_t *num_reg_sets); 40 41 virtual bool GetRegisterValue(int set, int reg, DNBRegisterValue *reg); 42 virtual bool SetRegisterValue(int set, int reg, const DNBRegisterValue *reg); 43 virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len); 44 virtual nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len); 45 virtual kern_return_t GetRegisterState (int set, bool force); 46 virtual kern_return_t SetRegisterState (int set); 47 virtual bool RegisterSetStateIsValid (int set) const; 48 49 virtual uint64_t GetPC(uint64_t failValue); // Get program counter 50 virtual kern_return_t SetPC(uint64_t value); 51 virtual uint64_t GetSP(uint64_t failValue); // Get stack pointer 52 virtual void ThreadWillResume(); 53 virtual bool ThreadDidStop(); 54 virtual bool NotifyException(MachException::Data& exc); 55 56 static const uint8_t * const SoftwareBreakpointOpcode (nub_size_t byte_size); 57 static uint32_t GetCPUType(); 58 59protected: 60 kern_return_t EnableHardwareSingleStep (bool enable); 61 62 typedef i386_thread_state_t GPR; 63 typedef i386_float_state_t FPU; 64 typedef i386_exception_state_t EXC; 65 66 static const DNBRegisterInfo g_gpr_registers[]; 67 static const DNBRegisterInfo g_fpu_registers[]; 68 static const DNBRegisterInfo g_exc_registers[]; 69 static const DNBRegisterSetInfo g_reg_sets[]; 70 static const size_t k_num_gpr_registers; 71 static const size_t k_num_fpu_registers; 72 static const size_t k_num_exc_registers; 73 static const size_t k_num_all_registers; 74 static const size_t k_num_register_sets; 75 76 typedef enum RegisterSetTag 77 { 78 e_regSetALL = REGISTER_SET_ALL, 79 e_regSetGPR, 80 e_regSetFPU, 81 e_regSetEXC, 82 kNumRegisterSets 83 } RegisterSet; 84 85 typedef enum RegisterSetWordSizeTag 86 { 87 e_regSetWordSizeGPR = i386_THREAD_STATE_COUNT, 88 e_regSetWordSizeFPR = i386_FLOAT_STATE_COUNT, 89 e_regSetWordSizeEXC = i386_EXCEPTION_STATE_COUNT 90 } RegisterSetWordSize; 91 92 enum 93 { 94 Read = 0, 95 Write = 1, 96 kNumErrors = 2 97 }; 98 99 struct Context 100 { 101 i386_thread_state_t gpr; 102 i386_float_state_t fpu; 103 i386_exception_state_t exc; 104 }; 105 106 struct State 107 { 108 Context context; 109 kern_return_t gpr_errs[2]; // Read/Write errors 110 kern_return_t fpu_errs[2]; // Read/Write errors 111 kern_return_t exc_errs[2]; // Read/Write errors 112 113 State() 114 { 115 uint32_t i; 116 for (i=0; i<kNumErrors; i++) 117 { 118 gpr_errs[i] = -1; 119 fpu_errs[i] = -1; 120 exc_errs[i] = -1; 121 } 122 } 123 void InvalidateAllRegisterStates() 124 { 125 SetError (e_regSetALL, Read, -1); 126 } 127 kern_return_t GetError (int flavor, uint32_t err_idx) const 128 { 129 if (err_idx < kNumErrors) 130 { 131 switch (flavor) 132 { 133 // When getting all errors, just OR all values together to see if 134 // we got any kind of error. 135 case e_regSetALL: return gpr_errs[err_idx] | 136 fpu_errs[err_idx] | 137 exc_errs[err_idx]; 138 case e_regSetGPR: return gpr_errs[err_idx]; 139 case e_regSetFPU: return fpu_errs[err_idx]; 140 case e_regSetEXC: return exc_errs[err_idx]; 141 default: break; 142 } 143 } 144 return -1; 145 } 146 bool SetError (int flavor, uint32_t err_idx, kern_return_t err) 147 { 148 if (err_idx < kNumErrors) 149 { 150 switch (flavor) 151 { 152 case e_regSetALL: 153 gpr_errs[err_idx] = 154 fpu_errs[err_idx] = 155 exc_errs[err_idx] = err; 156 return true; 157 158 case e_regSetGPR: 159 gpr_errs[err_idx] = err; 160 return true; 161 162 case e_regSetFPU: 163 fpu_errs[err_idx] = err; 164 return true; 165 166 case e_regSetEXC: 167 exc_errs[err_idx] = err; 168 return true; 169 170 default: break; 171 } 172 } 173 return false; 174 } 175 bool RegsAreValid (int flavor) const 176 { 177 return GetError(flavor, Read) == KERN_SUCCESS; 178 } 179 }; 180 181 kern_return_t GetGPRState (bool force); 182 kern_return_t GetFPUState (bool force); 183 kern_return_t GetEXCState (bool force); 184 185 kern_return_t SetGPRState (); 186 kern_return_t SetFPUState (); 187 kern_return_t SetEXCState (); 188 189 MachThread *m_thread; 190 State m_state; 191}; 192 193typedef DNBArchImplI386 DNBArch; 194 195#endif // #if defined (__i386__) 196#endif // #ifndef __DNBArchImplI386_h__ 197