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