EmulateInstruction.cpp revision 296417
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#include "lldb/Core/EmulateInstruction.h" 11 12#include "lldb/Core/Address.h" 13#include "lldb/Core/DataExtractor.h" 14#include "lldb/Core/Error.h" 15#include "lldb/Core/PluginManager.h" 16#include "lldb/Core/RegisterValue.h" 17#include "lldb/Core/StreamFile.h" 18#include "lldb/Core/StreamString.h" 19#include "lldb/Host/Endian.h" 20#include "lldb/Symbol/UnwindPlan.h" 21#include "lldb/Target/Process.h" 22#include "lldb/Target/RegisterContext.h" 23#include "lldb/Target/Target.h" 24#include "lldb/Target/Thread.h" 25 26using namespace lldb; 27using namespace lldb_private; 28 29EmulateInstruction* 30EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name) 31{ 32 EmulateInstructionCreateInstance create_callback = NULL; 33 if (plugin_name) 34 { 35 ConstString const_plugin_name (plugin_name); 36 create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const_plugin_name); 37 if (create_callback) 38 { 39 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type); 40 if (emulate_insn_ptr) 41 return emulate_insn_ptr; 42 } 43 } 44 else 45 { 46 for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx) 47 { 48 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type); 49 if (emulate_insn_ptr) 50 return emulate_insn_ptr; 51 } 52 } 53 return NULL; 54} 55 56EmulateInstruction::EmulateInstruction (const ArchSpec &arch) : 57 m_arch (arch), 58 m_baton (NULL), 59 m_read_mem_callback (&ReadMemoryDefault), 60 m_write_mem_callback (&WriteMemoryDefault), 61 m_read_reg_callback (&ReadRegisterDefault), 62 m_write_reg_callback (&WriteRegisterDefault), 63 m_addr (LLDB_INVALID_ADDRESS) 64{ 65 ::memset (&m_opcode, 0, sizeof (m_opcode)); 66} 67 68 69bool 70EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value) 71{ 72 if (m_read_reg_callback) 73 return m_read_reg_callback (this, m_baton, reg_info, reg_value); 74 return false; 75} 76 77bool 78EmulateInstruction::ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value) 79{ 80 RegisterInfo reg_info; 81 if (GetRegisterInfo(reg_kind, reg_num, reg_info)) 82 return ReadRegister (®_info, reg_value); 83 return false; 84} 85 86uint64_t 87EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind, 88 uint32_t reg_num, 89 uint64_t fail_value, 90 bool *success_ptr) 91{ 92 RegisterValue reg_value; 93 if (ReadRegister (reg_kind, reg_num, reg_value)) 94 return reg_value.GetAsUInt64(fail_value, success_ptr); 95 if (success_ptr) 96 *success_ptr = false; 97 return fail_value; 98} 99 100uint64_t 101EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info, 102 uint64_t fail_value, 103 bool *success_ptr) 104{ 105 RegisterValue reg_value; 106 if (ReadRegister (reg_info, reg_value)) 107 return reg_value.GetAsUInt64(fail_value, success_ptr); 108 if (success_ptr) 109 *success_ptr = false; 110 return fail_value; 111} 112 113bool 114EmulateInstruction::WriteRegister (const Context &context, 115 const RegisterInfo *reg_info, 116 const RegisterValue& reg_value) 117{ 118 if (m_write_reg_callback) 119 return m_write_reg_callback (this, m_baton, context, reg_info, reg_value); 120 return false; 121} 122 123bool 124EmulateInstruction::WriteRegister (const Context &context, 125 lldb::RegisterKind reg_kind, 126 uint32_t reg_num, 127 const RegisterValue& reg_value) 128{ 129 RegisterInfo reg_info; 130 if (GetRegisterInfo(reg_kind, reg_num, reg_info)) 131 return WriteRegister (context, ®_info, reg_value); 132 return false; 133} 134 135 136bool 137EmulateInstruction::WriteRegisterUnsigned (const Context &context, 138 lldb::RegisterKind reg_kind, 139 uint32_t reg_num, 140 uint64_t uint_value) 141{ 142 143 RegisterInfo reg_info; 144 if (GetRegisterInfo(reg_kind, reg_num, reg_info)) 145 { 146 RegisterValue reg_value; 147 if (reg_value.SetUInt(uint_value, reg_info.byte_size)) 148 return WriteRegister (context, ®_info, reg_value); 149 } 150 return false; 151} 152 153bool 154EmulateInstruction::WriteRegisterUnsigned (const Context &context, 155 const RegisterInfo *reg_info, 156 uint64_t uint_value) 157{ 158 159 if (reg_info) 160 { 161 RegisterValue reg_value; 162 if (reg_value.SetUInt(uint_value, reg_info->byte_size)) 163 return WriteRegister (context, reg_info, reg_value); 164 } 165 return false; 166} 167 168size_t 169EmulateInstruction::ReadMemory (const Context &context, 170 lldb::addr_t addr, 171 void *dst, 172 size_t dst_len) 173{ 174 if (m_read_mem_callback) 175 return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len; 176 return false; 177} 178 179uint64_t 180EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr) 181{ 182 uint64_t uval64 = 0; 183 bool success = false; 184 if (byte_size <= 8) 185 { 186 uint8_t buf[sizeof(uint64_t)]; 187 size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size); 188 if (bytes_read == byte_size) 189 { 190 lldb::offset_t offset = 0; 191 DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize()); 192 uval64 = data.GetMaxU64 (&offset, byte_size); 193 success = true; 194 } 195 } 196 197 if (success_ptr) 198 *success_ptr = success; 199 200 if (!success) 201 uval64 = fail_value; 202 return uval64; 203} 204 205 206bool 207EmulateInstruction::WriteMemoryUnsigned (const Context &context, 208 lldb::addr_t addr, 209 uint64_t uval, 210 size_t uval_byte_size) 211{ 212 StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder()); 213 strm.PutMaxHex64 (uval, uval_byte_size); 214 215 size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size); 216 if (bytes_written == uval_byte_size) 217 return true; 218 return false; 219} 220 221bool 222EmulateInstruction::WriteMemory (const Context &context, 223 lldb::addr_t addr, 224 const void *src, 225 size_t src_len) 226{ 227 if (m_write_mem_callback) 228 return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len; 229 return false; 230} 231 232 233void 234EmulateInstruction::SetBaton (void *baton) 235{ 236 m_baton = baton; 237} 238 239void 240EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback, 241 WriteMemoryCallback write_mem_callback, 242 ReadRegisterCallback read_reg_callback, 243 WriteRegisterCallback write_reg_callback) 244{ 245 m_read_mem_callback = read_mem_callback; 246 m_write_mem_callback = write_mem_callback; 247 m_read_reg_callback = read_reg_callback; 248 m_write_reg_callback = write_reg_callback; 249} 250 251void 252EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback) 253{ 254 m_read_mem_callback = read_mem_callback; 255} 256 257 258void 259EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback) 260{ 261 m_write_mem_callback = write_mem_callback; 262} 263 264 265void 266EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback) 267{ 268 m_read_reg_callback = read_reg_callback; 269} 270 271 272void 273EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback) 274{ 275 m_write_reg_callback = write_reg_callback; 276} 277 278 279 280// 281// Read & Write Memory and Registers callback functions. 282// 283 284size_t 285EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction, 286 void *baton, 287 const Context &context, 288 lldb::addr_t addr, 289 void *dst, 290 size_t dst_len) 291{ 292 if (!baton || dst == NULL || dst_len == 0) 293 return 0; 294 295 StackFrame *frame = (StackFrame *) baton; 296 297 ProcessSP process_sp (frame->CalculateProcess()); 298 if (process_sp) 299 { 300 Error error; 301 return process_sp->ReadMemory (addr, dst, dst_len, error); 302 } 303 return 0; 304} 305 306size_t 307EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction, 308 void *baton, 309 const Context &context, 310 lldb::addr_t addr, 311 const void *src, 312 size_t src_len) 313{ 314 if (!baton || src == NULL || src_len == 0) 315 return 0; 316 317 StackFrame *frame = (StackFrame *) baton; 318 319 ProcessSP process_sp (frame->CalculateProcess()); 320 if (process_sp) 321 { 322 Error error; 323 return process_sp->WriteMemory (addr, src, src_len, error); 324 } 325 326 return 0; 327} 328 329bool 330EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction, 331 void *baton, 332 const RegisterInfo *reg_info, 333 RegisterValue ®_value) 334{ 335 if (!baton) 336 return false; 337 338 StackFrame *frame = (StackFrame *) baton; 339 return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value); 340} 341 342bool 343EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction, 344 void *baton, 345 const Context &context, 346 const RegisterInfo *reg_info, 347 const RegisterValue ®_value) 348{ 349 if (!baton) 350 return false; 351 352 StackFrame *frame = (StackFrame *) baton; 353 return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value); 354} 355 356size_t 357EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction, 358 void *baton, 359 const Context &context, 360 lldb::addr_t addr, 361 void *dst, 362 size_t length) 363{ 364 StreamFile strm (stdout, false); 365 strm.Printf (" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length); 366 context.Dump (strm, instruction); 367 strm.EOL(); 368 *((uint64_t *) dst) = 0xdeadbeef; 369 return length; 370} 371 372size_t 373EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction, 374 void *baton, 375 const Context &context, 376 lldb::addr_t addr, 377 const void *dst, 378 size_t length) 379{ 380 StreamFile strm (stdout, false); 381 strm.Printf (" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length); 382 context.Dump (strm, instruction); 383 strm.EOL(); 384 return length; 385} 386 387bool 388EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction, 389 void *baton, 390 const RegisterInfo *reg_info, 391 RegisterValue ®_value) 392{ 393 StreamFile strm (stdout, false); 394 strm.Printf (" Read Register (%s)\n", reg_info->name); 395 lldb::RegisterKind reg_kind; 396 uint32_t reg_num; 397 if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num)) 398 reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num); 399 else 400 reg_value.SetUInt64(0); 401 402 return true; 403} 404 405bool 406EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction, 407 void *baton, 408 const Context &context, 409 const RegisterInfo *reg_info, 410 const RegisterValue ®_value) 411{ 412 StreamFile strm (stdout, false); 413 strm.Printf (" Write to Register (name = %s, value = " , reg_info->name); 414 reg_value.Dump(&strm, reg_info, false, false, eFormatDefault); 415 strm.PutCString (", context = "); 416 context.Dump (strm, instruction); 417 strm.EOL(); 418 return true; 419} 420 421void 422EmulateInstruction::Context::Dump (Stream &strm, 423 EmulateInstruction *instruction) const 424{ 425 switch (type) 426 { 427 case eContextReadOpcode: 428 strm.PutCString ("reading opcode"); 429 break; 430 431 case eContextImmediate: 432 strm.PutCString ("immediate"); 433 break; 434 435 case eContextPushRegisterOnStack: 436 strm.PutCString ("push register"); 437 break; 438 439 case eContextPopRegisterOffStack: 440 strm.PutCString ("pop register"); 441 break; 442 443 case eContextAdjustStackPointer: 444 strm.PutCString ("adjust sp"); 445 break; 446 447 case eContextSetFramePointer: 448 strm.PutCString ("set frame pointer"); 449 break; 450 451 case eContextAdjustBaseRegister: 452 strm.PutCString ("adjusting (writing value back to) a base register"); 453 break; 454 455 case eContextRegisterPlusOffset: 456 strm.PutCString ("register + offset"); 457 break; 458 459 case eContextRegisterStore: 460 strm.PutCString ("store register"); 461 break; 462 463 case eContextRegisterLoad: 464 strm.PutCString ("load register"); 465 break; 466 467 case eContextRelativeBranchImmediate: 468 strm.PutCString ("relative branch immediate"); 469 break; 470 471 case eContextAbsoluteBranchRegister: 472 strm.PutCString ("absolute branch register"); 473 break; 474 475 case eContextSupervisorCall: 476 strm.PutCString ("supervisor call"); 477 break; 478 479 case eContextTableBranchReadMemory: 480 strm.PutCString ("table branch read memory"); 481 break; 482 483 case eContextWriteRegisterRandomBits: 484 strm.PutCString ("write random bits to a register"); 485 break; 486 487 case eContextWriteMemoryRandomBits: 488 strm.PutCString ("write random bits to a memory address"); 489 break; 490 491 case eContextArithmetic: 492 strm.PutCString ("arithmetic"); 493 break; 494 495 case eContextReturnFromException: 496 strm.PutCString ("return from exception"); 497 break; 498 499 default: 500 strm.PutCString ("unrecognized context."); 501 break; 502 } 503 504 switch (info_type) 505 { 506 case eInfoTypeRegisterPlusOffset: 507 { 508 strm.Printf (" (reg_plus_offset = %s%+" PRId64 ")", 509 info.RegisterPlusOffset.reg.name, 510 info.RegisterPlusOffset.signed_offset); 511 } 512 break; 513 514 case eInfoTypeRegisterPlusIndirectOffset: 515 { 516 strm.Printf (" (reg_plus_reg = %s + %s)", 517 info.RegisterPlusIndirectOffset.base_reg.name, 518 info.RegisterPlusIndirectOffset.offset_reg.name); 519 } 520 break; 521 522 case eInfoTypeRegisterToRegisterPlusOffset: 523 { 524 strm.Printf (" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)", 525 info.RegisterToRegisterPlusOffset.base_reg.name, 526 info.RegisterToRegisterPlusOffset.offset, 527 info.RegisterToRegisterPlusOffset.data_reg.name); 528 } 529 break; 530 531 case eInfoTypeRegisterToRegisterPlusIndirectOffset: 532 { 533 strm.Printf (" (base_and_reg_offset = %s + %s, data_reg = %s)", 534 info.RegisterToRegisterPlusIndirectOffset.base_reg.name, 535 info.RegisterToRegisterPlusIndirectOffset.offset_reg.name, 536 info.RegisterToRegisterPlusIndirectOffset.data_reg.name); 537 } 538 break; 539 540 case eInfoTypeRegisterRegisterOperands: 541 { 542 strm.Printf (" (register to register binary op: %s and %s)", 543 info.RegisterRegisterOperands.operand1.name, 544 info.RegisterRegisterOperands.operand2.name); 545 } 546 break; 547 548 case eInfoTypeOffset: 549 strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset); 550 break; 551 552 case eInfoTypeRegister: 553 strm.Printf (" (reg = %s)", info.reg.name); 554 break; 555 556 case eInfoTypeImmediate: 557 strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))", 558 info.unsigned_immediate, 559 info.unsigned_immediate); 560 break; 561 562 case eInfoTypeImmediateSigned: 563 strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))", 564 info.signed_immediate, 565 info.signed_immediate); 566 break; 567 568 case eInfoTypeAddress: 569 strm.Printf (" (address = 0x%" PRIx64 ")", info.address); 570 break; 571 572 case eInfoTypeISAAndImmediate: 573 strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))", 574 info.ISAAndImmediate.isa, 575 info.ISAAndImmediate.unsigned_data32, 576 info.ISAAndImmediate.unsigned_data32); 577 break; 578 579 case eInfoTypeISAAndImmediateSigned: 580 strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))", 581 info.ISAAndImmediateSigned.isa, 582 info.ISAAndImmediateSigned.signed_data32, 583 info.ISAAndImmediateSigned.signed_data32); 584 break; 585 586 case eInfoTypeISA: 587 strm.Printf (" (isa = %u)", info.isa); 588 break; 589 590 case eInfoTypeNoArgs: 591 break; 592 } 593} 594 595bool 596EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target) 597{ 598 m_opcode = opcode; 599 m_addr = LLDB_INVALID_ADDRESS; 600 if (inst_addr.IsValid()) 601 { 602 if (target) 603 m_addr = inst_addr.GetLoadAddress (target); 604 if (m_addr == LLDB_INVALID_ADDRESS) 605 m_addr = inst_addr.GetFileAddress (); 606 } 607 return true; 608} 609 610bool 611EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info, 612 lldb::RegisterKind ®_kind, 613 uint32_t ®_num) 614{ 615 // Generic and DWARF should be the two most popular register kinds when 616 // emulating instructions since they are the most platform agnostic... 617 reg_num = reg_info->kinds[eRegisterKindGeneric]; 618 if (reg_num != LLDB_INVALID_REGNUM) 619 { 620 reg_kind = eRegisterKindGeneric; 621 return true; 622 } 623 624 reg_num = reg_info->kinds[eRegisterKindDWARF]; 625 if (reg_num != LLDB_INVALID_REGNUM) 626 { 627 reg_kind = eRegisterKindDWARF; 628 return true; 629 } 630 631 reg_num = reg_info->kinds[eRegisterKindLLDB]; 632 if (reg_num != LLDB_INVALID_REGNUM) 633 { 634 reg_kind = eRegisterKindLLDB; 635 return true; 636 } 637 638 reg_num = reg_info->kinds[eRegisterKindEHFrame]; 639 if (reg_num != LLDB_INVALID_REGNUM) 640 { 641 reg_kind = eRegisterKindEHFrame; 642 return true; 643 } 644 645 reg_num = reg_info->kinds[eRegisterKindProcessPlugin]; 646 if (reg_num != LLDB_INVALID_REGNUM) 647 { 648 reg_kind = eRegisterKindProcessPlugin; 649 return true; 650 } 651 return false; 652} 653 654uint32_t 655EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo ®_info) 656{ 657 lldb::RegisterKind reg_kind; 658 uint32_t reg_num; 659 if (reg_ctx && GetBestRegisterKindAndNumber (®_info, reg_kind, reg_num)) 660 return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num); 661 return LLDB_INVALID_REGNUM; 662} 663 664 665bool 666EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) 667{ 668 unwind_plan.Clear(); 669 return false; 670} 671 672 673