DNBArchImplI386.h revision db15e0cbbd18d6cd10a0197bae31aafb9e078365
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DNBArchImplI386.h ---------------------------------------*- C++ -*-===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Created by Greg Clayton on 6/25/07. 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef __DNBArchImplI386_h__ 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define __DNBArchImplI386_h__ 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1720d338fad87eba91de65aa9bec76e01c04472848Greg Clayton#if defined (__i386__) || defined (__x86_64__) 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DNBArch.h" 20db15e0cbbd18d6cd10a0197bae31aafb9e078365Sean Callanan#include "../HasAVX.h" 214d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan#include "MachRegisterStatesI386.h" 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass MachThread; 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass DNBArchImplI386 : public DNBArchProtocol 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic: 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DNBArchImplI386(MachThread *thread) : 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_thread(thread), 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner m_state() 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual ~DNBArchImplI386() 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 3620d338fad87eba91de65aa9bec76e01c04472848Greg Clayton 3720d338fad87eba91de65aa9bec76e01c04472848Greg Clayton static void Initialize(); 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 39fa1502444821fb699b14883bd24188c85a8793e0Johnny Chen virtual bool GetRegisterValue(int set, int reg, DNBRegisterValue *value); 40fa1502444821fb699b14883bd24188c85a8793e0Johnny Chen virtual bool SetRegisterValue(int set, int reg, const DNBRegisterValue *value); 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len); 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len); 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual kern_return_t GetRegisterState (int set, bool force); 4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual kern_return_t SetRegisterState (int set); 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual bool RegisterSetStateIsValid (int set) const; 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual uint64_t GetPC(uint64_t failValue); // Get program counter 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual kern_return_t SetPC(uint64_t value); 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual uint64_t GetSP(uint64_t failValue); // Get stack pointer 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual void ThreadWillResume(); 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual bool ThreadDidStop(); 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual bool NotifyException(MachException::Data& exc); 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerprotected: 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t EnableHardwareSingleStep (bool enable); 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 574d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan typedef __i386_thread_state_t GPR; 584d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan typedef __i386_float_state_t FPU; 594d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan typedef __i386_exception_state_t EXC; 604d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan typedef __i386_avx_state_t AVX; 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner static const DNBRegisterInfo g_gpr_registers[]; 634d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static const DNBRegisterInfo g_fpu_registers_no_avx[]; 644d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static const DNBRegisterInfo g_fpu_registers_avx[]; 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner static const DNBRegisterInfo g_exc_registers[]; 664d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static const DNBRegisterSetInfo g_reg_sets_no_avx[]; 674d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static const DNBRegisterSetInfo g_reg_sets_avx[]; 6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner static const size_t k_num_gpr_registers; 694d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static const size_t k_num_fpu_registers_no_avx; 704d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static const size_t k_num_fpu_registers_avx; 7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner static const size_t k_num_exc_registers; 724d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static const size_t k_num_all_registers_no_avx; 734d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static const size_t k_num_all_registers_avx; 7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner static const size_t k_num_register_sets; 7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner typedef enum RegisterSetTag 7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner e_regSetALL = REGISTER_SET_ALL, 7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner e_regSetGPR, 8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner e_regSetFPU, 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner e_regSetEXC, 8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kNumRegisterSets 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } RegisterSet; 8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner typedef enum RegisterSetWordSizeTag 8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 874d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan e_regSetWordSizeGPR = sizeof(GPR) / sizeof(int), 884d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan e_regSetWordSizeFPR = sizeof(FPU) / sizeof(int), 894d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int), 904d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int) 9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } RegisterSetWordSize; 9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner enum 9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Read = 0, 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Write = 1, 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kNumErrors = 2 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner }; 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner struct Context 10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 1024d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan __i386_thread_state_t gpr; 1034d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan union { 1044d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan __i386_float_state_t no_avx; 1054d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan __i386_avx_state_t avx; 1064d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan } fpu; 1074d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan __i386_exception_state_t exc; 10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner }; 10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner struct State 11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner Context context; 11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t gpr_errs[2]; // Read/Write errors 11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t fpu_errs[2]; // Read/Write errors 11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t exc_errs[2]; // Read/Write errors 1164d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan 11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner State() 11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner uint32_t i; 12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (i=0; i<kNumErrors; i++) 12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gpr_errs[i] = -1; 12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fpu_errs[i] = -1; 12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exc_errs[i] = -1; 12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void InvalidateAllRegisterStates() 12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SetError (e_regSetALL, Read, -1); 13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t GetError (int flavor, uint32_t err_idx) const 13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (err_idx < kNumErrors) 13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (flavor) 13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // When getting all errors, just OR all values together to see if 13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // we got any kind of error. 13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case e_regSetALL: return gpr_errs[err_idx] | 14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fpu_errs[err_idx] | 14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exc_errs[err_idx]; 14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case e_regSetGPR: return gpr_errs[err_idx]; 14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case e_regSetFPU: return fpu_errs[err_idx]; 14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case e_regSetEXC: return exc_errs[err_idx]; 14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: break; 14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return -1; 14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool SetError (int flavor, uint32_t err_idx, kern_return_t err) 15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (err_idx < kNumErrors) 15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner switch (flavor) 15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case e_regSetALL: 15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gpr_errs[err_idx] = 15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fpu_errs[err_idx] = 15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exc_errs[err_idx] = err; 16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case e_regSetGPR: 16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gpr_errs[err_idx] = err; 16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case e_regSetFPU: 16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fpu_errs[err_idx] = err; 16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner case e_regSetEXC: 17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner exc_errs[err_idx] = err; 17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return true; 17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner default: break; 17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return false; 17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool RegsAreValid (int flavor) const 18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner { 18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return GetError(flavor, Read) == KERN_SUCCESS; 18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner }; 18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t GetGPRState (bool force); 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t GetFPUState (bool force); 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t GetEXCState (bool force); 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t SetGPRState (); 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t SetFPUState (); 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner kern_return_t SetEXCState (); 19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 19320d338fad87eba91de65aa9bec76e01c04472848Greg Clayton static DNBArchProtocol * 19420d338fad87eba91de65aa9bec76e01c04472848Greg Clayton Create (MachThread *thread); 19520d338fad87eba91de65aa9bec76e01c04472848Greg Clayton 19620d338fad87eba91de65aa9bec76e01c04472848Greg Clayton static const uint8_t * const 19720d338fad87eba91de65aa9bec76e01c04472848Greg Clayton SoftwareBreakpointOpcode (nub_size_t byte_size); 19820d338fad87eba91de65aa9bec76e01c04472848Greg Clayton 19920d338fad87eba91de65aa9bec76e01c04472848Greg Clayton static const DNBRegisterSetInfo * 20020d338fad87eba91de65aa9bec76e01c04472848Greg Clayton GetRegisterSetInfo(nub_size_t *num_reg_sets); 2014d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan 2024d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static bool 203db15e0cbbd18d6cd10a0197bae31aafb9e078365Sean Callanan CPUHasAVX() 2044d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan { 2054d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan if (s_has_avx == kAVXUnknown) 206db15e0cbbd18d6cd10a0197bae31aafb9e078365Sean Callanan s_has_avx = (::HasAVX() ? kAVXPresent : kAVXNotPresent); 2074d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan 2084d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan return (s_has_avx == kAVXPresent); 2094d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan } 21020d338fad87eba91de65aa9bec76e01c04472848Greg Clayton 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner MachThread *m_thread; 2124d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan State m_state; 2134d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan 2144d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan static enum AVXPresence { 2154d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan kAVXPresent, 2164d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan kAVXNotPresent, 2174d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan kAVXUnknown 2184d3a89ef9d015e0cc3c12736b61d367fd98fe073Sean Callanan } s_has_avx; 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}; 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22120d338fad87eba91de65aa9bec76e01c04472848Greg Clayton#endif // #if defined (__i386__) || defined (__x86_64__) 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif // #ifndef __DNBArchImplI386_h__ 223