Add Emulate and DumpEmulation to Instruction class.

Move InstructionLLVM out of DisassemblerLLVM class.

Add instruction emulation function calls to SBInstruction and SBInstructionList APIs.

llvm-svn: 128956
This commit is contained in:
Caroline Tice 2011-04-05 23:22:54 +00:00
parent ce6b047a10
commit 7c9dd3ce3c
10 changed files with 159 additions and 42 deletions

View File

@ -137,6 +137,7 @@ protected:
private:
friend class SBThread;
friend class SBInstruction;
friend class lldb_private::ScriptInterpreterPython;
#ifndef SWIG

View File

@ -52,6 +52,12 @@ public:
bool
GetDescription (lldb::SBStream &description);
bool
EmulateWithFrame (lldb::SBFrame &frame);
bool
DumpEmulation (const char * triple); // triple is to specify the architecture, e.g. 'armv6' or 'arm-apple-darwin'
protected:
friend class SBInstructionList;

View File

@ -48,6 +48,9 @@ public:
bool
GetDescription (lldb::SBStream &description);
bool
DumpEmulationForAllInstructions (const char *triple);
protected:
friend class SBFunction;

View File

@ -19,6 +19,7 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/Opcode.h"
#include "lldb/Core/PluginInterface.h"
@ -66,7 +67,18 @@ public:
Decode (const Disassembler &disassembler,
const DataExtractor& data,
uint32_t data_offset) = 0;
bool
DumpEmulation (const ArchSpec &arch);
bool
Emulate (const ArchSpec &arch,
void *baton,
EmulateInstruction::ReadMemory read_mem_callback,
EmulateInstruction::WriteMemory write_mem_calback,
EmulateInstruction::ReadRegister read_reg_callback,
EmulateInstruction::WriteRegister write_reg_callback);
const Opcode &
GetOpcode () const
{

View File

@ -10,11 +10,18 @@
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBInstruction.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBTarget.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/EmulateInstruction.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
@ -107,3 +114,41 @@ SBInstruction::Print (FILE *out)
m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, false);
}
}
bool
SBInstruction::EmulateWithFrame (lldb::SBFrame &frame)
{
if (m_opaque_sp && frame.get())
{
lldb_private::ExecutionContext exe_ctx;
frame->CalculateExecutionContext (exe_ctx);
lldb_private::Target *target = exe_ctx.target;
lldb_private::ArchSpec arch = target->GetArchitecture();
return m_opaque_sp->Emulate (arch,
(void *) frame.get(),
&lldb_private::EmulateInstruction::ReadMemoryFrame,
&lldb_private::EmulateInstruction::WriteMemoryFrame,
&lldb_private::EmulateInstruction::ReadRegisterFrame,
&lldb_private::EmulateInstruction::WriteRegisterFrame);
}
return false;
}
bool
SBInstruction::DumpEmulation (const char *triple)
{
if (m_opaque_sp && triple)
{
lldb_private::ArchSpec arch (triple);
return m_opaque_sp->Emulate (arch,
NULL,
&lldb_private::EmulateInstruction::ReadMemoryDefault,
&lldb_private::EmulateInstruction::WriteMemoryDefault,
&lldb_private::EmulateInstruction::ReadRegisterDefault,
&lldb_private::EmulateInstruction::WriteRegisterDefault);
}
return false;
}

View File

@ -109,3 +109,18 @@ SBInstructionList::GetDescription (lldb::SBStream &description)
}
bool
SBInstructionList::DumpEmulationForAllInstructions (const char *triple)
{
if (m_opaque_sp)
{
size_t len = GetSize();
for (size_t i = 0; i < len; ++i)
{
if (!GetInstructionAtIndex((uint32_t) i).DumpEmulation (triple))
return false;
}
}
return true;
}

View File

