summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBFrame.h1
-rw-r--r--lldb/include/lldb/API/SBInstruction.h6
-rw-r--r--lldb/include/lldb/API/SBInstructionList.h3
-rw-r--r--lldb/include/lldb/Core/Disassembler.h14
-rw-r--r--lldb/source/API/SBInstruction.cpp45
-rw-r--r--lldb/source/API/SBInstructionList.cpp15
-rw-r--r--lldb/source/Core/Disassembler.cpp33
-rw-r--r--lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp18
-rw-r--r--lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h63
-rw-r--r--lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp3
10 files changed, 159 insertions, 42 deletions
diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h
index 9d7165b36aa..acbbcba49ea 100644
--- a/lldb/include/lldb/API/SBFrame.h
+++ b/lldb/include/lldb/API/SBFrame.h
@@ -137,6 +137,7 @@ protected:
private:
friend class SBThread;
+ friend class SBInstruction;
friend class lldb_private::ScriptInterpreterPython;
#ifndef SWIG
diff --git a/lldb/include/lldb/API/SBInstruction.h b/lldb/include/lldb/API/SBInstruction.h
index 26c0d9fba64..d12c8ce8b09 100644
--- a/lldb/include/lldb/API/SBInstruction.h
+++ b/lldb/include/lldb/API/SBInstruction.h
@@ -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;
diff --git a/lldb/include/lldb/API/SBInstructionList.h b/lldb/include/lldb/API/SBInstructionList.h
index 53df069941b..5e7d0612aea 100644
--- a/lldb/include/lldb/API/SBInstructionList.h
+++ b/lldb/include/lldb/API/SBInstructionList.h
@@ -48,6 +48,9 @@ public:
bool
GetDescription (lldb::SBStream &description);
+
+ bool
+ DumpEmulationForAllInstructions (const char *triple);
protected:
friend class SBFunction;
diff --git a/lldb/include/lldb/Core/Disassembler.h b/lldb/include/lldb/Core/Disassembler.h
index c46073ca38e..705d9bb7198 100644
--- a/lldb/include/lldb/Core/Disassembler.h
+++ b/lldb/include/lldb/Core/Disassembler.h
@@ -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
{
diff --git a/lldb/source/API/SBInstruction.cpp b/lldb/source/API/SBInstruction.cpp
index 75683f600e8..ce90bbb4fb7 100644
--- a/lldb/source/API/SBInstruction.cpp
+++ b/lldb/source/API/SBInstruction.cpp
@@ -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;
+}
+
diff --git a/lldb/source/API/SBInstructionList.cpp b/lldb/source/API/SBInstructionList.cpp
index 312922fd825..c6fe572e22f 100644
--- a/lldb/source/API/SBInstructionList.cpp
+++ b/lldb/source/API/SBInstructionList.cpp
@@ -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;
+}
+
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index e2de734d5d7..2318cf5783d 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -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()
{
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
index 74d45759efe..285578686e2 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
+++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
@@ -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)))
{
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
index 8408d70dc87..69998d91cb9 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
+++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
@@ -16,40 +16,41 @@
#include "lldb/Core/Disassembler.h"
#include "lldb/Host/Mutex.h"
-class DisassemblerLLVM : public lldb_private::Disassembler
+class InstructionLLVM : public lldb_private::Instruction
{
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;
- };
+ 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:
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index dbe3212bc0c..04abfbdb0de 100644
--- a/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -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.
}
OpenPOWER on IntegriCloud