DNBArchImplX86_64.h revision 20d338fad87eba91de65aa9bec76e01c04472848
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 <mach/mach_types.h> 20#include <mach/thread_status.h> 21 22 23class MachThread; 24 25class DNBArchImplX86_64 : public DNBArchProtocol 26{ 27public: 28 DNBArchImplX86_64(MachThread *thread) : 29 m_thread(thread), 30 m_state() 31 { 32 } 33 virtual ~DNBArchImplX86_64() 34 { 35 } 36 37 static void Initialize(); 38 virtual bool GetRegisterValue(int set, int reg, DNBRegisterValue *value); 39 virtual bool SetRegisterValue(int set, int reg, const DNBRegisterValue *value); 40 virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len); 41 virtual nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len); 42 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 x86_thread_state64_t GPR; 58 typedef x86_float_state64_t FPU; 59 typedef x86_exception_state64_t EXC; 60 61 static const DNBRegisterInfo g_gpr_registers[]; 62 static const DNBRegisterInfo g_fpu_registers[]; 63 static const DNBRegisterInfo g_exc_registers[]; 64 static const DNBRegisterSetInfo g_reg_sets[]; 65 static const size_t k_num_gpr_registers; 66 static const size_t k_num_fpu_registers; 67 static const size_t k_num_exc_registers; 68 static const size_t k_num_all_registers; 69 static const size_t k_num_register_sets; 70 71 typedef enum RegisterSetTag 72 { 73 e_regSetALL = REGISTER_SET_ALL, 74 e_regSetGPR, 75 e_regSetFPU, 76 e_regSetEXC, 77 kNumRegisterSets 78 } RegisterSet; 79 80 81 enum 82 { 83 Read = 0, 84 Write = 1, 85 kNumErrors = 2 86 }; 87 88 struct Context 89 { 90 GPR gpr; 91 FPU fpu; 92 EXC exc; 93 }; 94 95 struct State 96 { 97 Context context; 98 kern_return_t gpr_errs[2]; // Read/Write errors 99 kern_return_t fpu_errs[2]; // Read/Write errors 100 kern_return_t exc_errs[2]; // Read/Write errors 101 102 State() 103 { 104 uint32_t i; 105 for (i=0; i<kNumErrors; i++) 106 { 107 gpr_errs[i] = -1; 108 fpu_errs[i] = -1; 109 exc_errs[i] = -1; 110 } 111 } 112 113 void 114 InvalidateAllRegisterStates() 115 { 116 SetError (e_regSetALL, Read, -1); 117 } 118 119 kern_return_t 120 GetError (int flavor, uint32_t err_idx) const 121 { 122 if (err_idx < kNumErrors) 123 { 124 switch (flavor) 125 { 126 // When getting all errors, just OR all values together to see if 127 // we got any kind of error. 128 case e_regSetALL: return gpr_errs[err_idx] | 129 fpu_errs[err_idx] | 130 exc_errs[err_idx]; 131 case e_regSetGPR: return gpr_errs[err_idx]; 132 case e_regSetFPU: return fpu_errs[err_idx]; 133 case e_regSetEXC: return exc_errs[err_idx]; 134 default: break; 135 } 136 } 137 return -1; 138 } 139 140 bool 141 SetError (int flavor, uint32_t err_idx, kern_return_t err) 142 { 143 if (err_idx < kNumErrors) 144 { 145 switch (flavor) 146 { 147 case e_regSetALL: 148 gpr_errs[err_idx] = 149 fpu_errs[err_idx] = 150 exc_errs[err_idx] = err; 151 return true; 152 153 case e_regSetGPR: 154 gpr_errs[err_idx] = err; 155 return true; 156 157 case e_regSetFPU: 158 fpu_errs[err_idx] = err; 159 return true; 160 161 case e_regSetEXC: 162 exc_errs[err_idx] = err; 163 return true; 164 165 default: break; 166 } 167 } 168 return false; 169 } 170 171 bool 172 RegsAreValid (int flavor) const 173 { 174 return GetError(flavor, Read) == KERN_SUCCESS; 175 } 176 }; 177 178 kern_return_t GetGPRState (bool force); 179 kern_return_t GetFPUState (bool force); 180 kern_return_t GetEXCState (bool force); 181 182 kern_return_t SetGPRState (); 183 kern_return_t SetFPUState (); 184 kern_return_t SetEXCState (); 185 186 static DNBArchProtocol * 187 Create (MachThread *thread); 188 189 static const uint8_t * const 190 SoftwareBreakpointOpcode (nub_size_t byte_size); 191 192 static const DNBRegisterSetInfo * 193 GetRegisterSetInfo(nub_size_t *num_reg_sets); 194 195 MachThread *m_thread; 196 State m_state; 197}; 198 199#endif // #if defined (__i386__) || defined (__x86_64__) 200#endif // #ifndef __DNBArchImplX86_64_h__ 201