@ -489,6 +489,39 @@ Instruction::GetAddressClass ()
return m_address_class;
}
bool
Instruction::DumpEmulation (const ArchSpec &arch)
{
std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
if (insn_emulator_ap.get())
{
insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress());
return insn_emulator_ap->EvaluateInstruction ();
}
return false;
}
bool
Instruction::Emulate (const ArchSpec &arch,
void *baton,
EmulateInstruction::ReadMemory read_mem_callback,
EmulateInstruction::WriteMemory write_mem_callback,
EmulateInstruction::ReadRegister read_reg_callback,
EmulateInstruction::WriteRegister write_reg_callback)
{
std::auto_ptr<EmulateInstruction> insn_emulator_ap (EmulateInstruction::FindPlugin (arch, NULL));
if (insn_emulator_ap.get())
{
insn_emulator_ap->SetBaton (baton);
insn_emulator_ap->SetCallbacks (read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
insn_emulator_ap->SetInstruction (GetOpcode(), GetAddress());
return insn_emulator_ap->EvaluateInstruction ();
}
return false;
}
InstructionList::InstructionList() :
m_instructions()
{

View File

@ -74,15 +74,15 @@ static int IPRegisterReader(uint64_t *value, unsigned regID, void* arg)
return -1;
}
DisassemblerLLVM::InstructionLLVM::InstructionLLVM (const Address &addr,
AddressClass addr_class,
EDDisassemblerRef disassembler) :
InstructionLLVM::InstructionLLVM (const Address &addr,
AddressClass addr_class,
EDDisassemblerRef disassembler) :
Instruction (addr, addr_class),
m_disassembler (disassembler)
{
}
DisassemblerLLVM::InstructionLLVM::~InstructionLLVM()
InstructionLLVM::~InstructionLLVM()
{
}
@ -98,7 +98,7 @@ PadString(Stream *s, const std::string &str, size_t width)
}
void
DisassemblerLLVM::InstructionLLVM::Dump
InstructionLLVM::Dump
(
Stream *s,
uint32_t max_opcode_byte_size,
@ -332,15 +332,15 @@ DisassemblerLLVM::InstructionLLVM::Dump
}
bool
DisassemblerLLVM::InstructionLLVM::DoesBranch() const
InstructionLLVM::DoesBranch() const
{
return EDInstIsBranch(m_inst);
}
size_t
DisassemblerLLVM::InstructionLLVM::Decode (const Disassembler &disassembler,
const lldb_private::DataExtractor &data,
uint32_t data_offset)
InstructionLLVM::Decode (const Disassembler &disassembler,
const lldb_private::DataExtractor &data,
uint32_t data_offset)
{
if (EDCreateInsts(&m_inst, 1, m_disassembler, DataExtractorByteReader, data_offset, (void*)(&data)))
{

View File

@ -16,40 +16,41 @@
#include "lldb/Core/Disassembler.h"
#include "lldb/Host/Mutex.h"
class InstructionLLVM : public lldb_private::Instruction
{
public:
InstructionLLVM (const lldb_private::Address &addr,
lldb_private::AddressClass addr_class,
EDDisassemblerRef disassembler);
virtual
~InstructionLLVM();
virtual void
Dump (lldb_private::Stream *s,
uint32_t max_opcode_byte_size,
bool show_address,
bool show_bytes,
const lldb_private::ExecutionContext* exe_ctx,
bool raw);
virtual bool
DoesBranch () const;
virtual size_t
Decode (const lldb_private::Disassembler &disassembler,
const lldb_private::DataExtractor &data,
uint32_t data_offset);
protected:
EDDisassemblerRef m_disassembler;
EDInstRef m_inst;
};
class DisassemblerLLVM : public lldb_private::Disassembler
{
public:
class InstructionLLVM : public lldb_private::Instruction
{
public:
InstructionLLVM (const lldb_private::Address &addr,
lldb_private::AddressClass addr_class,
EDDisassemblerRef disassembler);
virtual
~InstructionLLVM();
virtual void
Dump (lldb_private::Stream *s,
uint32_t max_opcode_byte_size,
bool show_address,
bool show_bytes,
const lldb_private::ExecutionContext* exe_ctx,
bool raw);
virtual bool
DoesBranch () const;
virtual size_t
Decode (const Disassembler &disassembler,
const lldb_private::DataExtractor &data,
uint32_t data_offset);
protected:
EDDisassemblerRef m_disassembler;
EDInstRef m_inst;
};
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------

View File

@ -13056,7 +13056,8 @@ EmulateInstructionARM::EvaluateInstruction ()
}
// Just for now, for testing purposes.
//fprintf (stdout, "\nEvaluateInstruction, opcode (0x%x), found = '%s'\n", m_opcode.GetOpcode32(), opcode_data->name);
if (m_baton == NULL)
fprintf (stdout, "\nEvaluateInstruction, opcode (0x%x), found = '%s'\n", m_opcode.GetOpcode32(), opcode_data->name);
return (this->*opcode_data->callback) (m_opcode.GetOpcode32(), opcode_data->encoding); // Call the Emulate... function.
}