mirror of
https://github.com/intel/llvm.git
synced 2026-01-19 09:31:59 +08:00
Modified the Disassembler::Instruction base class to contain an Opcode instance so that we can know the bytes for an instruction without needing to keep the data around. Modified the DisassemblerLLVM's instruction class to correctly extract the opcode bytes if all goes well. llvm-svn: 128248
126 lines
3.9 KiB
C++
126 lines
3.9 KiB
C++
//===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "lldb/Core/EmulateInstruction.h"
|
|
|
|
#include "lldb/Core/DataExtractor.h"
|
|
#include "lldb/Core/PluginManager.h"
|
|
#include "lldb/Core/StreamString.h"
|
|
#include "lldb/Host/Endian.h"
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
EmulateInstruction*
|
|
EmulateInstruction::FindPlugin (const ArchSpec &arch, const char *plugin_name)
|
|
{
|
|
EmulateInstructionCreateInstance create_callback = NULL;
|
|
if (plugin_name)
|
|
{
|
|
create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (plugin_name);
|
|
if (create_callback)
|
|
{
|
|
std::auto_ptr<EmulateInstruction> instance_ap(create_callback(arch));
|
|
if (instance_ap.get())
|
|
return instance_ap.release();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != NULL; ++idx)
|
|
{
|
|
std::auto_ptr<EmulateInstruction> instance_ap(create_callback(arch));
|
|
if (instance_ap.get())
|
|
return instance_ap.release();
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
EmulateInstruction::EmulateInstruction
|
|
(
|
|
lldb::ByteOrder byte_order,
|
|
uint32_t addr_byte_size,
|
|
void *baton,
|
|
ReadMemory read_mem_callback,
|
|
WriteMemory write_mem_callback,
|
|
ReadRegister read_reg_callback,
|
|
WriteRegister write_reg_callback
|
|
) :
|
|
m_byte_order (endian::InlHostByteOrder()),
|
|
m_addr_byte_size (sizeof (void *)),
|
|
m_baton (baton),
|
|
m_read_mem_callback (read_mem_callback),
|
|
m_write_mem_callback (write_mem_callback),
|
|
m_read_reg_callback (read_reg_callback),
|
|
m_write_reg_callback (write_reg_callback),
|
|
m_opcode (),
|
|
m_opcode_pc (LLDB_INVALID_ADDRESS)
|
|
{
|
|
}
|
|
|
|
uint64_t
|
|
EmulateInstruction::ReadRegisterUnsigned (uint32_t reg_kind, uint32_t reg_num, uint64_t fail_value, bool *success_ptr)
|
|
{
|
|
uint64_t uval64 = 0;
|
|
bool success = m_read_reg_callback (m_baton, reg_kind, reg_num, uval64);
|
|
if (success_ptr)
|
|
*success_ptr = success;
|
|
if (!success)
|
|
uval64 = fail_value;
|
|
return uval64;
|
|
}
|
|
|
|
bool
|
|
EmulateInstruction::WriteRegisterUnsigned (const Context &context, uint32_t reg_kind, uint32_t reg_num, uint64_t reg_value)
|
|
{
|
|
return m_write_reg_callback (m_baton, context, reg_kind, reg_num, reg_value);
|
|
}
|
|
|
|
uint64_t
|
|
EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
|
|
{
|
|
uint64_t uval64 = 0;
|
|
bool success = false;
|
|
if (byte_size <= 8)
|
|
{
|
|
uint8_t buf[sizeof(uint64_t)];
|
|
size_t bytes_read = m_read_mem_callback (m_baton, context, addr, buf, byte_size);
|
|
if (bytes_read == byte_size)
|
|
{
|
|
uint32_t offset = 0;
|
|
DataExtractor data (buf, byte_size, m_byte_order, m_addr_byte_size);
|
|
uval64 = data.GetMaxU64 (&offset, byte_size);
|
|
success = true;
|
|
}
|
|
}
|
|
|
|
if (success_ptr)
|
|
*success_ptr = success;
|
|
|
|
if (!success)
|
|
uval64 = fail_value;
|
|
return uval64;
|
|
}
|
|
|
|
|
|
bool
|
|
EmulateInstruction::WriteMemoryUnsigned (const Context &context,
|
|
lldb::addr_t addr,
|
|
uint64_t uval,
|
|
size_t uval_byte_size)
|
|
{
|
|
StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
|
|
strm.PutMaxHex64 (uval, uval_byte_size);
|
|
|
|
size_t bytes_written = m_write_mem_callback (m_baton, context, addr, strm.GetData(), uval_byte_size);
|
|
if (bytes_written == uval_byte_size)
|
|
return true;
|
|
return false;
|
|
}
|