28#include "llvm/ADT/StringRef.h"
29#include "llvm/Support/ErrorExtras.h"
48 const char *plugin_name) {
54 if (create_callback) {
56 create_callback(arch, supported_inst_type);
58 return emulate_insn_ptr;
61 for (
auto create_callback :
64 create_callback(arch, supported_inst_type);
66 return emulate_insn_ptr;
74std::optional<RegisterValue>
89 std::optional<RegisterInfo> reg_info =
GetRegisterInfo(reg_kind, reg_num);
93 std::optional<RegisterValue> value =
ReadRegister(*reg_info);
96 return value.has_value();
105 return reg_value.
GetAsUInt64(fail_value, success_ptr);
107 *success_ptr =
false;
114 std::optional<RegisterValue> reg_value =
ReadRegister(reg_info);
117 *success_ptr =
false;
121 return reg_value->GetAsUInt64(fail_value, success_ptr);
136 std::optional<RegisterInfo> reg_info =
GetRegisterInfo(reg_kind, reg_num);
145 uint64_t uint_value) {
146 std::optional<RegisterInfo> reg_info =
GetRegisterInfo(reg_kind, reg_num);
149 if (reg_value.
SetUInt(uint_value, reg_info->byte_size))
157 uint64_t uint_value) {
165 void *dst,
size_t dst_len) {
178 bool success =
false;
179 if (byte_size <= 8) {
180 uint8_t buf[
sizeof(uint64_t)];
183 if (bytes_read == byte_size) {
186 uval64 = data.
GetMaxU64(&offset, byte_size);
192 *success_ptr = success;
201 size_t uval_byte_size) {
207 return (bytes_written == uval_byte_size);
211 const void *src,
size_t src_len) {
256 void *baton,
const Context &context,
259 if (baton ==
nullptr || dst ==
nullptr || dst_len == 0)
267 return process_sp->ReadMemory(addr, dst, dst_len,
error);
273 void *baton,
const Context &context,
276 if (baton ==
nullptr || src ==
nullptr || src_len == 0)
284 return process_sp->WriteMemory(addr, src, src_len,
error);
294 if (baton ==
nullptr)
302 void *baton,
const Context &context,
305 if (baton ==
nullptr)
318 strm.
Printf(
" Read from Memory (address = 0x%" PRIx64
", length = %" PRIu64
320 addr, (uint64_t)length);
321 context.
Dump(strm, instruction);
323 *((uint64_t *)dst) = 0xdeadbeef;
331 const void *dst,
size_t length) {
333 strm.
Printf(
" Write to Memory (address = 0x%" PRIx64
", length = %" PRIu64
335 addr, (uint64_t)length);
336 context.
Dump(strm, instruction);
346 strm.
Printf(
" Read Register (%s)\n", reg_info->
name);
350 reg_value.
SetUInt64((uint64_t)reg_kind << 24 | reg_num);
363 strm.
Printf(
" Write to Register (name = %s, value = ", reg_info->
name);
366 context.
Dump(strm, instruction);
399 strm.
PutCString(
"adjusting (writing value back to) a base register");
431 strm.
PutCString(
"write random bits to a register");
435 strm.
PutCString(
"write random bits to a memory address");
453 strm.
Printf(
" (reg_plus_offset = %s%+" PRId64
")",
454 info.RegisterPlusOffset.reg.name,
455 info.RegisterPlusOffset.signed_offset);
459 strm.
Printf(
" (reg_plus_reg = %s + %s)",
460 info.RegisterPlusIndirectOffset.base_reg.name,
461 info.RegisterPlusIndirectOffset.offset_reg.name);
465 strm.
Printf(
" (base_and_imm_offset = %s%+" PRId64
", data_reg = %s)",
466 info.RegisterToRegisterPlusOffset.base_reg.name,
467 info.RegisterToRegisterPlusOffset.offset,
468 info.RegisterToRegisterPlusOffset.data_reg.name);
472 strm.
Printf(
" (base_and_reg_offset = %s + %s, data_reg = %s)",
473 info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
474 info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
475 info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
479 strm.
Printf(
" (register to register binary op: %s and %s)",
480 info.RegisterRegisterOperands.operand1.name,
481 info.RegisterRegisterOperands.operand2.name);
485 strm.
Printf(
" (signed_offset = %+" PRId64
")",
info.signed_offset);
493 strm.
Printf(
" (unsigned_immediate = %" PRIu64
" (0x%16.16" PRIx64
"))",
494 info.unsigned_immediate,
info.unsigned_immediate);
498 strm.
Printf(
" (signed_immediate = %+" PRId64
" (0x%16.16" PRIx64
"))",
499 info.signed_immediate,
info.signed_immediate);
503 strm.
Printf(
" (address = 0x%" PRIx64
")",
info.address);
507 strm.
Printf(
" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
508 info.ISAAndImmediate.isa,
info.ISAAndImmediate.unsigned_data32,
509 info.ISAAndImmediate.unsigned_data32);
513 strm.
Printf(
" (isa = %u, signed_immediate = %i (0x%8.8x))",
514 info.ISAAndImmediateSigned.isa,
515 info.ISAAndImmediateSigned.signed_data32,
516 info.ISAAndImmediateSigned.signed_data32);
534 if (target !=
nullptr)
589std::unique_ptr<SingleStepBreakpointLocationsPredictor>
591 std::unique_ptr<EmulateInstruction> emulator_up) {
593 emulator_up->GetSingleStepBreakpointLocationsPredictorCreator();
594 return creator(std::move(emulator_up));
598 bool success =
false;
601 return success ? std::optional<addr_t>(addr) : std::nullopt;
617llvm::Expected<BreakpointLocations>
624 return next_pc.takeError();
629 return llvm::createStringError(
"Can't read PC");
632 eEmulateInstructionOptionAutoAdvancePC);
637 return next_pc.takeError();
640llvm::Expected<addr_t>
642 std::optional<uint32_t> instr_size =
m_emulator_up->GetLastInstrSize();
644 return llvm::createStringError(
"Read instruction failed!");
648 return llvm::createStringError(
"Can't read PC");
654llvm::Expected<addr_t>
659 return llvm::createStringError(
"Can't read PC");
663 assert(entry_pc !=
pc &&
"Emulation was successfull but PC wasn't updated");
667 if (entry_pc ==
pc) {
678 return llvm::createStringError(
"Instruction emulation failed unexpectedly.");
static llvm::raw_ostream & error(Stream &strm)
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
lldb::addr_t GetFileAddress() const
Get the file address.
bool IsValid() const
Check if the object state is valid.
An architecture specification class.
"lldb/Core/EmulateInstruction.h" A class that allows emulation of CPU opcodes.
static bool GetBestRegisterKindAndNumber(const RegisterInfo *reg_info, lldb::RegisterKind ®_kind, uint32_t ®_num)
static bool WriteRegisterDefault(EmulateInstruction *instruction, void *baton, const Context &context, const RegisterInfo *reg_info, const RegisterValue ®_value)
static size_t WriteMemoryFrame(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length)
@ eContextRelativeBranchImmediate
@ eContextSetFramePointer
@ eContextAdjustBaseRegister
@ eContextWriteMemoryRandomBits
@ eContextTableBranchReadMemory
@ eContextWriteRegisterRandomBits
@ eContextAdjustStackPointer
@ eContextReturnFromException
@ eContextPushRegisterOnStack
@ eContextPopRegisterOffStack
@ eContextAbsoluteBranchRegister
@ eContextRegisterPlusOffset
@ eInfoTypeRegisterPlusOffset
@ eInfoTypeRegisterRegisterOperands
@ eInfoTypeImmediateSigned
@ eInfoTypeISAAndImmediate
@ eInfoTypeRegisterToRegisterPlusOffset
@ eInfoTypeRegisterToRegisterPlusIndirectOffset
@ eInfoTypeRegisterPlusIndirectOffset
@ eInfoTypeISAAndImmediateSigned
WriteMemoryCallback m_write_mem_callback
lldb::ByteOrder GetByteOrder() const
void SetWriteRegCallback(WriteRegisterCallback write_reg_callback)
bool(* WriteRegisterCallback)(EmulateInstruction *instruction, void *baton, const Context &context, const RegisterInfo *reg_info, const RegisterValue ®_value)
void SetCallbacks(ReadMemoryCallback read_mem_callback, WriteMemoryCallback write_mem_callback, ReadRegisterCallback read_reg_callback, WriteRegisterCallback write_reg_callback)
static bool ReadRegisterDefault(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue ®_value)
std::optional< lldb::addr_t > ReadPC()
virtual bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan)
bool ReadMemory(const Context &context, lldb::addr_t addr, void *dst, size_t dst_len)
bool WriteMemoryUnsigned(const Context &context, lldb::addr_t addr, uint64_t uval, size_t uval_byte_size)
static uint32_t GetInternalRegisterNumber(RegisterContext *reg_ctx, const RegisterInfo ®_info)
void SetReadRegCallback(ReadRegisterCallback read_reg_callback)
std::optional< RegisterValue > ReadRegister(const RegisterInfo ®_info)
ReadRegisterCallback m_read_reg_callback
size_t(* WriteMemoryCallback)(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length)
static size_t ReadMemoryFrame(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length)
bool WriteRegister(const Context &context, const RegisterInfo &ref_info, const RegisterValue ®_value)
bool WriteRegisterUnsigned(const Context &context, const RegisterInfo ®_info, uint64_t reg_value)
bool WriteMemory(const Context &context, lldb::addr_t addr, const void *src, size_t src_len)
bool WritePC(lldb::addr_t addr)
uint64_t ReadMemoryUnsigned(const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
WriteRegisterCallback m_write_reg_callback
static std::unique_ptr< SingleStepBreakpointLocationsPredictor > CreateBreakpointLocationPredictor(std::unique_ptr< EmulateInstruction > emulator_up)
EmulateInstruction(const ArchSpec &arch)
static size_t WriteMemoryDefault(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, const void *dst, size_t length)
size_t(* ReadMemoryCallback)(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length)
void SetReadMemCallback(ReadMemoryCallback read_mem_callback)
static bool WriteRegisterFrame(EmulateInstruction *instruction, void *baton, const Context &context, const RegisterInfo *reg_info, const RegisterValue ®_value)
uint32_t GetAddressByteSize() const
ReadMemoryCallback m_read_mem_callback
static bool ReadRegisterFrame(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue ®_value)
bool(* ReadRegisterCallback)(EmulateInstruction *instruction, void *baton, const RegisterInfo *reg_info, RegisterValue ®_value)
virtual std::optional< RegisterInfo > GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num)=0
void SetBaton(void *baton)
static size_t ReadMemoryDefault(EmulateInstruction *instruction, void *baton, const Context &context, lldb::addr_t addr, void *dst, size_t length)
virtual bool SetInstruction(const Opcode &insn_opcode, const Address &inst_addr, Target *target)
static EmulateInstruction * FindPlugin(const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
uint64_t ReadRegisterUnsigned(const RegisterInfo ®_info, uint64_t fail_value, bool *success_ptr)
void SetWriteMemCallback(WriteMemoryCallback write_mem_callback)
static EmulateInstructionCreateInstance GetEmulateInstructionCreateCallbackForPluginName(llvm::StringRef name)
static llvm::SmallVector< EmulateInstructionCreateInstance > GetEmulateInstructionCreateCallbacks()
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
bool SetUInt(uint64_t uint, uint32_t byte_size)
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
llvm::Expected< lldb::addr_t > GetBreakpointLocationAddress(lldb::addr_t entry_pc)
std::unique_ptr< EmulateInstruction > m_emulator_up
llvm::Expected< lldb::addr_t > GetNextInstructionAddress()
virtual llvm::Expected< BreakpointLocations > GetBreakpointLocations()
This base class provides an interface to stack frames.
virtual lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
lldb::ProcessSP CalculateProcess() override
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
@ eBinary
Get and put data as binary instead of as the default string mode.
size_t EOL()
Output and End of Line character to the stream.
size_t PutMaxHex64(uint64_t uvalue, size_t byte_size, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
#define LLDB_REGNUM_GENERIC_PC
A class that represents a running process on the host machine.
EmulateInstruction *(* EmulateInstructionCreateInstance)(const ArchSpec &arch, InstructionType inst_type)
InstructionType
Instruction types.
std::vector< lldb::addr_t > BreakpointLocations
void DumpRegisterValue(const RegisterValue ®_val, Stream &s, const RegisterInfo ®_info, bool prefix_with_name, bool prefix_with_alt_name, lldb::Format format, uint32_t reg_name_right_align_at=0, ExecutionContextScope *exe_scope=nullptr, bool print_flags=false, lldb::TargetSP target_sp=nullptr)
std::shared_ptr< lldb_private::Process > ProcessSP
RegisterKind
Register numbering types.
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
@ eRegisterKindLLDB
lldb's internal register numbers
@ eRegisterKindDWARF
the register numbers seen DWARF
@ eRegisterKindEHFrame
the register numbers seen in eh_frame
@ eRegisterKindProcessPlugin
num used by the process plugin - e.g.
void Dump(Stream &s, EmulateInstruction *instruction) const
union lldb_private::EmulateInstruction::Context::ContextInfo info
enum InfoType GetInfoType() const
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.