DNBArchImplI386.h revision 5b4b00f5fd83d87de954d80d54fd6cc922772c19
1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//===-- DNBArchImplI386.h ---------------------------------------*- C++ -*-===// 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// The LLVM Compiler Infrastructure 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is distributed under the University of Illinois Open Source 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// License. See LICENSE.TXT for details. 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//===----------------------------------------------------------------------===// 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Created by Greg Clayton on 6/25/07. 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//===----------------------------------------------------------------------===// 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef __DNBArchImplI386_h__ 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define __DNBArchImplI386_h__ 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#if defined (__i386__) || defined (__x86_64__) 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "DNBArch.h" 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "../HasAVX.h" 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#include "MachRegisterStatesI386.h" 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass MachThread; 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass DNBArchImplI386 : public DNBArchProtocol 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic: 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DNBArchImplI386(MachThread *thread) : 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_thread(thread), 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_state() 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual ~DNBArchImplI386() 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void Initialize(); 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual bool GetRegisterValue(int set, int reg, DNBRegisterValue *value); 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual bool SetRegisterValue(int set, int reg, const DNBRegisterValue *value); 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len); 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len); 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual kern_return_t GetRegisterState (int set, bool force); 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual kern_return_t SetRegisterState (int set); 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual bool RegisterSetStateIsValid (int set) const; 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual uint64_t GetPC(uint64_t failValue); // Get program counter 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual kern_return_t SetPC(uint64_t value); 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual uint64_t GetSP(uint64_t failValue); // Get stack pointer 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual void ThreadWillResume(); 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual bool ThreadDidStop(); 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual bool NotifyException(MachException::Data& exc); 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual uint32_t NumSupportedHardwareWatchpoints(); 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath virtual uint32_t GetHardwareWatchpointHit(); 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprotected: 607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez kern_return_t EnableHardwareSingleStep (bool enable); 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef __i386_thread_state_t GPR; 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef __i386_float_state_t FPU; 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef __i386_exception_state_t EXC; 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef __i386_avx_state_t AVX; 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef __i386_debug_state_t DBG; 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const DNBRegisterInfo g_gpr_registers[]; 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const DNBRegisterInfo g_fpu_registers_no_avx[]; 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const DNBRegisterInfo g_fpu_registers_avx[]; 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const DNBRegisterInfo g_exc_registers[]; 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const DNBRegisterSetInfo g_reg_sets_no_avx[]; 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const DNBRegisterSetInfo g_reg_sets_avx[]; 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const size_t k_num_gpr_registers; 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const size_t k_num_fpu_registers_no_avx; 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const size_t k_num_fpu_registers_avx; 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const size_t k_num_exc_registers; 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const size_t k_num_all_registers_no_avx; 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const size_t k_num_all_registers_avx; 807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez static const size_t k_num_register_sets; 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef enum RegisterSetTag 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetALL = REGISTER_SET_ALL, 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetGPR, 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetFPU, 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetEXC, 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetDBG, 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath kNumRegisterSets 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } RegisterSet; 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef enum RegisterSetWordSizeTag 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetWordSizeGPR = sizeof(GPR) / sizeof(int), 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetWordSizeFPR = sizeof(FPU) / sizeof(int), 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int), 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int), 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath e_regSetWordSizeDBG = sizeof(DBG) / sizeof(int) 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } RegisterSetWordSize; 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Read = 0, 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Write = 1, 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath kNumErrors = 2 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath struct Context 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath GPR gpr; 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath union { 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath FPU no_avx; 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath AVX avx; 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } fpu; 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EXC exc; 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DBG dbg; 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath struct State 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Context context; 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath kern_return_t gpr_errs[2]; // Read/Write errors 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath kern_return_t fpu_errs[2]; // Read/Write errors 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath kern_return_t exc_errs[2]; // Read/Write errors 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath kern_return_t dbg_errs[2]; // Read/Write errors 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath State() 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath uint32_t i; 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (i=0; i<kNumErrors; i++) 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath gpr_errs[i] = -1; 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath fpu_errs[i] = -1; 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath exc_errs[i] = -1; 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dbg_errs[i] = -1; 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void InvalidateAllRegisterStates() 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SetError (e_regSetALL, Read, -1); 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath kern_return_t GetError (int flavor, uint32_t err_idx) const 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (err_idx < kNumErrors) 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath switch (flavor) 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // When getting all errors, just OR all values together to see if 149 // we got any kind of error. 150 case e_regSetALL: return gpr_errs[err_idx] | 151 fpu_errs[err_idx] | 152 exc_errs[err_idx]; 153 case e_regSetGPR: return gpr_errs[err_idx]; 154 case e_regSetFPU: return fpu_errs[err_idx]; 155 case e_regSetEXC: return exc_errs[err_idx]; 156 case e_regSetDBG: return dbg_errs[err_idx]; 157 default: break; 158 } 159 } 160 return -1; 161 } 162 bool SetError (int flavor, uint32_t err_idx, kern_return_t err) 163 { 164 if (err_idx < kNumErrors) 165 { 166 switch (flavor) 167 { 168 case e_regSetALL: 169 gpr_errs[err_idx] = 170 fpu_errs[err_idx] = 171 exc_errs[err_idx] = 172 dbg_errs[err_idx] = err; 173 return true; 174 175 case e_regSetGPR: 176 gpr_errs[err_idx] = err; 177 return true; 178 179 case e_regSetFPU: 180 fpu_errs[err_idx] = err; 181 return true; 182 183 case e_regSetEXC: 184 exc_errs[err_idx] = err; 185 return true; 186 187 case e_regSetDBG: 188 dbg_errs[err_idx] = err; 189 return true; 190 191 default: break; 192 } 193 } 194 return false; 195 } 196 bool RegsAreValid (int flavor) const 197 { 198 return GetError(flavor, Read) == KERN_SUCCESS; 199 } 200 }; 201 202 kern_return_t GetGPRState (bool force); 203 kern_return_t GetFPUState (bool force); 204 kern_return_t GetEXCState (bool force); 205 kern_return_t GetDBGState (bool force); 206 207 kern_return_t SetGPRState (); 208 kern_return_t SetFPUState (); 209 kern_return_t SetEXCState (); 210 kern_return_t SetDBGState (); 211 212 static DNBArchProtocol * 213 Create (MachThread *thread); 214 215 static const uint8_t * const 216 SoftwareBreakpointOpcode (nub_size_t byte_size); 217 218 static const DNBRegisterSetInfo * 219 GetRegisterSetInfo(nub_size_t *num_reg_sets); 220 221 static bool 222 CPUHasAVX() 223 { 224 if (s_has_avx == kAVXUnknown) 225 s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent); 226 227 return (s_has_avx == kAVXPresent); 228 } 229 230 // Helper functions for watchpoint manipulations. 231 static void SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, bool write); 232 static void ClearWatchpoint(DBG &debug_state, uint32_t hw_index); 233 static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index); 234 static void ClearWatchpointHits(DBG &debug_state); 235 static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index); 236 237 MachThread *m_thread; 238 State m_state; 239 240 static enum AVXPresence { 241 kAVXPresent, 242 kAVXNotPresent, 243 kAVXUnknown 244 } s_has_avx; 245}; 246 247#endif // #if defined (__i386__) || defined (__x86_64__) 248#endif // #ifndef __DNBArchImplI386_h__ 249