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