EmulateInstruction.h revision 9dd30d0b56d859a0ca600760e46b74a6b674672d
1//===-- EmulateInstruction.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#ifndef lldb_EmulateInstruction_h_ 11#define lldb_EmulateInstruction_h_ 12 13#include "lldb/lldb-include.h" 14#include "lldb/Core/PluginInterface.h" 15 16//---------------------------------------------------------------------- 17/// @class EmulateInstruction EmulateInstruction.h "lldb/Core/EmulateInstruction.h" 18/// @brief A class that allows emulation of CPU opcodes. 19/// 20/// This class is a plug-in interface that is accessed through the 21/// standard static FindPlugin function call in the EmulateInstruction 22/// class. The FindPlugin takes a target triple and returns a new object 23/// if there is a plug-in that supports the architecture and OS. Four 24/// callbacks and a baton are provided. The four callbacks are read 25/// register, write register, read memory and write memory. 26/// 27/// This class is currently designed for these main use cases: 28/// - Auto generation of Call Frame Information (CFI) from assembly code 29/// - Predicting single step breakpoint locations 30/// - Emulating instructions for breakpoint traps 31/// 32/// Objects can be asked to read an instruction which will cause a call 33/// to the read register callback to get the PC, followed by a read 34/// memory call to read the opcode. If ReadInstruction () returns true, 35/// then a call to EmulateInstruction::EvaluateInstruction () can be 36/// made. At this point the EmulateInstruction subclass will use all of 37/// the callbacks to emulate an instruction. 38/// 39/// Clients that provide the callbacks can either do the read/write 40/// registers/memory to actually emulate the instruction on a real or 41/// virtual CPU, or watch for the EmulateInstruction::Context which 42/// is context for the read/write register/memory which explains why 43/// the callback is being called. Examples of a context are: 44/// "pushing register 3 onto the stack at offset -12", or "adjusting 45/// stack pointer by -16". This extra context allows the generation of 46/// CFI information from assembly code without having to actually do 47/// the read/write register/memory. 48/// 49/// Clients must be prepared that not all instructions for an 50/// Instruction Set Architecture (ISA) will be emulated. 51/// 52/// Subclasses at the very least should implement the instructions that 53/// save and restore regiters onto the stack and adjustment to the stack 54/// pointer. By just implementing a few instructions for an ISA that are 55/// the typical prologue opcodes, you can then generate CFI using a 56/// class that will soon be available. 57/// 58/// Implmenting all of the instructions that affect the PC can then 59/// allow single step prediction support. 60/// 61/// Implmenting all of the instructions allows for emulation of opcodes 62/// for breakpoint traps and will pave the way for "thread centric" 63/// debugging. The current debugging model is "process centric" where 64/// all threads must be stopped when any thread is stopped since when 65/// hitting software breakpoints once must disable the breakpoint by 66/// restoring the original breakpoint opcde, single stepping and 67/// restoring the breakpoint trap. If all threads were allowed to run 68/// then other threads could miss the breakpoint. 69/// 70/// This class centralizes the code that usually is done in separate 71/// code paths in a debugger (single step prediction, finding save 72/// restore locations of registers for unwinding stack frame variables, 73/// and emulating the intruction is just a bonus. 74//---------------------------------------------------------------------- 75 76namespace lldb_private { 77 78class EmulateInstruction : 79 public PluginInterface 80{ 81public: 82 83 static EmulateInstruction* 84 FindPlugin (const ConstString &triple, const char *plugin_name); 85 86 enum ContextType 87 { 88 eContextInvalid = 0, 89 // Read an instruciton opcode from memory 90 eContextReadOpcode, 91 92 // Usually used for writing a register value whose source value in an 93 // immediate 94 eContextImmediate, 95 96 // Exclusively used when saving a register to the stack as part of the 97 // prologue 98 // arg0 = register kind 99 // arg1 = register number 100 // arg2 = signed offset from current SP value where register is being 101 // stored 102 eContextPushRegisterOnStack, 103 104 // Exclusively used when restoring a register off the stack as part of 105 // the epilogue 106 // arg0 = register kind 107 // arg1 = register number 108 // arg2 = signed offset from current SP value where register is being 109 // restored 110 eContextPopRegisterOffStack, 111 112 // Add or subtract a value from the stack 113 // arg0 = register kind for SP 114 // arg1 = register number for SP 115 // arg2 = signed offset being applied to the SP value 116 eContextAdjustStackPointer, 117 118 // Used in WriteRegister callbacks to indicate where the 119 // arg0 = source register kind 120 // arg1 = source register number 121 // arg2 = source signed offset 122 eContextRegisterPlusOffset, 123 124 // Used when performing a PC-relative branch where the 125 // arg0 = don't care 126 // arg1 = imm32 (signed offset) 127 // arg2 = target instruction set or don't care 128 eContextRelativeBranchImmediate, 129 130 // Used when performing an absolute branch where the 131 // arg0 = target register kind 132 // arg1 = target register number 133 // arg2 = target instruction set or don't care 134 eContextAbsoluteBranchRegister, 135 136 // Used when performing a supervisor call to an operating system to 137 // provide a service: 138 // arg0 = current instruction set or don't care 139 // arg1 = immediate data or don't care 140 // arg2 = don't care 141 eContextSupervisorCall 142 }; 143 144 struct Context 145 { 146 ContextType type; 147 lldb::addr_t arg0; // Register kind. 148 lldb::addr_t arg1; // Register spec. 149 int64_t arg2; // Possible negative value. 150 }; 151 152 union Opcode 153 { 154 uint8_t inst8; 155 uint16_t inst16; 156 uint32_t inst32; 157 uint64_t inst64; 158 union inst 159 { 160 uint8_t bytes[16]; 161 uint8_t length; 162 }; 163 }; 164 165 enum OpcodeType 166 { 167 eOpcode8, 168 eOpcode16, 169 eOpcode32, 170 eOpcode64, 171 eOpcodeBytes 172 }; 173 174 struct Instruction 175 { 176 OpcodeType opcode_type; 177 Opcode opcode; 178 }; 179 180 typedef size_t (*ReadMemory) (void *baton, 181 const Context &context, 182 lldb::addr_t addr, 183 void *dst, 184 size_t length); 185 186 typedef size_t (*WriteMemory) (void *baton, 187 const Context &context, 188 lldb::addr_t addr, 189 const void *dst, 190 size_t length); 191 192 typedef bool (*ReadRegister) (void *baton, 193 uint32_t reg_kind, 194 uint32_t reg_num, 195 uint64_t ®_value); 196 197 typedef bool (*WriteRegister) (void *baton, 198 const Context &context, 199 uint32_t reg_kind, 200 uint32_t reg_num, 201 uint64_t reg_value); 202 203 EmulateInstruction (lldb::ByteOrder byte_order, 204 uint32_t addr_byte_size, 205 void *baton, 206 ReadMemory read_mem_callback, 207 WriteMemory write_mem_callback, 208 ReadRegister read_reg_callback, 209 WriteRegister write_reg_callback); 210 211 virtual ~EmulateInstruction() 212 { 213 } 214 215 virtual bool 216 SetTargetTriple (const ConstString &triple) = 0; 217 218 virtual bool 219 ReadInstruction () = 0; 220 221 virtual bool 222 EvaluateInstruction () = 0; 223 224 uint64_t 225 ReadRegisterUnsigned (uint32_t reg_kind, 226 uint32_t reg_num, 227 uint64_t fail_value, 228 bool *success_ptr); 229 230 bool 231 WriteRegisterUnsigned (const Context &context, 232 uint32_t reg_kind, 233 uint32_t reg_num, 234 uint64_t reg_value); 235 236 uint64_t 237 ReadMemoryUnsigned (const Context &context, 238 lldb::addr_t addr, 239 size_t byte_size, 240 uint64_t fail_value, 241 bool *success_ptr); 242 243 bool 244 WriteMemoryUnsigned (const Context &context, 245 lldb::addr_t addr, 246 uint64_t uval, 247 size_t uval_byte_size); 248 249 uint32_t 250 GetAddressByteSize () const 251 { 252 return m_addr_byte_size; 253 } 254 255 lldb::ByteOrder 256 GetByteOrder () const 257 { 258 return m_byte_order; 259 } 260 261 uint64_t 262 OpcodeAsUnsigned (bool *success_ptr) 263 { 264 if (success_ptr) 265 *success_ptr = true; 266 switch (m_inst.opcode_type) 267 { 268 eOpcode8: return m_inst.opcode.inst8; 269 eOpcode16: return m_inst.opcode.inst16; 270 eOpcode32: return m_inst.opcode.inst32; 271 eOpcode64: return m_inst.opcode.inst64; 272 eOpcodeBytes: 273 break; 274 } 275 if (success_ptr) 276 *success_ptr = false; 277 return 0; 278 } 279 280protected: 281 lldb::ByteOrder m_byte_order; 282 uint32_t m_addr_byte_size; 283 void * m_baton; 284 ReadMemory m_read_mem_callback; 285 WriteMemory m_write_mem_callback; 286 ReadRegister m_read_reg_callback; 287 WriteRegister m_write_reg_callback; 288 289 lldb::addr_t m_inst_pc; 290 Instruction m_inst; 291 //------------------------------------------------------------------ 292 // For EmulateInstruction only 293 //------------------------------------------------------------------ 294 DISALLOW_COPY_AND_ASSIGN (EmulateInstruction); 295}; 296 297} // namespace lldb_private 298 299#endif // lldb_EmulateInstruction_h_ 300