DNBArchImplX86_64.h revision 4d35f889ec869f86e950059470e90c99857ce477
1//===-- DNBArchImplX86_64.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 __DNBArchImplX86_64_h__ 15#define __DNBArchImplX86_64_h__ 16 17#if defined (__i386__) || defined (__x86_64__) 18#include "DNBArch.h" 19#include "../HasAVX.h" 20#include "MachRegisterStatesX86_64.h" 21 22class MachThread; 23 24class DNBArchImplX86_64 : public DNBArchProtocol 25{ 26public: 27 DNBArchImplX86_64(MachThread *thread) : 28 m_thread(thread), 29 m_state(), 30 m_2pc_dbg_checkpoint(), 31 m_2pc_trans_state(Trans_Done) 32 { 33 } 34 virtual ~DNBArchImplX86_64() 35 { 36 } 37 38 static void Initialize(); 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 44 virtual kern_return_t GetRegisterState (int set, bool force); 45 virtual kern_return_t SetRegisterState (int set); 46 virtual bool RegisterSetStateIsValid (int set) const; 47 48 virtual uint64_t GetPC(uint64_t failValue); // Get program counter 49 virtual kern_return_t SetPC(uint64_t value); 50 virtual uint64_t GetSP(uint64_t failValue); // Get stack pointer 51 virtual void ThreadWillResume(); 52 virtual bool ThreadDidStop(); 53 virtual bool NotifyException(MachException::Data& exc); 54 55 virtual uint32_t NumSupportedHardwareWatchpoints(); 56 virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); 57 virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); 58 virtual void HardwareWatchpointStateChanged (); 59 virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr); 60 61protected: 62 kern_return_t EnableHardwareSingleStep (bool enable); 63 64 typedef __x86_64_thread_state_t GPR; 65 typedef __x86_64_float_state_t FPU; 66 typedef __x86_64_exception_state_t EXC; 67 typedef __x86_64_avx_state_t AVX; 68 typedef __x86_64_debug_state_t DBG; 69 70 static const DNBRegisterInfo g_gpr_registers[]; 71 static const DNBRegisterInfo g_fpu_registers_no_avx[]; 72 static const DNBRegisterInfo g_fpu_registers_avx[]; 73 static const DNBRegisterInfo g_exc_registers[]; 74 static const DNBRegisterSetInfo g_reg_sets_no_avx[]; 75 static const DNBRegisterSetInfo g_reg_sets_avx[]; 76 static const size_t k_num_gpr_registers; 77 static const size_t k_num_fpu_registers_no_avx; 78 static const size_t k_num_fpu_registers_avx; 79 static const size_t k_num_exc_registers; 80 static const size_t k_num_all_registers_no_avx; 81 static const size_t k_num_all_registers_avx; 82 static const size_t k_num_register_sets; 83 84 typedef enum RegisterSetTag 85 { 86 e_regSetALL = REGISTER_SET_ALL, 87 e_regSetGPR, 88 e_regSetFPU, 89 e_regSetEXC, 90 e_regSetDBG, 91 kNumRegisterSets 92 } RegisterSet; 93 94 typedef enum RegisterSetWordSizeTag 95 { 96 e_regSetWordSizeGPR = sizeof(GPR) / sizeof(int), 97 e_regSetWordSizeFPU = sizeof(FPU) / sizeof(int), 98 e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int), 99 e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int), 100 e_regSetWordSizeDBG = sizeof(DBG) / sizeof(int) 101 } RegisterSetWordSize; 102 103 enum 104 { 105 Read = 0, 106 Write = 1, 107 kNumErrors = 2 108 }; 109 110 struct Context 111 { 112 GPR gpr; 113 union { 114 FPU no_avx; 115 AVX avx; 116 } fpu; 117 EXC exc; 118 DBG dbg; 119 }; 120 121 // See also HardwareWatchpointStateChanged() which updates this class-wide variable. 122 static DBG Global_Debug_State; 123 static bool Valid_Global_Debug_State; 124 125 struct State 126 { 127 Context context; 128 kern_return_t gpr_errs[2]; // Read/Write errors 129 kern_return_t fpu_errs[2]; // Read/Write errors 130 kern_return_t exc_errs[2]; // Read/Write errors 131 kern_return_t dbg_errs[2]; // Read/Write errors 132 133 State() 134 { 135 uint32_t i; 136 for (i=0; i<kNumErrors; i++) 137 { 138 gpr_errs[i] = -1; 139 fpu_errs[i] = -1; 140 exc_errs[i] = -1; 141 dbg_errs[i] = -1; 142 } 143 } 144 145 void 146 InvalidateAllRegisterStates() 147 { 148 SetError (e_regSetALL, Read, -1); 149 } 150 151 kern_return_t 152 GetError (int flavor, uint32_t err_idx) const 153 { 154 if (err_idx < kNumErrors) 155 { 156 switch (flavor) 157 { 158 // When getting all errors, just OR all values together to see if 159 // we got any kind of error. 160 case e_regSetALL: return gpr_errs[err_idx] | 161 fpu_errs[err_idx] | 162 exc_errs[err_idx]; 163 case e_regSetGPR: return gpr_errs[err_idx]; 164 case e_regSetFPU: return fpu_errs[err_idx]; 165 case e_regSetEXC: return exc_errs[err_idx]; 166 case e_regSetDBG: return dbg_errs[err_idx]; 167 default: break; 168 } 169 } 170 return -1; 171 } 172 173 bool 174 SetError (int flavor, uint32_t err_idx, kern_return_t err) 175 { 176 if (err_idx < kNumErrors) 177 { 178 switch (flavor) 179 { 180 case e_regSetALL: 181 gpr_errs[err_idx] = 182 fpu_errs[err_idx] = 183 exc_errs[err_idx] = 184 dbg_errs[err_idx] = err; 185 return true; 186 187 case e_regSetGPR: 188 gpr_errs[err_idx] = err; 189 return true; 190 191 case e_regSetFPU: 192 fpu_errs[err_idx] = err; 193 return true; 194 195 case e_regSetEXC: 196 exc_errs[err_idx] = err; 197 return true; 198 199 case e_regSetDBG: 200 dbg_errs[err_idx] = err; 201 return true; 202 203 default: break; 204 } 205 } 206 return false; 207 } 208 209 bool 210 RegsAreValid (int flavor) const 211 { 212 return GetError(flavor, Read) == KERN_SUCCESS; 213 } 214 }; 215 216 kern_return_t GetGPRState (bool force); 217 kern_return_t GetFPUState (bool force); 218 kern_return_t GetEXCState (bool force); 219 kern_return_t GetDBGState (bool force); 220 221 kern_return_t SetGPRState (); 222 kern_return_t SetFPUState (); 223 kern_return_t SetEXCState (); 224 kern_return_t SetDBGState (); 225 226 static DNBArchProtocol * 227 Create (MachThread *thread); 228 229 static const uint8_t * const 230 SoftwareBreakpointOpcode (nub_size_t byte_size); 231 232 static const DNBRegisterSetInfo * 233 GetRegisterSetInfo(nub_size_t *num_reg_sets); 234 235 // Helper functions for watchpoint manipulations. 236 static void SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, bool write); 237 static void ClearWatchpoint(DBG &debug_state, uint32_t hw_index); 238 static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index); 239 static void ClearWatchpointHits(DBG &debug_state); 240 static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index); 241 static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index); 242 243 virtual bool StartTransForHWP(); 244 virtual bool RollbackTransForHWP(); 245 virtual bool FinishTransForHWP(); 246 DBG GetDBGCheckpoint(); 247 248 MachThread *m_thread; 249 State m_state; 250 DBG m_2pc_dbg_checkpoint; 251 uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning (0), Done (1), or Rolled Back (2)? 252}; 253 254#endif // #if defined (__i386__) || defined (__x86_64__) 255#endif // #ifndef __DNBArchImplX86_64_h__ 256