Add Emulate and DumpEmulation to Instruction class.

Move InstructionLLVM out of DisassemblerLLVM class.

Add instruction emulation function calls to SBInstruction and SBInstructionList APIs.



git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@128956 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp
index 75683f6..ce90bbb 100644
--- a/source/API/SBInstruction.cpp
+++ b/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 @@
         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/source/API/SBInstructionList.cpp b/source/API/SBInstructionList.cpp
index 312922f..c6fe572 100644
--- a/source/API/SBInstructionList.cpp
+++ b/source/API/SBInstructionList.cpp
@@ -109,3 +109,18 @@
 }
 
 
+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/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp
index e2de734..2318cf5 100644
--- a/source/Core/Disassembler.cpp
+++ b/source/Core/Disassembler.cpp
@@ -489,6 +489,39 @@
     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/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
index 74d4575..2855786 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
@@ -74,15 +74,15 @@
     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 @@
 }
 
 void
-DisassemblerLLVM::InstructionLLVM::Dump
+InstructionLLVM::Dump
 (
     Stream *s,
     uint32_t max_opcode_byte_size,
@@ -332,15 +332,15 @@
 }
 
 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/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h b/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
index 8408d70..69998d9 100644
--- a/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
+++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
@@ -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
     //------------------------------------------------------------------
diff --git a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
index dbe3212..04abfbd 100644
--- a/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
+++ b/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
@@ -13056,7 +13056,8 @@
     }
     
     // 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.
 }