EmulateInstruction.h revision ea69d6ddc37e25d57973699463110b6c3233f0a0
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 <string> 14 15#include "lldb/lldb-public.h" 16#include "lldb/Core/ArchSpec.h" 17#include "lldb/Core/PluginInterface.h" 18#include "lldb/Core/Opcode.h" 19 20//---------------------------------------------------------------------- 21/// @class EmulateInstruction EmulateInstruction.h "lldb/Core/EmulateInstruction.h" 22/// @brief A class that allows emulation of CPU opcodes. 23/// 24/// This class is a plug-in interface that is accessed through the 25/// standard static FindPlugin function call in the EmulateInstruction 26/// class. The FindPlugin takes a target triple and returns a new object 27/// if there is a plug-in that supports the architecture and OS. Four 28/// callbacks and a baton are provided. The four callbacks are read 29/// register, write register, read memory and write memory. 30/// 31/// This class is currently designed for these main use cases: 32/// - Auto generation of Call Frame Information (CFI) from assembly code 33/// - Predicting single step breakpoint locations 34/// - Emulating instructions for breakpoint traps 35/// 36/// Objects can be asked to read an instruction which will cause a call 37/// to the read register callback to get the PC, followed by a read 38/// memory call to read the opcode. If ReadInstruction () returns true, 39/// then a call to EmulateInstruction::EvaluateInstruction () can be 40/// made. At this point the EmulateInstruction subclass will use all of 41/// the callbacks to emulate an instruction. 42/// 43/// Clients that provide the callbacks can either do the read/write 44/// registers/memory to actually emulate the instruction on a real or 45/// virtual CPU, or watch for the EmulateInstruction::Context which 46/// is context for the read/write register/memory which explains why 47/// the callback is being called. Examples of a context are: 48/// "pushing register 3 onto the stack at offset -12", or "adjusting 49/// stack pointer by -16". This extra context allows the generation of 50/// CFI information from assembly code without having to actually do 51/// the read/write register/memory. 52/// 53/// Clients must be prepared that not all instructions for an 54/// Instruction Set Architecture (ISA) will be emulated. 55/// 56/// Subclasses at the very least should implement the instructions that 57/// save and restore regiters onto the stack and adjustment to the stack 58/// pointer. By just implementing a few instructions for an ISA that are 59/// the typical prologue opcodes, you can then generate CFI using a 60/// class that will soon be available. 61/// 62/// Implmenting all of the instructions that affect the PC can then 63/// allow single step prediction support. 64/// 65/// Implmenting all of the instructions allows for emulation of opcodes 66/// for breakpoint traps and will pave the way for "thread centric" 67/// debugging. The current debugging model is "process centric" where 68/// all threads must be stopped when any thread is stopped since when 69/// hitting software breakpoints once must disable the breakpoint by 70/// restoring the original breakpoint opcde, single stepping and 71/// restoring the breakpoint trap. If all threads were allowed to run 72/// then other threads could miss the breakpoint. 73/// 74/// This class centralizes the code that usually is done in separate 75/// code paths in a debugger (single step prediction, finding save 76/// restore locations of registers for unwinding stack frame variables, 77/// and emulating the intruction is just a bonus. 78//---------------------------------------------------------------------- 79 80namespace lldb_private { 81 82class EmulateInstruction : 83 public PluginInterface 84{ 85public: 86 87 static EmulateInstruction* 88 FindPlugin (const ArchSpec &arch, const char *plugin_name); 89 90 enum ContextType 91 { 92 eContextInvalid = 0, 93 // Read an instruciton opcode from memory 94 eContextReadOpcode, 95 96 // Usually used for writing a register value whose source value in an 97 // immediate 98 eContextImmediate, 99 100 // Exclusively used when saving a register to the stack as part of the 101 // prologue 102 eContextPushRegisterOnStack, 103 104 // Exclusively used when restoring a register off the stack as part of 105 // the epilogue 106 eContextPopRegisterOffStack, 107 108 // Add or subtract a value from the stack 109 eContextAdjustStackPointer, 110 111 // Add or subtract a value from a base address register (other than SP) 112 eContextAdjustBaseRegister, 113 114 // Used in WriteRegister callbacks to indicate where the 115 eContextRegisterPlusOffset, 116 117 // Used in WriteMemory callback to indicate where the data came from 118 eContextRegisterStore, 119 120 eContextRegisterLoad, 121 122 // Used when performing a PC-relative branch where the 123 eContextRelativeBranchImmediate, 124 125 // Used when performing an absolute branch where the 126 eContextAbsoluteBranchRegister, 127 128 // Used when performing a supervisor call to an operating system to 129 // provide a service: 130 eContextSupervisorCall, 131 132 // Used when performing a MemU operation to read the PC-relative offset 133 // from an address. 134 eContextTableBranchReadMemory, 135 136 // Used when random bits are written into a register 137 eContextWriteRegisterRandomBits, 138 139 // Used when random bits are written to memory 140 eContextWriteMemoryRandomBits, 141 142 eContextMultiplication, 143 144 eContextAddition, 145 146 eContextSubtraction, 147 148 eContextReturnFromException 149 }; 150 151 enum InfoType { 152 eInfoTypeRegisterPlusOffset, 153 eInfoTypeRegisterPlusIndirectOffset, 154 eInfoTypeRegisterToRegisterPlusOffset, 155 eInfoTypeRegisterToRegisterPlusIndirectOffset, 156 eInfoTypeRegisterRegisterOperands, 157 eInfoTypeOffset, 158 eInfoTypeRegister, 159 eInfoTypeImmediate, 160 eInfoTypeImmediateSigned, 161 eInfoTypeAddress, 162 eInfoTypeModeAndImmediate, 163 eInfoTypeModeAndImmediateSigned, 164 eInfoTypeMode, 165 eInfoTypeNoArgs 166 } InfoType; 167 168 struct Register 169 { 170 uint32_t kind; 171 uint32_t num; 172 173 174 void 175 SetRegister (uint32_t reg_kind, uint32_t reg_num) 176 { 177 kind = reg_kind; 178 num = reg_num; 179 } 180 }; 181 182 struct Context 183 { 184 ContextType type; 185 enum InfoType info_type; 186 union 187 { 188 struct RegisterPlusOffset 189 { 190 Register reg; // base register 191 int64_t signed_offset; // signed offset added to base register 192 } RegisterPlusOffset; 193 194 struct RegisterPlusIndirectOffset 195 { 196 Register base_reg; // base register number 197 Register offset_reg; // offset register kind 198 } RegisterPlusIndirectOffset; 199 200 struct RegisterToRegisterPlusOffset 201 { 202 Register data_reg; // source/target register for data 203 Register base_reg; // base register for address calculation 204 int64_t offset; // offset for address calculation 205 } RegisterToRegisterPlusOffset; 206 207 struct RegisterToRegisterPlusIndirectOffset 208 { 209 Register base_reg; // base register for address calculation 210 Register offset_reg; // offset register for address calculation 211 Register data_reg; // source/target register for data 212 } RegisterToRegisterPlusIndirectOffset; 213 214 struct RegisterRegisterOperands 215 { 216 Register operand1; // register containing first operand for binary op 217 Register operand2; // register containing second operand for binary op 218 } RegisterRegisterOperands; 219 220 int64_t signed_offset; // signed offset by which to adjust self (for registers only) 221 222 Register reg; // plain register 223 224 uint64_t immediate; // immediate value 225 226 int64_t signed_immediate; // signed immediate value 227 228 lldb::addr_t address; // direct address 229 230 struct ModeAndImmediate 231 { 232 uint32_t mode; // eModeARM or eModeThumb 233 uint32_t data_value; // immdiate data 234 } ModeAndImmediate; 235 236 struct ModeAndImmediateSigned 237 { 238 uint32_t mode; // eModeARM or eModeThumb 239 int32_t signed_data_value; // signed immdiate data 240 } ModeAndImmediateSigned; 241 242 uint32_t mode; // eModeARM or eModeThumb 243 244 } info; 245 246 void 247 SetRegisterPlusOffset (Register base_reg, 248 int64_t signed_offset) 249 { 250 info_type = eInfoTypeRegisterPlusOffset; 251 info.RegisterPlusOffset.reg = base_reg; 252 info.RegisterPlusOffset.signed_offset = signed_offset; 253 } 254 255 void 256 SetRegisterPlusIndirectOffset (Register base_reg, 257 Register offset_reg) 258 { 259 info_type = eInfoTypeRegisterPlusIndirectOffset; 260 info.RegisterPlusIndirectOffset.base_reg = base_reg; 261 info.RegisterPlusIndirectOffset.offset_reg = offset_reg; 262 } 263 264 void 265 SetRegisterToRegisterPlusOffset (Register data_reg, 266 Register base_reg, 267 int64_t offset) 268 { 269 info_type = eInfoTypeRegisterToRegisterPlusOffset; 270 info.RegisterToRegisterPlusOffset.data_reg = data_reg; 271 info.RegisterToRegisterPlusOffset.base_reg = base_reg; 272 info.RegisterToRegisterPlusOffset.offset = offset; 273 } 274 275 void 276 SetRegisterToRegisterPlusIndirectOffset (Register base_reg, 277 Register offset_reg, 278 Register data_reg) 279 { 280 info_type = eInfoTypeRegisterToRegisterPlusIndirectOffset; 281 info.RegisterToRegisterPlusIndirectOffset.base_reg = base_reg; 282 info.RegisterToRegisterPlusIndirectOffset.offset_reg = offset_reg; 283 info.RegisterToRegisterPlusIndirectOffset.data_reg = data_reg; 284 } 285 286 void 287 SetRegisterRegisterOperands (Register op1_reg, 288 Register op2_reg) 289 { 290 info_type = eInfoTypeRegisterRegisterOperands; 291 info.RegisterRegisterOperands.operand1 = op1_reg; 292 info.RegisterRegisterOperands.operand2 = op2_reg; 293 } 294 295 void 296 SetOffset (int64_t signed_offset) 297 { 298 info_type = eInfoTypeOffset; 299 info.signed_offset = signed_offset; 300 } 301 302 void 303 SetRegister (Register reg) 304 { 305 info_type = eInfoTypeRegister; 306 info.reg = reg; 307 } 308 309 void 310 SetImmediate (uint64_t immediate) 311 { 312 info_type = eInfoTypeImmediate; 313 info.immediate = immediate; 314 } 315 316 void 317 SetImmediateSigned (int64_t signed_immediate) 318 { 319 info_type = eInfoTypeImmediateSigned; 320 info.signed_immediate = signed_immediate; 321 } 322 323 void 324 SetAddress (lldb::addr_t address) 325 { 326 info_type = eInfoTypeAddress; 327 info.address = address; 328 } 329 void 330 SetModeAndImmediate (uint32_t mode, uint32_t data_value) 331 { 332 info_type = eInfoTypeModeAndImmediate; 333 info.ModeAndImmediate.mode = mode; 334 info.ModeAndImmediate.data_value = data_value; 335 } 336 337 void 338 SetModeAndImmediateSigned (uint32_t mode, int32_t signed_data_value) 339 { 340 info_type = eInfoTypeModeAndImmediateSigned; 341 info.ModeAndImmediateSigned.mode = mode; 342 info.ModeAndImmediateSigned.signed_data_value = signed_data_value; 343 } 344 345 void 346 SetMode (uint32_t mode) 347 { 348 info_type = eInfoTypeMode; 349 info.mode = mode; 350 } 351 352 void 353 SetNoArgs () 354 { 355 info_type = eInfoTypeNoArgs; 356 } 357 358 }; 359 360 static void 361 PrintContext (const char *context_type, const Context &context); 362 363 typedef size_t (*ReadMemory) (void *baton, 364 const Context &context, 365 lldb::addr_t addr, 366 void *dst, 367 size_t length); 368 369 typedef size_t (*WriteMemory) (void *baton, 370 const Context &context, 371 lldb::addr_t addr, 372 const void *dst, 373 size_t length); 374 375 typedef bool (*ReadRegister) (void *baton, 376 uint32_t reg_kind, 377 uint32_t reg_num, 378 uint64_t ®_value); 379 380 typedef bool (*WriteRegister) (void *baton, 381 const Context &context, 382 uint32_t reg_kind, 383 uint32_t reg_num, 384 uint64_t reg_value); 385 386 EmulateInstruction (lldb::ByteOrder byte_order, 387 uint32_t addr_byte_size, 388 const ArchSpec &arch, 389 void *baton, 390 ReadMemory read_mem_callback, 391 WriteMemory write_mem_callback, 392 ReadRegister read_reg_callback, 393 WriteRegister write_reg_callback); 394 395 EmulateInstruction (lldb::ByteOrder byte_order, 396 uint32_t addr_byte_size, 397 const ArchSpec &arch); 398 399 virtual ~EmulateInstruction() 400 { 401 } 402 403 virtual bool 404 SetTargetTriple (const ArchSpec &arch) = 0; 405 406 virtual bool 407 ReadInstruction () = 0; 408 409 virtual bool 410 SetInstruction (const Opcode &insn_opcode, const Address &inst_addr) = 0; 411 412 virtual bool 413 EvaluateInstruction () = 0; 414 415 static void 416 TranslateRegister (uint32_t reg_kind, uint32_t reg_num, std::string ®_name); 417 418 uint64_t 419 ReadRegisterUnsigned (uint32_t reg_kind, 420 uint32_t reg_num, 421 uint64_t fail_value, 422 bool *success_ptr); 423 424 bool 425 WriteRegisterUnsigned (const Context &context, 426 uint32_t reg_kind, 427 uint32_t reg_num, 428 uint64_t reg_value); 429 430 uint64_t 431 ReadMemoryUnsigned (const Context &context, 432 lldb::addr_t addr, 433 size_t byte_size, 434 uint64_t fail_value, 435 bool *success_ptr); 436 437 bool 438 WriteMemoryUnsigned (const Context &context, 439 lldb::addr_t addr, 440 uint64_t uval, 441 size_t uval_byte_size); 442 443 uint32_t 444 GetAddressByteSize () const 445 { 446 return m_addr_byte_size; 447 } 448 449 lldb::ByteOrder 450 GetByteOrder () const 451 { 452 return m_byte_order; 453 } 454 455 const Opcode & 456 GetOpcode () const 457 { 458 return m_opcode; 459 } 460 461 462 static size_t 463 ReadMemoryFrame (void *baton, 464 const Context &context, 465 lldb::addr_t addr, 466 void *dst, 467 size_t length); 468 469 static size_t 470 WriteMemoryFrame (void *baton, 471 const Context &context, 472 lldb::addr_t addr, 473 const void *dst, 474 size_t length); 475 476 static bool 477 ReadRegisterFrame (void *baton, 478 uint32_t reg_kind, 479 uint32_t reg_num, 480 uint64_t ®_value); 481 482 483 static bool 484 WriteRegisterFrame (void *baton, 485 const Context &context, 486 uint32_t reg_kind, 487 uint32_t reg_num, 488 uint64_t reg_value); 489 490 static size_t 491 ReadMemoryDefault (void *baton, 492 const Context &context, 493 lldb::addr_t addr, 494 void *dst, 495 size_t length); 496 497 static size_t 498 WriteMemoryDefault (void *baton, 499 const Context &context, 500 lldb::addr_t addr, 501 const void *dst, 502 size_t length); 503 504 static bool 505 ReadRegisterDefault (void *baton, 506 uint32_t reg_kind, 507 uint32_t reg_num, 508 uint64_t ®_value); 509 510 511 static bool 512 WriteRegisterDefault (void *baton, 513 const Context &context, 514 uint32_t reg_kind, 515 uint32_t reg_num, 516 uint64_t reg_value); 517 518 void 519 SetBaton (void *baton); 520 521 void 522 SetCallbacks (ReadMemory read_mem_callback, 523 WriteMemory write_mem_callback, 524 ReadRegister read_reg_callback, 525 WriteRegister write_reg_callback); 526 527 void 528 SetReadMemCallback (ReadMemory read_mem_callback); 529 530 void 531 SetWriteMemCallback (WriteMemory write_mem_callback); 532 533 void 534 SetReadRegCallback (ReadRegister read_reg_callback); 535 536 void 537 SetWriteRegCallback (WriteRegister write_reg_callback); 538 539 540protected: 541 lldb::ByteOrder m_byte_order; 542 uint32_t m_addr_byte_size; 543 ArchSpec m_arch; 544 void * m_baton; 545 ReadMemory m_read_mem_callback; 546 WriteMemory m_write_mem_callback; 547 ReadRegister m_read_reg_callback; 548 WriteRegister m_write_reg_callback; 549 lldb::addr_t m_opcode_pc; 550 Opcode m_opcode; 551 //------------------------------------------------------------------ 552 // For EmulateInstruction only 553 //------------------------------------------------------------------ 554 DISALLOW_COPY_AND_ASSIGN (EmulateInstruction); 555}; 556 557} // namespace lldb_private 558 559#endif // lldb_EmulateInstruction_h_ 560