diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/API/SBInstruction.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/API/SBInstruction.cpp | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp b/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp new file mode 100644 index 0000000..2334cc0 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp @@ -0,0 +1,248 @@ +//===-- SBInstruction.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.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; + +SBInstruction::SBInstruction () +{ +} + +SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) : + m_opaque_sp (inst_sp) +{ +} + +SBInstruction::SBInstruction(const SBInstruction &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +const SBInstruction & +SBInstruction::operator = (const SBInstruction &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +SBInstruction::~SBInstruction () +{ +} + +bool +SBInstruction::IsValid() +{ + return (m_opaque_sp.get() != NULL); +} + +SBAddress +SBInstruction::GetAddress() +{ + SBAddress sb_addr; + if (m_opaque_sp && m_opaque_sp->GetAddress().IsValid()) + sb_addr.SetAddress(&m_opaque_sp->GetAddress()); + return sb_addr; +} + +const char * +SBInstruction::GetMnemonic(SBTarget target) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker; + ExecutionContext exe_ctx; + TargetSP target_sp (target.GetSP()); + if (target_sp) + { + api_locker.Lock (target_sp->GetAPIMutex()); + target_sp->CalculateExecutionContext (exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); + } + return m_opaque_sp->GetMnemonic(&exe_ctx); + } + return NULL; +} + +const char * +SBInstruction::GetOperands(SBTarget target) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker; + ExecutionContext exe_ctx; + TargetSP target_sp (target.GetSP()); + if (target_sp) + { + api_locker.Lock (target_sp->GetAPIMutex()); + target_sp->CalculateExecutionContext (exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); + } + return m_opaque_sp->GetOperands(&exe_ctx); + } + return NULL; +} + +const char * +SBInstruction::GetComment(SBTarget target) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker; + ExecutionContext exe_ctx; + TargetSP target_sp (target.GetSP()); + if (target_sp) + { + api_locker.Lock (target_sp->GetAPIMutex()); + target_sp->CalculateExecutionContext (exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); + } + return m_opaque_sp->GetComment(&exe_ctx); + } + return NULL; +} + +size_t +SBInstruction::GetByteSize () +{ + if (m_opaque_sp) + return m_opaque_sp->GetOpcode().GetByteSize(); + return 0; +} + +SBData +SBInstruction::GetData (SBTarget target) +{ + lldb::SBData sb_data; + if (m_opaque_sp) + { + DataExtractorSP data_extractor_sp (new DataExtractor()); + if (m_opaque_sp->GetData (*data_extractor_sp)) + { + sb_data.SetOpaque (data_extractor_sp); + } + } + return sb_data; +} + + + +bool +SBInstruction::DoesBranch () +{ + if (m_opaque_sp) + return m_opaque_sp->DoesBranch (); + return false; +} + +void +SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp) +{ + m_opaque_sp = inst_sp; +} + +bool +SBInstruction::GetDescription (lldb::SBStream &s) +{ + if (m_opaque_sp) + { + // Use the "ref()" instead of the "get()" accessor in case the SBStream + // didn't have a stream already created, one will get created... + m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL); + return true; + } + return false; +} + +void +SBInstruction::Print (FILE *out) +{ + if (out == NULL) + return; + + if (m_opaque_sp) + { + StreamFile out_stream (out, false); + m_opaque_sp->Dump (&out_stream, 0, true, false, NULL); + } +} + +bool +SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options) +{ + if (m_opaque_sp) + { + lldb::StackFrameSP frame_sp (frame.GetFrameSP()); + + if (frame_sp) + { + lldb_private::ExecutionContext exe_ctx; + frame_sp->CalculateExecutionContext (exe_ctx); + lldb_private::Target *target = exe_ctx.GetTargetPtr(); + lldb_private::ArchSpec arch = target->GetArchitecture(); + + return m_opaque_sp->Emulate (arch, + evaluate_options, + (void *) frame_sp.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, NULL); + + return m_opaque_sp->DumpEmulation (arch); + + } + return false; +} + +bool +SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file) +{ + if (!m_opaque_sp.get()) + m_opaque_sp.reset (new PseudoInstruction()); + + return m_opaque_sp->TestEmulation (output_stream.get(), test_file); +} + +lldb::AddressClass +SBInstruction::GetAddressClass () +{ + if (m_opaque_sp.get()) + return m_opaque_sp->GetAddressClass(); + return eAddressClassInvalid; +} |