1 //===-- DNBArchImplI386.h ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Created by Greg Clayton on 6/25/07.
12 //===----------------------------------------------------------------------===//
14 #ifndef __DNBArchImplI386_h__
15 #define __DNBArchImplI386_h__
17 #if defined (__i386__) || defined (__x86_64__)
20 #include "../HasAVX.h"
21 #include "MachRegisterStatesI386.h"
27 class DNBArchImplI386 : public DNBArchProtocol
30 DNBArchImplI386(MachThread *thread) :
34 m_2pc_dbg_checkpoint(),
35 m_2pc_trans_state(Trans_Done),
36 m_saved_register_states()
39 virtual ~DNBArchImplI386()
43 static void Initialize();
45 virtual bool GetRegisterValue(uint32_t set, uint32_t reg, DNBRegisterValue *value);
46 virtual bool SetRegisterValue(uint32_t set, uint32_t reg, const DNBRegisterValue *value);
47 virtual nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len);
48 virtual nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len);
49 virtual uint32_t SaveRegisterState ();
50 virtual bool RestoreRegisterState (uint32_t save_id);
52 virtual kern_return_t GetRegisterState (int set, bool force);
53 virtual kern_return_t SetRegisterState (int set);
54 virtual bool RegisterSetStateIsValid (int set) const;
56 virtual uint64_t GetPC(uint64_t failValue); // Get program counter
57 virtual kern_return_t SetPC(uint64_t value);
58 virtual uint64_t GetSP(uint64_t failValue); // Get stack pointer
59 virtual void ThreadWillResume();
60 virtual bool ThreadDidStop();
61 virtual bool NotifyException(MachException::Data& exc);
63 virtual uint32_t NumSupportedHardwareWatchpoints();
64 virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write, bool also_set_on_task);
65 virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index, bool also_set_on_task);
66 virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr);
69 kern_return_t EnableHardwareSingleStep (bool enable);
71 typedef __i386_thread_state_t GPR;
72 typedef __i386_float_state_t FPU;
73 typedef __i386_exception_state_t EXC;
74 typedef __i386_avx_state_t AVX;
75 typedef __i386_debug_state_t DBG;
77 static const DNBRegisterInfo g_gpr_registers[];
78 static const DNBRegisterInfo g_fpu_registers_no_avx[];
79 static const DNBRegisterInfo g_fpu_registers_avx[];
80 static const DNBRegisterInfo g_exc_registers[];
81 static const DNBRegisterSetInfo g_reg_sets_no_avx[];
82 static const DNBRegisterSetInfo g_reg_sets_avx[];
83 static const size_t k_num_gpr_registers;
84 static const size_t k_num_fpu_registers_no_avx;
85 static const size_t k_num_fpu_registers_avx;
86 static const size_t k_num_exc_registers;
87 static const size_t k_num_all_registers_no_avx;
88 static const size_t k_num_all_registers_avx;
89 static const size_t k_num_register_sets;
91 typedef enum RegisterSetTag
93 e_regSetALL = REGISTER_SET_ALL,
101 typedef enum RegisterSetWordSizeTag
103 e_regSetWordSizeGPR = sizeof(GPR) / sizeof(int),
104 e_regSetWordSizeFPU = sizeof(FPU) / sizeof(int),
105 e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int),
106 e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int),
107 e_regSetWordSizeDBG = sizeof(DBG) / sizeof(int)
108 } RegisterSetWordSize;
131 kern_return_t gpr_errs[2]; // Read/Write errors
132 kern_return_t fpu_errs[2]; // Read/Write errors
133 kern_return_t exc_errs[2]; // Read/Write errors
134 kern_return_t dbg_errs[2]; // Read/Write errors
139 for (i=0; i<kNumErrors; i++)
147 void InvalidateAllRegisterStates()
149 SetError (e_regSetALL, Read, -1);
151 kern_return_t GetError (int flavor, uint32_t err_idx) const
153 if (err_idx < kNumErrors)
157 // When getting all errors, just OR all values together to see if
158 // we got any kind of error.
159 case e_regSetALL: return gpr_errs[err_idx] |
162 case e_regSetGPR: return gpr_errs[err_idx];
163 case e_regSetFPU: return fpu_errs[err_idx];
164 case e_regSetEXC: return exc_errs[err_idx];
165 case e_regSetDBG: return dbg_errs[err_idx];
171 bool SetError (int flavor, uint32_t err_idx, kern_return_t err)
173 if (err_idx < kNumErrors)
181 dbg_errs[err_idx] = err;
185 gpr_errs[err_idx] = err;
189 fpu_errs[err_idx] = err;
193 exc_errs[err_idx] = err;
197 dbg_errs[err_idx] = err;
205 bool RegsAreValid (int flavor) const
207 return GetError(flavor, Read) == KERN_SUCCESS;
211 kern_return_t GetGPRState (bool force);
212 kern_return_t GetFPUState (bool force);
213 kern_return_t GetEXCState (bool force);
214 kern_return_t GetDBGState (bool force);
216 kern_return_t SetGPRState ();
217 kern_return_t SetFPUState ();
218 kern_return_t SetEXCState ();
219 kern_return_t SetDBGState (bool also_set_on_task);
221 static DNBArchProtocol *
222 Create (MachThread *thread);
224 static const uint8_t *
225 SoftwareBreakpointOpcode (nub_size_t byte_size);
227 static const DNBRegisterSetInfo *
228 GetRegisterSetInfo(nub_size_t *num_reg_sets);
231 GetRegisterContextSize();
233 // Helper functions for watchpoint manipulations.
234 static void SetWatchpoint(DBG &debug_state, uint32_t hw_index, nub_addr_t addr, nub_size_t size, bool read, bool write);
235 static void ClearWatchpoint(DBG &debug_state, uint32_t hw_index);
236 static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index);
237 static void ClearWatchpointHits(DBG &debug_state);
238 static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
239 static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
241 virtual bool StartTransForHWP();
242 virtual bool RollbackTransForHWP();
243 virtual bool FinishTransForHWP();
244 DBG GetDBGCheckpoint();
246 MachThread *m_thread;
248 DBG m_2pc_dbg_checkpoint;
249 uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning (0), Done (1), or Rolled Back (2)?
250 typedef std::map<uint32_t, Context> SaveRegisterStates;
251 SaveRegisterStates m_saved_register_states;
254 #endif // #if defined (__i386__) || defined (__x86_64__)
255 #endif // #ifndef __DNBArchImplI386_h__