forked from OSchip/llvm-project
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:
parent
ce6b047a10
commit
7c9dd3ce3c
|
@ -137,6 +137,7 @@ protected:
|
|||
|
||||
private:
|
||||
friend class SBThread;
|
||||
friend class SBInstruction;
|
||||
friend class lldb_private::ScriptInterpreterPython;
|
||||
|
||||
#ifndef SWIG
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ public:
|
|||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
|
||||
bool
|
||||
DumpEmulationForAllInstructions (const char *triple);
|
||||
|
||||
protected:
|
||||
friend class SBFunction;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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)))
|
||||
{
|
||||
|
|
|
@ -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
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue