forked from OSchip/llvm-project
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;
|
|
}
|