From 7c9dd3ce3c70301ed46f7eb1345a96cfd1fa37b0 Mon Sep 17 00:00:00 2001 From: Caroline Tice Date: Tue, 5 Apr 2011 23:22:54 +0000 Subject: [PATCH] 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 --- lldb/include/lldb/API/SBFrame.h | 1 + lldb/include/lldb/API/SBInstruction.h | 6 ++ lldb/include/lldb/API/SBInstructionList.h | 3 + lldb/include/lldb/Core/Disassembler.h | 14 ++++- lldb/source/API/SBInstruction.cpp | 45 +++++++++++++ lldb/source/API/SBInstructionList.cpp | 15 +++++ lldb/source/Core/Disassembler.cpp | 33 ++++++++++ .../Disassembler/llvm/DisassemblerLLVM.cpp | 18 +++--- .../Disassembler/llvm/DisassemblerLLVM.h | 63 ++++++++++--------- .../Instruction/ARM/EmulateInstructionARM.cpp | 3 +- 10 files changed, 159 insertions(+), 42 deletions(-) diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h index 9d7165b36aaf..acbbcba49eac 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 26c0d9fba64a..d12c8ce8b098 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 53df069941bf..5e7d0612aeab 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 c46073ca38e0..705d9bb71980 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 75683f600e8d..ce90bbb4fb72 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 312922fd825d..c6fe572e22f7 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 e2de734d5d71..2318cf5783d9 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 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 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 74d45759efeb..285578686e2d 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 8408d70dc879..69998d91cb9e 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 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/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index dbe3212bc0c1..04abfbdb0ded 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. }