DNBArchImplI386.h revision 153191e36fcc528c393f0290a646d3f777a33695
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__) || defined (__x86_64__) 18 19#include "DNBArch.h" 20#include "../HasAVX.h" 21#include "MachRegisterStatesI386.h" 22 23class MachThread; 24 25class DNBArchImplI386 : public DNBArchProtocol 26{ 27public: 28 DNBArchImplI386(MachThread *thread) : 29 m_thread(thread), 30 m_state() 31 { 32 } 33 virtual ~DNBArchImplI386() 34 { 35 } 36 37 static void Initialize(); 38 39 virtual bool GetRegisterValue(int set, int reg, DNBRegisterValue *value); 40 virtual bool SetRegisterValue(int set, int reg, const DNBRegisterValue *value); 41 virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len); 42 virtual nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len); 43 virtual kern_return_t GetRegisterState (int set, bool force); 44 virtual kern_return_t SetRegisterState (int set); 45 virtual bool RegisterSetStateIsValid (int set) const; 46 47 virtual uint64_t GetPC(uint64_t failValue); // Get program counter 48 virtual kern_return_t SetPC(uint64_t value); 49 virtual uint64_t GetSP(uint64_t failValue); // Get stack pointer 50 virtual void ThreadWillResume(); 51 virtual bool ThreadDidStop(); 52 virtual bool NotifyException(MachException::Data& exc); 53 54protected: 55 kern_return_t EnableHardwareSingleStep (bool enable); 56 57 typedef __i386_thread_state_t GPR; 58 typedef __i386_float_state_t FPU; 59 typedef __i386_exception_state_t EXC; 60 typedef __i386_avx_state_t AVX; 61 62 static const DNBRegisterInfo g_gpr_registers[]; 63 static const DNBRegisterInfo g_fpu_registers_no_avx[]; 64 static const DNBRegisterInfo g_fpu_registers_avx[]; 65 static const DNBRegisterInfo g_exc_registers[]; 66 static const DNBRegisterSetInfo g_reg_sets_no_avx[]; 67 static const DNBRegisterSetInfo g_reg_sets_avx[]; 68 static const size_t k_num_gpr_registers; 69 static const size_t k_num_fpu_registers_no_avx; 70 static const size_t k_num_fpu_registers_avx; 71 static const size_t k_num_exc_registers; 72 static const size_t k_num_all_registers_no_avx; 73 static const size_t k_num_all_registers_avx; 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 = sizeof(GPR) / sizeof(int), 88 e_regSetWordSizeFPR = sizeof(FPU) / sizeof(int), 89 e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int), 90 e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int) 91 } RegisterSetWordSize; 92 93 enum 94 { 95 Read = 0, 96 Write = 1, 97 kNumErrors = 2 98 }; 99 100 struct Context 101 { 102 __i386_thread_state_t gpr; 103 union { 104 __i386_float_state_t no_avx; 105 __i386_avx_state_t avx; 106 } fpu; 107 __i386_exception_state_t exc; 108 }; 109 110 struct State 111 { 112 Context context; 113 kern_return_t gpr_errs[2]; // Read/Write errors 114 kern_return_t fpu_errs[2]; // Read/Write errors 115 kern_return_t exc_errs[2]; // Read/Write errors 116 117 State() 118 { 119 uint32_t i; 120 for (i=0; i<kNumErrors; i++) 121 { 122 gpr_errs[i] = -1; 123 fpu_errs[i] = -1; 124 exc_errs[i] = -1; 125 } 126 } 127 void InvalidateAllRegisterStates() 128 { 129 SetError (e_regSetALL, Read, -1); 130 } 131 kern_return_t GetError (int flavor, uint32_t err_idx) const 132 { 133 if (err_idx < kNumErrors) 134 { 135 switch (flavor) 136 { 137 // When getting all errors, just OR all values together to see if 138 // we got any kind of error. 139 case e_regSetALL: return gpr_errs[err_idx] | 140 fpu_errs[err_idx] | 141 exc_errs[err_idx]; 142 case e_regSetGPR: return gpr_errs[err_idx]; 143 case e_regSetFPU: return fpu_errs[err_idx]; 144 case e_regSetEXC: return exc_errs[err_idx]; 145 default: break; 146 } 147 } 148 return -1; 149 } 150 bool SetError (int flavor, uint32_t err_idx, kern_return_t err) 151 { 152 if (err_idx < kNumErrors) 153 { 154 switch (flavor) 155 { 156 case e_regSetALL: 157 gpr_errs[err_idx] = 158 fpu_errs[err_idx] = 159 exc_errs[err_idx] = err; 160 return true; 161 162 case e_regSetGPR: 163 gpr_errs[err_idx] = err; 164 return true; 165 166 case e_regSetFPU: 167 fpu_errs[err_idx] = err; 168 return true; 169 170 case e_regSetEXC: 171 exc_errs[err_idx] = err; 172 return true; 173 174 default: break; 175 } 176 } 177 return false; 178 } 179 bool RegsAreValid (int flavor) const 180 { 181 return GetError(flavor, Read) == KERN_SUCCESS; 182 } 183 }; 184 185 kern_return_t GetGPRState (bool force); 186 kern_return_t GetFPUState (bool force); 187 kern_return_t GetEXCState (bool force); 188 189 kern_return_t SetGPRState (); 190 kern_return_t SetFPUState (); 191 kern_return_t SetEXCState (); 192 193 static DNBArchProtocol * 194 Create (MachThread *thread); 195 196 static const uint8_t * const 197 SoftwareBreakpointOpcode (nub_size_t byte_size); 198 199 static const DNBRegisterSetInfo * 200 GetRegisterSetInfo(nub_size_t *num_reg_sets); 201 202 static bool 203 CPUHasAVX() 204 { 205#if 0 206 if (s_has_avx == kAVXUnknown) 207 s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent); 208 209 return (s_has_avx == kAVXPresent); 210#else 211 // ::HasAVX() will cause this code to crash because the 212 // assembly function doesn't backup and restore the registers 213 // it uses. Until this is fixed, AVX will be disabled. 214 return 0; 215#endif 216 } 217 218 MachThread *m_thread; 219 State m_state; 220 221 static enum AVXPresence { 222 kAVXPresent, 223 kAVXNotPresent, 224 kAVXUnknown 225 } s_has_avx; 226}; 227 228#endif // #if defined (__i386__) || defined (__x86_64__) 229#endif // #ifndef __DNBArchImplI386_h__ 230