EmulateInstruction.h revision 7fac857ec72051dc0a91b027719c275ea672a470
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 ArchSpec &arch, 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 // Add or subtract a value from a base address register (other than SP) 119 // arg0 = register kind for base register 120 // arg1 = register number of base register 121 // arg2 = signed offset being applied to base register 122 eContextAdjustBaseRegister, 123 124 // Used in WriteRegister callbacks to indicate where the 125 // arg0 = source register kind 126 // arg1 = source register number 127 // arg2 = source signed offset 128 eContextRegisterPlusOffset, 129 130 // Used in WriteMemory callback to indicate where the data came from 131 // arg0 = register kind 132 // arg1 = register number (register being stored) 133 // arg2 = address of store 134 eContextRegisterStore, 135 136 eContextRegisterLoad, 137 138 // Used when performing a PC-relative branch where the 139 // arg0 = don't care 140 // arg1 = imm32 (signed offset) 141 // arg2 = target instruction set or don't care 142 eContextRelativeBranchImmediate, 143 144 // Used when performing an absolute branch where the 145 // arg0 = target register kind 146 // arg1 = target register number 147 // arg2 = target instruction set or don't care 148 eContextAbsoluteBranchRegister, 149 150 // Used when performing a supervisor call to an operating system to 151 // provide a service: 152 // arg0 = current instruction set or don't care 153 // arg1 = immediate data or don't care 154 // arg2 = don't care 155 eContextSupervisorCall, 156 157 // Used when random bits are written into a register 158 // arg0 = target register kind 159 // arg1 = target register number 160 // arg2 = don't care 161 eContextWriteRegisterRandomBits, 162 163 // Used when random bits are written to memory 164 // arg0 = target memory address 165 // arg1 = don't care 166 // arg2 = don't care 167 eContextWriteMemoryRandomBits 168 }; 169 170 enum InfoType { 171 eInfoTypeRegisterPlusOffset, 172 eInfoTypeRegisterPlusIndirectOffset, 173 eInfoTypeRegisterToRegisterPlusOffset, 174 eInfoTypeOffset, 175 eInfoTypeRegister, 176 eInfoTypeImmediate, 177 eInfoTypeImmediateSigned, 178 eInfoTypeAddress, 179 eInfoTypeModeAndImmediate, 180 eInfoTypeModeAndImmediateSigned, 181 eInfoTypeMode, 182 eInfoTypeNoArgs 183 } InfoType; 184 185 struct Register 186 { 187 uint32_t kind; 188 uint32_t num; 189 190 191 void 192 SetRegister (uint32_t reg_kind, uint32_t reg_num) 193 { 194 kind = reg_kind; 195 num = reg_num; 196 } 197 }; 198 199 struct Context 200 { 201 ContextType type; 202 enum InfoType info_type; 203 union 204 { 205 struct RegisterPlusOffset 206 { 207 Register reg; // base register 208 int64_t signed_offset; // signed offset added to base register 209 } RegisterPlusOffset; 210 211 struct RegisterPlusIndirectOffset 212 { 213 Register base_reg; // base register number 214 Register offset_reg; // offset register kind 215 } RegisterPlusIndirectOffset; 216 217 struct RegisterToRegisterPlusOffset 218 { 219 Register data_reg; // source/target register for data 220 Register base_reg; // base register for address calculation 221 int64_t offset; // offset for address calculation 222 } RegisterToRegisterPlusOffset; 223 224 int64_t signed_offset; // signed offset by which to adjust self (for registers only) 225 226 Register reg; // plain register 227 228 uint64_t immediate; // immediate value 229 230 int64_t signed_immediate; // signed immediate value 231 232 lldb::addr_t address; // direct address 233 234 struct ModeAndImmediate 235 { 236 uint32_t mode; // eModeARM or eModeThumb 237 uint32_t data_value; // immdiate data 238 } ModeAndImmediate; 239 240 struct ModeAndImmediateSigned 241 { 242 uint32_t mode; // eModeARM or eModeThumb 243 int32_t signed_data_value; // signed immdiate data 244 } ModeAndImmediateSigned; 245 246 uint32_t mode; // eModeARM or eModeThumb 247 248 } info; 249 250 void 251 SetRegisterPlusOffset (Register base_reg, 252 int64_t signed_offset) 253 { 254 info_type = eInfoTypeRegisterPlusOffset; 255 info.RegisterPlusOffset.reg = base_reg; 256 info.RegisterPlusOffset.signed_offset = signed_offset; 257 } 258 259 void 260 SetRegisterPlusIndirectOffset (Register base_reg, 261 Register offset_reg) 262 { 263 info_type = eInfoTypeRegisterPlusIndirectOffset; 264 info.RegisterPlusIndirectOffset.base_reg = base_reg; 265 info.RegisterPlusIndirectOffset.offset_reg = offset_reg; 266 } 267 268 void 269 SetRegisterToRegisterPlusOffset (Register data_reg, 270 Register base_reg, 271 int64_t offset) 272 { 273 info_type = eInfoTypeRegisterToRegisterPlusOffset; 274 info.RegisterToRegisterPlusOffset.data_reg = data_reg; 275 info.RegisterToRegisterPlusOffset.base_reg = base_reg; 276 info.RegisterToRegisterPlusOffset.offset = offset; 277 } 278 279 void 280 SetOffset (int64_t signed_offset) 281 { 282 info_type = eInfoTypeOffset; 283 info.signed_offset = signed_offset; 284 } 285 286 void 287 SetRegister (Register reg) 288 { 289 info_type = eInfoTypeRegister; 290 info.reg = reg; 291 } 292 293 void 294 SetImmediate (uint64_t immediate) 295 { 296 info_type = eInfoTypeImmediate; 297 info.immediate = immediate; 298 } 299 300 void 301 SetImmediateSigned (int64_t signed_immediate) 302 { 303 info_type = eInfoTypeImmediateSigned; 304 info.signed_immediate = signed_immediate; 305 } 306 307 void 308 SetAddress (lldb::addr_t address) 309 { 310 info_type = eInfoTypeAddress; 311 info.address = address; 312 } 313 void 314 SetModeAndImmediate (uint32_t mode, uint32_t data_value) 315 { 316 info_type = eInfoTypeModeAndImmediate; 317 info.ModeAndImmediate.mode = mode; 318 info.ModeAndImmediate.data_value = data_value; 319 } 320 321 void 322 SetModeAndImmediateSigned (uint32_t mode, int32_t signed_data_value) 323 { 324 info_type = eInfoTypeModeAndImmediateSigned; 325 info.ModeAndImmediateSigned.mode = mode; 326 info.ModeAndImmediateSigned.signed_data_value = signed_data_value; 327 } 328 329 void 330 SetMode (uint32_t mode) 331 { 332 info_type = eInfoTypeMode; 333 info.mode = mode; 334 } 335 336 void 337 SetNoArgs () 338 { 339 info_type = eInfoTypeNoArgs; 340 } 341 342 }; 343 344 union Opcode 345 { 346 uint8_t inst8; 347 uint16_t inst16; 348 uint32_t inst32; 349 uint64_t inst64; 350 union inst 351 { 352 uint8_t bytes[16]; 353 uint8_t length; 354 }; 355 }; 356 357 enum OpcodeType 358 { 359 eOpcode8, 360 eOpcode16, 361 eOpcode32, 362 eOpcode64, 363 eOpcodeBytes 364 }; 365 366 struct Instruction 367 { 368 OpcodeType opcode_type; 369 Opcode opcode; 370 }; 371 372 typedef size_t (*ReadMemory) (void *baton, 373 const Context &context, 374 lldb::addr_t addr, 375 void *dst, 376 size_t length); 377 378 typedef size_t (*WriteMemory) (void *baton, 379 const Context &context, 380 lldb::addr_t addr, 381 const void *dst, 382 size_t length); 383 384 typedef bool (*ReadRegister) (void *baton, 385 uint32_t reg_kind, 386 uint32_t reg_num, 387 uint64_t ®_value); 388 389 typedef bool (*WriteRegister) (void *baton, 390 const Context &context, 391 uint32_t reg_kind, 392 uint32_t reg_num, 393 uint64_t reg_value); 394 395 EmulateInstruction (lldb::ByteOrder byte_order, 396 uint32_t addr_byte_size, 397 void *baton, 398 ReadMemory read_mem_callback, 399 WriteMemory write_mem_callback, 400 ReadRegister read_reg_callback, 401 WriteRegister write_reg_callback); 402 403 virtual ~EmulateInstruction() 404 { 405 } 406 407 virtual bool 408 SetTargetTriple (const ArchSpec &arch) = 0; 409 410 virtual bool 411 ReadInstruction () = 0; 412 413 virtual bool 414 EvaluateInstruction () = 0; 415 416 uint64_t 417 ReadRegisterUnsigned (uint32_t reg_kind, 418 uint32_t reg_num, 419 uint64_t fail_value, 420 bool *success_ptr); 421 422 bool 423 WriteRegisterUnsigned (const Context &context, 424 uint32_t reg_kind, 425 uint32_t reg_num, 426 uint64_t reg_value); 427 428 uint64_t 429 ReadMemoryUnsigned (const Context &context, 430 lldb::addr_t addr, 431 size_t byte_size, 432 uint64_t fail_value, 433 bool *success_ptr); 434 435 bool 436 WriteMemoryUnsigned (const Context &context, 437 lldb::addr_t addr, 438 uint64_t uval, 439 size_t uval_byte_size); 440 441 uint32_t 442 GetAddressByteSize () const 443 { 444 return m_addr_byte_size; 445 } 446 447 lldb::ByteOrder 448 GetByteOrder () const 449 { 450 return m_byte_order; 451 } 452 453 uint64_t 454 OpcodeAsUnsigned (bool *success_ptr) 455 { 456 if (success_ptr) 457 *success_ptr = true; 458 switch (m_inst.opcode_type) 459 { 460 eOpcode8: return m_inst.opcode.inst8; 461 eOpcode16: return m_inst.opcode.inst16; 462 eOpcode32: return m_inst.opcode.inst32; 463 eOpcode64: return m_inst.opcode.inst64; 464 eOpcodeBytes: 465 break; 466 } 467 if (success_ptr) 468 *success_ptr = false; 469 return 0; 470 } 471 472protected: 473 lldb::ByteOrder m_byte_order; 474 uint32_t m_addr_byte_size; 475 void * m_baton; 476 ReadMemory m_read_mem_callback; 477 WriteMemory m_write_mem_callback; 478 ReadRegister m_read_reg_callback; 479 WriteRegister m_write_reg_callback; 480 481 lldb::addr_t m_inst_pc; 482 Instruction m_inst; 483 //------------------------------------------------------------------ 484 // For EmulateInstruction only 485 //------------------------------------------------------------------ 486 DISALLOW_COPY_AND_ASSIGN (EmulateInstruction); 487}; 488 489} // namespace lldb_private 490 491#endif // lldb_EmulateInstruction_h_ 492