diff options
author | Ed Maste <emaste@FreeBSD.org> | 2013-08-23 17:46:38 +0000 |
---|---|---|
committer | Ed Maste <emaste@FreeBSD.org> | 2013-08-23 17:46:38 +0000 |
commit | f034231a6a1fd5d6395206c1651de8cd9402cca3 (patch) | |
tree | f561dabc721ad515599172c16da3a4400b7f4aec /source | |
download | src-f034231a6a1fd5d6395206c1651de8cd9402cca3.tar.gz src-f034231a6a1fd5d6395206c1651de8cd9402cca3.zip |
Import lldb as of SVN r188801
(A number of files not required for the FreeBSD build have been removed.)
Sponsored by: DARPA, AFRL
Notes
Notes:
svn path=/vendor/lldb/dist/; revision=254721
Diffstat (limited to 'source')
541 files changed, 276788 insertions, 0 deletions
diff --git a/source/API/SBAddress.cpp b/source/API/SBAddress.cpp new file mode 100644 index 000000000000..799c90907634 --- /dev/null +++ b/source/API/SBAddress.cpp @@ -0,0 +1,326 @@ +//===-- SBAddress.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/SBAddress.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBSection.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Host/Mutex.h" +#include "lldb/Target/Target.h" + + +using namespace lldb; +using namespace lldb_private; + + +SBAddress::SBAddress () : + m_opaque_ap () +{ +} + +SBAddress::SBAddress (const Address *lldb_object_ptr) : + m_opaque_ap () +{ + if (lldb_object_ptr) + ref() = *lldb_object_ptr; +} + +SBAddress::SBAddress (const SBAddress &rhs) : + m_opaque_ap () +{ + if (rhs.IsValid()) + ref() = rhs.ref(); +} + + +SBAddress::SBAddress (lldb::SBSection section, lldb::addr_t offset) : + m_opaque_ap(new Address (section.GetSP(), offset)) +{ +} + +// Create an address by resolving a load address using the supplied target +SBAddress::SBAddress (lldb::addr_t load_addr, lldb::SBTarget &target) : + m_opaque_ap() +{ + SetLoadAddress (load_addr, target); +} + + + +SBAddress::~SBAddress () +{ +} + +const SBAddress & +SBAddress::operator = (const SBAddress &rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + ref() = rhs.ref(); + else + m_opaque_ap.reset(); + } + return *this; +} + +bool +SBAddress::IsValid () const +{ + return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid(); +} + +void +SBAddress::Clear () +{ + m_opaque_ap.reset(); +} + +void +SBAddress::SetAddress (lldb::SBSection section, lldb::addr_t offset) +{ + Address &addr = ref(); + addr.SetSection (section.GetSP()); + addr.SetOffset (offset); +} + + +void +SBAddress::SetAddress (const Address *lldb_object_ptr) +{ + if (lldb_object_ptr) + ref() = *lldb_object_ptr; + else + m_opaque_ap.reset(); +} + +lldb::addr_t +SBAddress::GetFileAddress () const +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetFileAddress(); + else + return LLDB_INVALID_ADDRESS; +} + +lldb::addr_t +SBAddress::GetLoadAddress (const SBTarget &target) const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + lldb::addr_t addr = LLDB_INVALID_ADDRESS; + TargetSP target_sp (target.GetSP()); + if (target_sp) + { + if (m_opaque_ap.get()) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + addr = m_opaque_ap->GetLoadAddress (target_sp.get()); + } + } + + if (log) + { + if (addr == LLDB_INVALID_ADDRESS) + log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS", target_sp.get()); + else + log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64, target_sp.get(), addr); + } + + return addr; +} + +void +SBAddress::SetLoadAddress (lldb::addr_t load_addr, lldb::SBTarget &target) +{ + // Create the address object if we don't already have one + ref(); + if (target.IsValid()) + *this = target.ResolveLoadAddress(load_addr); + else + m_opaque_ap->Clear(); + + // Check if we weren't were able to resolve a section offset address. + // If we weren't it is ok, the load address might be a location on the + // stack or heap, so we should just have an address with no section and + // a valid offset + if (!m_opaque_ap->IsValid()) + m_opaque_ap->SetOffset(load_addr); +} + +bool +SBAddress::OffsetAddress (addr_t offset) +{ + if (m_opaque_ap.get()) + { + addr_t addr_offset = m_opaque_ap->GetOffset(); + if (addr_offset != LLDB_INVALID_ADDRESS) + { + m_opaque_ap->SetOffset(addr_offset + offset); + return true; + } + } + return false; +} + +lldb::SBSection +SBAddress::GetSection () +{ + lldb::SBSection sb_section; + if (m_opaque_ap.get()) + sb_section.SetSP (m_opaque_ap->GetSection()); + return sb_section; +} + +lldb::addr_t +SBAddress::GetOffset () +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetOffset(); + return 0; +} + +Address * +SBAddress::operator->() +{ + return m_opaque_ap.get(); +} + +const Address * +SBAddress::operator->() const +{ + return m_opaque_ap.get(); +} + +Address & +SBAddress::ref () +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new Address()); + return *m_opaque_ap; +} + +const Address & +SBAddress::ref () const +{ + // This object should already have checked with "IsValid()" + // prior to calling this function. In case you didn't we will assert + // and die to let you know. + assert (m_opaque_ap.get()); + return *m_opaque_ap; +} + +Address * +SBAddress::get () +{ + return m_opaque_ap.get(); +} + +bool +SBAddress::GetDescription (SBStream &description) +{ + // Call "ref()" on the stream to make sure it creates a backing stream in + // case there isn't one already... + Stream &strm = description.ref(); + if (m_opaque_ap.get()) + { + m_opaque_ap->Dump (&strm, + NULL, + Address::DumpStyleResolvedDescription, + Address::DumpStyleModuleWithFileAddress, + 4); + StreamString sstrm; +// m_opaque_ap->Dump (&sstrm, NULL, Address::DumpStyleResolvedDescription, Address::DumpStyleInvalid, 4); +// if (sstrm.GetData()) +// strm.Printf (" (%s)", sstrm.GetData()); + } + else + strm.PutCString ("No value"); + + return true; +} + +SBModule +SBAddress::GetModule () +{ + SBModule sb_module; + if (m_opaque_ap.get()) + sb_module.SetSP (m_opaque_ap->GetModule()); + return sb_module; +} + +SBSymbolContext +SBAddress::GetSymbolContext (uint32_t resolve_scope) +{ + SBSymbolContext sb_sc; + if (m_opaque_ap.get()) + m_opaque_ap->CalculateSymbolContext (&sb_sc.ref(), resolve_scope); + return sb_sc; +} + +SBCompileUnit +SBAddress::GetCompileUnit () +{ + SBCompileUnit sb_comp_unit; + if (m_opaque_ap.get()) + sb_comp_unit.reset(m_opaque_ap->CalculateSymbolContextCompileUnit()); + return sb_comp_unit; +} + +SBFunction +SBAddress::GetFunction () +{ + SBFunction sb_function; + if (m_opaque_ap.get()) + sb_function.reset(m_opaque_ap->CalculateSymbolContextFunction()); + return sb_function; +} + +SBBlock +SBAddress::GetBlock () +{ + SBBlock sb_block; + if (m_opaque_ap.get()) + sb_block.SetPtr(m_opaque_ap->CalculateSymbolContextBlock()); + return sb_block; +} + +SBSymbol +SBAddress::GetSymbol () +{ + SBSymbol sb_symbol; + if (m_opaque_ap.get()) + sb_symbol.reset(m_opaque_ap->CalculateSymbolContextSymbol()); + return sb_symbol; +} + +SBLineEntry +SBAddress::GetLineEntry () +{ + SBLineEntry sb_line_entry; + if (m_opaque_ap.get()) + { + LineEntry line_entry; + if (m_opaque_ap->CalculateSymbolContextLineEntry (line_entry)) + sb_line_entry.SetLineEntry (line_entry); + } + return sb_line_entry; +} + +AddressClass +SBAddress::GetAddressClass () +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetAddressClass(); + return eAddressClassInvalid; +} + diff --git a/source/API/SBBlock.cpp b/source/API/SBBlock.cpp new file mode 100644 index 000000000000..c8a665f7d6fb --- /dev/null +++ b/source/API/SBBlock.cpp @@ -0,0 +1,373 @@ +//===-- SBBlock.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/SBBlock.h" +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBFrame.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBValue.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + + +SBBlock::SBBlock () : + m_opaque_ptr (NULL) +{ +} + +SBBlock::SBBlock (lldb_private::Block *lldb_object_ptr) : + m_opaque_ptr (lldb_object_ptr) +{ +} + +SBBlock::SBBlock(const SBBlock &rhs) : + m_opaque_ptr (rhs.m_opaque_ptr) +{ +} + +const SBBlock & +SBBlock::operator = (const SBBlock &rhs) +{ + m_opaque_ptr = rhs.m_opaque_ptr; + return *this; +} + +SBBlock::~SBBlock () +{ + m_opaque_ptr = NULL; +} + +bool +SBBlock::IsValid () const +{ + return m_opaque_ptr != NULL; +} + +bool +SBBlock::IsInlined () const +{ + if (m_opaque_ptr) + return m_opaque_ptr->GetInlinedFunctionInfo () != NULL; + return false; +} + +const char * +SBBlock::GetInlinedName () const +{ + if (m_opaque_ptr) + { + const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo (); + if (inlined_info) + return inlined_info->GetName().AsCString (NULL); + } + return NULL; +} + +SBFileSpec +SBBlock::GetInlinedCallSiteFile () const +{ + SBFileSpec sb_file; + if (m_opaque_ptr) + { + const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo (); + if (inlined_info) + sb_file.SetFileSpec (inlined_info->GetCallSite().GetFile()); + } + return sb_file; +} + +uint32_t +SBBlock::GetInlinedCallSiteLine () const +{ + if (m_opaque_ptr) + { + const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo (); + if (inlined_info) + return inlined_info->GetCallSite().GetLine(); + } + return 0; +} + +uint32_t +SBBlock::GetInlinedCallSiteColumn () const +{ + if (m_opaque_ptr) + { + const InlineFunctionInfo* inlined_info = m_opaque_ptr->GetInlinedFunctionInfo (); + if (inlined_info) + return inlined_info->GetCallSite().GetColumn(); + } + return 0; +} + +void +SBBlock::AppendVariables (bool can_create, bool get_parent_variables, lldb_private::VariableList *var_list) +{ + if (IsValid()) + { + bool show_inline = true; + m_opaque_ptr->AppendVariables (can_create, get_parent_variables, show_inline, var_list); + } +} + +SBBlock +SBBlock::GetParent () +{ + SBBlock sb_block; + if (m_opaque_ptr) + sb_block.m_opaque_ptr = m_opaque_ptr->GetParent(); + return sb_block; +} + +lldb::SBBlock +SBBlock::GetContainingInlinedBlock () +{ + SBBlock sb_block; + if (m_opaque_ptr) + sb_block.m_opaque_ptr = m_opaque_ptr->GetContainingInlinedBlock (); + return sb_block; +} + +SBBlock +SBBlock::GetSibling () +{ + SBBlock sb_block; + if (m_opaque_ptr) + sb_block.m_opaque_ptr = m_opaque_ptr->GetSibling(); + return sb_block; +} + +SBBlock +SBBlock::GetFirstChild () +{ + SBBlock sb_block; + if (m_opaque_ptr) + sb_block.m_opaque_ptr = m_opaque_ptr->GetFirstChild(); + return sb_block; +} + +lldb_private::Block * +SBBlock::GetPtr () +{ + return m_opaque_ptr; +} + +void +SBBlock::SetPtr (lldb_private::Block *block) +{ + m_opaque_ptr = block; +} + +bool +SBBlock::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + if (m_opaque_ptr) + { + lldb::user_id_t id = m_opaque_ptr->GetID(); + strm.Printf ("Block: {id: %" PRIu64 "} ", id); + if (IsInlined()) + { + strm.Printf (" (inlined, '%s') ", GetInlinedName()); + } + lldb_private::SymbolContext sc; + m_opaque_ptr->CalculateSymbolContext (&sc); + if (sc.function) + { + m_opaque_ptr->DumpAddressRanges (&strm, + sc.function->GetAddressRange().GetBaseAddress().GetFileAddress()); + } + } + else + strm.PutCString ("No value"); + + return true; +} + +uint32_t +SBBlock::GetNumRanges () +{ + if (m_opaque_ptr) + return m_opaque_ptr->GetNumRanges(); + return 0; +} + +lldb::SBAddress +SBBlock::GetRangeStartAddress (uint32_t idx) +{ + lldb::SBAddress sb_addr; + if (m_opaque_ptr) + { + AddressRange range; + if (m_opaque_ptr->GetRangeAtIndex(idx, range)) + { + sb_addr.ref() = range.GetBaseAddress(); + } + } + return sb_addr; +} + +lldb::SBAddress +SBBlock::GetRangeEndAddress (uint32_t idx) +{ + lldb::SBAddress sb_addr; + if (m_opaque_ptr) + { + AddressRange range; + if (m_opaque_ptr->GetRangeAtIndex(idx, range)) + { + sb_addr.ref() = range.GetBaseAddress(); + sb_addr.ref().Slide(range.GetByteSize()); + } + } + return sb_addr; +} + +uint32_t +SBBlock::GetRangeIndexForBlockAddress (lldb::SBAddress block_addr) +{ + if (m_opaque_ptr && block_addr.IsValid()) + { + return m_opaque_ptr->GetRangeIndexContainingAddress (block_addr.ref()); + } + + return UINT32_MAX; +} + + +lldb::SBValueList +SBBlock::GetVariables (lldb::SBFrame& frame, + bool arguments, + bool locals, + bool statics, + lldb::DynamicValueType use_dynamic) +{ + Block *block = GetPtr(); + SBValueList value_list; + if (block) + { + StackFrameSP frame_sp(frame.GetFrameSP()); + VariableListSP variable_list_sp (block->GetBlockVariableList (true)); + + if (variable_list_sp) + { + const size_t num_variables = variable_list_sp->GetSize(); + if (num_variables) + { + for (size_t i = 0; i < num_variables; ++i) + { + VariableSP variable_sp (variable_list_sp->GetVariableAtIndex(i)); + if (variable_sp) + { + bool add_variable = false; + switch (variable_sp->GetScope()) + { + case eValueTypeVariableGlobal: + case eValueTypeVariableStatic: + add_variable = statics; + break; + + case eValueTypeVariableArgument: + add_variable = arguments; + break; + + case eValueTypeVariableLocal: + add_variable = locals; + break; + + default: + break; + } + if (add_variable) + { + if (frame_sp) + { + lldb::ValueObjectSP valobj_sp(frame_sp->GetValueObjectForFrameVariable (variable_sp,eNoDynamicValues)); + SBValue value_sb; + value_sb.SetSP(valobj_sp, use_dynamic); + value_list.Append (value_sb); + } + } + } + } + } + } + } + return value_list; +} + +lldb::SBValueList +SBBlock::GetVariables (lldb::SBTarget& target, + bool arguments, + bool locals, + bool statics) +{ + Block *block = GetPtr(); + + SBValueList value_list; + if (block) + { + TargetSP target_sp(target.GetSP()); + + VariableListSP variable_list_sp (block->GetBlockVariableList (true)); + + if (variable_list_sp) + { + const size_t num_variables = variable_list_sp->GetSize(); + if (num_variables) + { + for (size_t i = 0; i < num_variables; ++i) + { + VariableSP variable_sp (variable_list_sp->GetVariableAtIndex(i)); + if (variable_sp) + { + bool add_variable = false; + switch (variable_sp->GetScope()) + { + case eValueTypeVariableGlobal: + case eValueTypeVariableStatic: + add_variable = statics; + break; + + case eValueTypeVariableArgument: + add_variable = arguments; + break; + + case eValueTypeVariableLocal: + add_variable = locals; + break; + + default: + break; + } + if (add_variable) + { + if (target_sp) + value_list.Append (ValueObjectVariable::Create (target_sp.get(), variable_sp)); + } + } + } + } + } + } + return value_list; +} + diff --git a/source/API/SBBreakpoint.cpp b/source/API/SBBreakpoint.cpp new file mode 100644 index 000000000000..11ad149fdddc --- /dev/null +++ b/source/API/SBBreakpoint.cpp @@ -0,0 +1,648 @@ +//===-- SBBreakpoint.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/SBBreakpoint.h" +#include "lldb/API/SBBreakpointLocation.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBThread.h" + +#include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadSpec.h" + + +#include "lldb/lldb-enumerations.h" + +using namespace lldb; +using namespace lldb_private; + +struct CallbackData +{ + SBBreakpoint::BreakpointHitCallback callback; + void *callback_baton; +}; + +class SBBreakpointCallbackBaton : public Baton +{ +public: + + SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) : + Baton (new CallbackData) + { + CallbackData *data = (CallbackData *)m_data; + data->callback = callback; + data->callback_baton = baton; + } + + virtual ~SBBreakpointCallbackBaton() + { + CallbackData *data = (CallbackData *)m_data; + + if (data) + { + delete data; + m_data = NULL; + } + } +}; + + +SBBreakpoint::SBBreakpoint () : + m_opaque_sp () +{ +} + +SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + + +SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) : + m_opaque_sp (bp_sp) +{ +} + +SBBreakpoint::~SBBreakpoint() +{ +} + +const SBBreakpoint & +SBBreakpoint::operator = (const SBBreakpoint& rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +bool +SBBreakpoint::operator == (const lldb::SBBreakpoint& rhs) +{ + if (m_opaque_sp && rhs.m_opaque_sp) + return m_opaque_sp.get() == rhs.m_opaque_sp.get(); + return false; +} + +bool +SBBreakpoint::operator != (const lldb::SBBreakpoint& rhs) +{ + if (m_opaque_sp && rhs.m_opaque_sp) + return m_opaque_sp.get() != rhs.m_opaque_sp.get(); + return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp); +} + +break_id_t +SBBreakpoint::GetID () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + break_id_t break_id = LLDB_INVALID_BREAK_ID; + if (m_opaque_sp) + break_id = m_opaque_sp->GetID(); + + if (log) + { + if (break_id == LLDB_INVALID_BREAK_ID) + log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID", m_opaque_sp.get()); + else + log->Printf ("SBBreakpoint(%p)::GetID () => %u", m_opaque_sp.get(), break_id); + } + + return break_id; +} + + +bool +SBBreakpoint::IsValid() const +{ + return (bool) m_opaque_sp; +} + +void +SBBreakpoint::ClearAllBreakpointSites () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->ClearAllBreakpointSites (); + } +} + +SBBreakpointLocation +SBBreakpoint::FindLocationByAddress (addr_t vm_addr) +{ + SBBreakpointLocation sb_bp_location; + + if (m_opaque_sp) + { + if (vm_addr != LLDB_INVALID_ADDRESS) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + Address address; + Target &target = m_opaque_sp->GetTarget(); + if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false) + { + address.SetRawAddress (vm_addr); + } + sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address)); + } + } + return sb_bp_location; +} + +break_id_t +SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr) +{ + break_id_t break_id = LLDB_INVALID_BREAK_ID; + + if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + Address address; + Target &target = m_opaque_sp->GetTarget(); + if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false) + { + address.SetRawAddress (vm_addr); + } + break_id = m_opaque_sp->FindLocationIDByAddress (address); + } + + return break_id; +} + +SBBreakpointLocation +SBBreakpoint::FindLocationByID (break_id_t bp_loc_id) +{ + SBBreakpointLocation sb_bp_location; + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id)); + } + + return sb_bp_location; +} + +SBBreakpointLocation +SBBreakpoint::GetLocationAtIndex (uint32_t index) +{ + SBBreakpointLocation sb_bp_location; + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index)); + } + + return sb_bp_location; +} + +void +SBBreakpoint::SetEnabled (bool enable) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)", m_opaque_sp.get(), enable); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetEnabled (enable); + } +} + +bool +SBBreakpoint::IsEnabled () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + return m_opaque_sp->IsEnabled(); + } + else + return false; +} + +void +SBBreakpoint::SetOneShot (bool one_shot) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)", m_opaque_sp.get(), one_shot); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetOneShot (one_shot); + } +} + +bool +SBBreakpoint::IsOneShot () const +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + return m_opaque_sp->IsOneShot(); + } + else + return false; +} + +bool +SBBreakpoint::IsInternal () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + return m_opaque_sp->IsInternal(); + } + else + return false; +} + +void +SBBreakpoint::SetIgnoreCount (uint32_t count) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)", m_opaque_sp.get(), count); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetIgnoreCount (count); + } +} + +void +SBBreakpoint::SetCondition (const char *condition) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetCondition (condition); + } +} + +const char * +SBBreakpoint::GetCondition () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + return m_opaque_sp->GetConditionText (); + } + return NULL; +} + +uint32_t +SBBreakpoint::GetHitCount () const +{ + uint32_t count = 0; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + count = m_opaque_sp->GetHitCount(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u", m_opaque_sp.get(), count); + + return count; +} + +uint32_t +SBBreakpoint::GetIgnoreCount () const +{ + uint32_t count = 0; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + count = m_opaque_sp->GetIgnoreCount(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u", m_opaque_sp.get(), count); + + return count; +} + +void +SBBreakpoint::SetThreadID (tid_t tid) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetThreadID (tid); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")", m_opaque_sp.get(), tid); + +} + +tid_t +SBBreakpoint::GetThreadID () +{ + tid_t tid = LLDB_INVALID_THREAD_ID; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + tid = m_opaque_sp->GetThreadID(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64, m_opaque_sp.get(), tid); + return tid; +} + +void +SBBreakpoint::SetThreadIndex (uint32_t index) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)", m_opaque_sp.get(), index); + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index); + } +} + +uint32_t +SBBreakpoint::GetThreadIndex() const +{ + uint32_t thread_idx = UINT32_MAX; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate(); + if (thread_spec != NULL) + thread_idx = thread_spec->GetIndex(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u", m_opaque_sp.get(), thread_idx); + + return thread_idx; +} + + +void +SBBreakpoint::SetThreadName (const char *thread_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)", m_opaque_sp.get(), thread_name); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name); + } +} + +const char * +SBBreakpoint::GetThreadName () const +{ + const char *name = NULL; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate(); + if (thread_spec != NULL) + name = thread_spec->GetName(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s", m_opaque_sp.get(), name); + + return name; +} + +void +SBBreakpoint::SetQueueName (const char *queue_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)", m_opaque_sp.get(), queue_name); + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name); + } +} + +const char * +SBBreakpoint::GetQueueName () const +{ + const char *name = NULL; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate(); + if (thread_spec) + name = thread_spec->GetQueueName(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s", m_opaque_sp.get(), name); + + return name; +} + +size_t +SBBreakpoint::GetNumResolvedLocations() const +{ + size_t num_resolved = 0; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + num_resolved = m_opaque_sp->GetNumResolvedLocations(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_resolved); + return num_resolved; +} + +size_t +SBBreakpoint::GetNumLocations() const +{ + size_t num_locs = 0; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + num_locs = m_opaque_sp->GetNumLocations(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_locs); + return num_locs; +} + +bool +SBBreakpoint::GetDescription (SBStream &s) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID()); + m_opaque_sp->GetResolverDescription (s.get()); + m_opaque_sp->GetFilterDescription (s.get()); + const size_t num_locations = m_opaque_sp->GetNumLocations (); + s.Printf(", locations = %" PRIu64, (uint64_t)num_locations); + return true; + } + s.Printf ("No value"); + return false; +} + +bool +SBBreakpoint::PrivateBreakpointHitCallback +( + void *baton, + StoppointCallbackContext *ctx, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id +) +{ + ExecutionContext exe_ctx (ctx->exe_ctx_ref); + BreakpointSP bp_sp(exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id)); + if (baton && bp_sp) + { + CallbackData *data = (CallbackData *)baton; + lldb_private::Breakpoint *bp = bp_sp.get(); + if (bp && data->callback) + { + Process *process = exe_ctx.GetProcessPtr(); + if (process) + { + SBProcess sb_process (process->shared_from_this()); + SBThread sb_thread; + SBBreakpointLocation sb_location; + assert (bp_sp); + sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id)); + Thread *thread = exe_ctx.GetThreadPtr(); + if (thread) + sb_thread.SetThread(thread->shared_from_this()); + + return data->callback (data->callback_baton, + sb_process, + sb_thread, + sb_location); + } + } + } + return true; // Return true if we should stop at this breakpoint +} + +void +SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)", m_opaque_sp.get(), callback, baton); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton)); + m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false); + } +} + + +lldb_private::Breakpoint * +SBBreakpoint::operator->() const +{ + return m_opaque_sp.get(); +} + +lldb_private::Breakpoint * +SBBreakpoint::get() const +{ + return m_opaque_sp.get(); +} + +lldb::BreakpointSP & +SBBreakpoint::operator *() +{ + return m_opaque_sp; +} + +const lldb::BreakpointSP & +SBBreakpoint::operator *() const +{ + return m_opaque_sp; +} + +bool +SBBreakpoint::EventIsBreakpointEvent (const lldb::SBEvent &event) +{ + return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != NULL; + +} + +BreakpointEventType +SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event) +{ + if (event.IsValid()) + return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP()); + return eBreakpointEventTypeInvalidType; +} + +SBBreakpoint +SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event) +{ + SBBreakpoint sb_breakpoint; + if (event.IsValid()) + sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP()); + return sb_breakpoint; +} + +SBBreakpointLocation +SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx) +{ + SBBreakpointLocation sb_breakpoint_loc; + if (event.IsValid()) + sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx)); + return sb_breakpoint_loc; +} + +uint32_t +SBBreakpoint::GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event) +{ + uint32_t num_locations = 0; + if (event.IsValid()) + num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (event.GetSP())); + return num_locations; +} + + diff --git a/source/API/SBBreakpointLocation.cpp b/source/API/SBBreakpointLocation.cpp new file mode 100644 index 000000000000..6fdf59f38b4a --- /dev/null +++ b/source/API/SBBreakpointLocation.cpp @@ -0,0 +1,320 @@ +//===-- SBBreakpointLocation.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/SBBreakpointLocation.h" +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBStream.h" + +#include "lldb/lldb-types.h" +#include "lldb/lldb-defines.h" +#include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Target/ThreadSpec.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/ThreadSpec.h" + +using namespace lldb; +using namespace lldb_private; + + +SBBreakpointLocation::SBBreakpointLocation () : + m_opaque_sp () +{ +} + +SBBreakpointLocation::SBBreakpointLocation (const lldb::BreakpointLocationSP &break_loc_sp) : + m_opaque_sp (break_loc_sp) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + { + SBStream sstr; + GetDescription (sstr, lldb::eDescriptionLevelBrief); + log->Printf ("SBBreakpointLocation::SBBreakpointLocaiton (const lldb::BreakpointLocationsSP &break_loc_sp" + "=%p) => this.sp = %p (%s)", break_loc_sp.get(), m_opaque_sp.get(), sstr.GetData()); + } +} + +SBBreakpointLocation::SBBreakpointLocation(const SBBreakpointLocation &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +const SBBreakpointLocation & +SBBreakpointLocation::operator = (const SBBreakpointLocation &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + + +SBBreakpointLocation::~SBBreakpointLocation () +{ +} + +bool +SBBreakpointLocation::IsValid() const +{ + return m_opaque_sp.get() != NULL; +} + +SBAddress +SBBreakpointLocation::GetAddress () +{ + if (m_opaque_sp) + return SBAddress(&m_opaque_sp->GetAddress()); + else + return SBAddress(); +} + +addr_t +SBBreakpointLocation::GetLoadAddress () +{ + addr_t ret_addr = LLDB_INVALID_ADDRESS; + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + ret_addr = m_opaque_sp->GetLoadAddress(); + } + + return ret_addr; +} + +void +SBBreakpointLocation::SetEnabled (bool enabled) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + m_opaque_sp->SetEnabled (enabled); + } +} + +bool +SBBreakpointLocation::IsEnabled () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + return m_opaque_sp->IsEnabled(); + } + else + return false; +} + +uint32_t +SBBreakpointLocation::GetIgnoreCount () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + return m_opaque_sp->GetIgnoreCount(); + } + else + return 0; +} + +void +SBBreakpointLocation::SetIgnoreCount (uint32_t n) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + m_opaque_sp->SetIgnoreCount (n); + } +} + +void +SBBreakpointLocation::SetCondition (const char *condition) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + m_opaque_sp->SetCondition (condition); + } +} + +const char * +SBBreakpointLocation::GetCondition () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + return m_opaque_sp->GetConditionText (); + } + return NULL; +} + +void +SBBreakpointLocation::SetThreadID (tid_t thread_id) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + m_opaque_sp->SetThreadID (thread_id); + } +} + +tid_t +SBBreakpointLocation::GetThreadID () +{ + tid_t tid = LLDB_INVALID_THREAD_ID; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + return m_opaque_sp->GetThreadID(); + } + return tid; +} + +void +SBBreakpointLocation::SetThreadIndex (uint32_t index) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + m_opaque_sp->SetThreadIndex (index); + } +} + +uint32_t +SBBreakpointLocation::GetThreadIndex() const +{ + uint32_t thread_idx = UINT32_MAX; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + return m_opaque_sp->GetThreadIndex(); + } + return thread_idx; +} + + +void +SBBreakpointLocation::SetThreadName (const char *thread_name) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + m_opaque_sp->SetThreadName (thread_name); + } +} + +const char * +SBBreakpointLocation::GetThreadName () const +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + return m_opaque_sp->GetThreadName(); + } + return NULL; +} + +void +SBBreakpointLocation::SetQueueName (const char *queue_name) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + m_opaque_sp->SetQueueName (queue_name); + } +} + +const char * +SBBreakpointLocation::GetQueueName () const +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + m_opaque_sp->GetQueueName (); + } + return NULL; +} + +bool +SBBreakpointLocation::IsResolved () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + return m_opaque_sp->IsResolved(); + } + return false; +} + +void +SBBreakpointLocation::SetLocation (const lldb::BreakpointLocationSP &break_loc_sp) +{ + // Uninstall the callbacks? + m_opaque_sp = break_loc_sp; +} + +bool +SBBreakpointLocation::GetDescription (SBStream &description, DescriptionLevel level) +{ + Stream &strm = description.ref(); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + m_opaque_sp->GetDescription (&strm, level); + strm.EOL(); + } + else + strm.PutCString ("No value"); + + return true; +} + +break_id_t +SBBreakpointLocation::GetID () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + return m_opaque_sp->GetID (); + } + else + return LLDB_INVALID_BREAK_ID; +} + +SBBreakpoint +SBBreakpointLocation::GetBreakpoint () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + //if (log) + // log->Printf ("SBBreakpointLocation::GetBreakpoint ()"); + + SBBreakpoint sb_bp; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + *sb_bp = m_opaque_sp->GetBreakpoint ().shared_from_this(); + } + + if (log) + { + SBStream sstr; + sb_bp.GetDescription (sstr); + log->Printf ("SBBreakpointLocation(%p)::GetBreakpoint () => SBBreakpoint(%p) %s", + m_opaque_sp.get(), sb_bp.get(), sstr.GetData()); + } + return sb_bp; +} + diff --git a/source/API/SBBroadcaster.cpp b/source/API/SBBroadcaster.cpp new file mode 100644 index 000000000000..7168305ac80b --- /dev/null +++ b/source/API/SBBroadcaster.cpp @@ -0,0 +1,196 @@ +//===-- SBBroadcaster.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/Core/Broadcaster.h" +#include "lldb/Core/Log.h" + +#include "lldb/API/SBBroadcaster.h" +#include "lldb/API/SBListener.h" +#include "lldb/API/SBEvent.h" + +using namespace lldb; +using namespace lldb_private; + + +SBBroadcaster::SBBroadcaster () : + m_opaque_sp (), + m_opaque_ptr (NULL) +{ +} + +SBBroadcaster::SBBroadcaster (const char *name) : + m_opaque_sp (new Broadcaster (NULL, name)), + m_opaque_ptr (NULL) +{ + m_opaque_ptr = m_opaque_sp.get(); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE)); + + if (log) + log->Printf ("SBBroadcaster::SBBroadcaster (name=\"%s\") => SBBroadcaster(%p)", + name, m_opaque_ptr); +} + +SBBroadcaster::SBBroadcaster (lldb_private::Broadcaster *broadcaster, bool owns) : + m_opaque_sp (owns ? broadcaster : NULL), + m_opaque_ptr (broadcaster) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE)); + + if (log) + log->Printf ("SBBroadcaster::SBBroadcaster (broadcaster=%p, bool owns=%i) => SBBroadcaster(%p)", + broadcaster, owns, m_opaque_ptr); +} + +SBBroadcaster::SBBroadcaster (const SBBroadcaster &rhs) : + m_opaque_sp (rhs.m_opaque_sp), + m_opaque_ptr (rhs.m_opaque_ptr) +{ +} + +const SBBroadcaster & +SBBroadcaster::operator = (const SBBroadcaster &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + m_opaque_ptr = rhs.m_opaque_ptr; + } + return *this; +} + +SBBroadcaster::~SBBroadcaster() +{ + reset (NULL, false); +} + +void +SBBroadcaster::BroadcastEventByType (uint32_t event_type, bool unique) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBroadcaster(%p)::BroadcastEventByType (event_type=0x%8.8x, unique=%i)", m_opaque_ptr, event_type, unique); + + if (m_opaque_ptr == NULL) + return; + + if (unique) + m_opaque_ptr->BroadcastEventIfUnique (event_type); + else + m_opaque_ptr->BroadcastEvent (event_type); +} + +void +SBBroadcaster::BroadcastEvent (const SBEvent &event, bool unique) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBroadcaster(%p)::BroadcastEventByType (SBEvent(%p), unique=%i)", m_opaque_ptr, event.get(), unique); + + if (m_opaque_ptr == NULL) + return; + + EventSP event_sp = event.GetSP (); + if (unique) + m_opaque_ptr->BroadcastEventIfUnique (event_sp); + else + m_opaque_ptr->BroadcastEvent (event_sp); +} + +void +SBBroadcaster::AddInitialEventsToListener (const SBListener &listener, uint32_t requested_events) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBroadcaster(%p)::AddInitialEventsToListener (SBListener(%p), event_mask=0x%8.8x)", m_opaque_ptr, listener.get(), requested_events); + if (m_opaque_ptr) + m_opaque_ptr->AddInitialEventsToListener (listener.get(), requested_events); +} + +uint32_t +SBBroadcaster::AddListener (const SBListener &listener, uint32_t event_mask) +{ + if (m_opaque_ptr) + return m_opaque_ptr->AddListener (listener.get(), event_mask); + return 0; +} + +const char * +SBBroadcaster::GetName () const +{ + if (m_opaque_ptr) + return m_opaque_ptr->GetBroadcasterName().GetCString(); + return NULL; +} + +bool +SBBroadcaster::EventTypeHasListeners (uint32_t event_type) +{ + if (m_opaque_ptr) + return m_opaque_ptr->EventTypeHasListeners (event_type); + return false; +} + +bool +SBBroadcaster::RemoveListener (const SBListener &listener, uint32_t event_mask) +{ + if (m_opaque_ptr) + return m_opaque_ptr->RemoveListener (listener.get(), event_mask); + return false; +} + +Broadcaster * +SBBroadcaster::get () const +{ + return m_opaque_ptr; +} + +void +SBBroadcaster::reset (Broadcaster *broadcaster, bool owns) +{ + if (owns) + m_opaque_sp.reset (broadcaster); + else + m_opaque_sp.reset (); + m_opaque_ptr = broadcaster; +} + + +bool +SBBroadcaster::IsValid () const +{ + return m_opaque_ptr != NULL; +} + +void +SBBroadcaster::Clear () +{ + m_opaque_sp.reset(); + m_opaque_ptr = NULL; +} + +bool +SBBroadcaster::operator == (const SBBroadcaster &rhs) const +{ + return m_opaque_ptr == rhs.m_opaque_ptr; + +} + +bool +SBBroadcaster::operator != (const SBBroadcaster &rhs) const +{ + return m_opaque_ptr != rhs.m_opaque_ptr; +} + +bool +SBBroadcaster::operator < (const SBBroadcaster &rhs) const +{ + return m_opaque_ptr < rhs.m_opaque_ptr; +} diff --git a/source/API/SBCommandInterpreter.cpp b/source/API/SBCommandInterpreter.cpp new file mode 100644 index 000000000000..0c839004601c --- /dev/null +++ b/source/API/SBCommandInterpreter.cpp @@ -0,0 +1,490 @@ +//===-- SBCommandInterpreter.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/lldb-python.h" + +#include "lldb/lldb-types.h" +#include "lldb/Core/SourceManager.h" +#include "lldb/Core/Listener.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Target/Target.h" + +#include "lldb/API/SBBroadcaster.h" +#include "lldb/API/SBCommandReturnObject.h" +#include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBListener.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" + +using namespace lldb; +using namespace lldb_private; + +class CommandPluginInterfaceImplementation : public CommandObjectParsed +{ +public: + CommandPluginInterfaceImplementation (CommandInterpreter &interpreter, + const char *name, + lldb::SBCommandPluginInterface* backend, + const char *help = NULL, + const char *syntax = NULL, + uint32_t flags = 0) : + CommandObjectParsed (interpreter, name, help, syntax, flags), + m_backend(backend) {} + + virtual bool + IsRemovable() const { return true; } + +protected: + virtual bool + DoExecute (Args& command, CommandReturnObject &result) + { + SBCommandReturnObject sb_return(&result); + SBCommandInterpreter sb_interpreter(&m_interpreter); + SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this()); + bool ret = m_backend->DoExecute (debugger_sb,(char**)command.GetArgumentVector(), sb_return); + sb_return.Release(); + return ret; + } + lldb::SBCommandPluginInterface* m_backend; +}; + +SBCommandInterpreter::SBCommandInterpreter (CommandInterpreter *interpreter) : + m_opaque_ptr (interpreter) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBCommandInterpreter::SBCommandInterpreter (interpreter=%p)" + " => SBCommandInterpreter(%p)", interpreter, m_opaque_ptr); +} + +SBCommandInterpreter::SBCommandInterpreter(const SBCommandInterpreter &rhs) : + m_opaque_ptr (rhs.m_opaque_ptr) +{ +} + +const SBCommandInterpreter & +SBCommandInterpreter::operator = (const SBCommandInterpreter &rhs) +{ + m_opaque_ptr = rhs.m_opaque_ptr; + return *this; +} + +SBCommandInterpreter::~SBCommandInterpreter () +{ +} + +bool +SBCommandInterpreter::IsValid() const +{ + return m_opaque_ptr != NULL; +} + + +bool +SBCommandInterpreter::CommandExists (const char *cmd) +{ + if (cmd && m_opaque_ptr) + return m_opaque_ptr->CommandExists (cmd); + return false; +} + +bool +SBCommandInterpreter::AliasExists (const char *cmd) +{ + if (cmd && m_opaque_ptr) + return m_opaque_ptr->AliasExists (cmd); + return false; +} + +lldb::ReturnStatus +SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p), add_to_history=%i)", + m_opaque_ptr, command_line, result.get(), add_to_history); + + result.Clear(); + if (command_line && m_opaque_ptr) + { + m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref()); + } + else + { + result->AppendError ("SBCommandInterpreter or the command line is not valid"); + result->SetStatus (eReturnStatusFailed); + } + + // We need to get the value again, in case the command disabled the log! + log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); + if (log) + { + SBStream sstr; + result.GetDescription (sstr); + log->Printf ("SBCommandInterpreter(%p)::HandleCommand (command=\"%s\", SBCommandReturnObject(%p): %s, add_to_history=%i) => %i", + m_opaque_ptr, command_line, result.get(), sstr.GetData(), add_to_history, result.GetStatus()); + } + + return result.GetStatus(); +} + +int +SBCommandInterpreter::HandleCompletion (const char *current_line, + const char *cursor, + const char *last_char, + int match_start_point, + int max_return_elements, + SBStringList &matches) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + int num_completions = 0; + + // Sanity check the arguments that are passed in: + // cursor & last_char have to be within the current_line. + if (current_line == NULL || cursor == NULL || last_char == NULL) + return 0; + + if (cursor < current_line || last_char < current_line) + return 0; + + size_t current_line_size = strlen (current_line); + if (cursor - current_line > current_line_size || last_char - current_line > current_line_size) + return 0; + + if (log) + log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %" PRId64 ", last char at: %" PRId64 ", match_start_point: %d, max_return_elements: %d)", + m_opaque_ptr, current_line, (uint64_t) (cursor - current_line), (uint64_t) (last_char - current_line), match_start_point, max_return_elements); + + if (m_opaque_ptr) + { + lldb_private::StringList lldb_matches; + num_completions = m_opaque_ptr->HandleCompletion (current_line, cursor, last_char, match_start_point, + max_return_elements, lldb_matches); + + SBStringList temp_list (&lldb_matches); + matches.AppendList (temp_list); + } + if (log) + log->Printf ("SBCommandInterpreter(%p)::HandleCompletion - Found %d completions.", m_opaque_ptr, num_completions); + + return num_completions; +} + +int +SBCommandInterpreter::HandleCompletion (const char *current_line, + uint32_t cursor_pos, + int match_start_point, + int max_return_elements, + lldb::SBStringList &matches) +{ + const char *cursor = current_line + cursor_pos; + const char *last_char = current_line + strlen (current_line); + return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches); +} + +bool +SBCommandInterpreter::HasCommands () +{ + if (m_opaque_ptr) + return m_opaque_ptr->HasCommands(); + return false; +} + +bool +SBCommandInterpreter::HasAliases () +{ + if (m_opaque_ptr) + return m_opaque_ptr->HasAliases(); + return false; +} + +bool +SBCommandInterpreter::HasAliasOptions () +{ + if (m_opaque_ptr) + return m_opaque_ptr->HasAliasOptions (); + return false; +} + +SBProcess +SBCommandInterpreter::GetProcess () +{ + SBProcess sb_process; + ProcessSP process_sp; + if (m_opaque_ptr) + { + TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); + if (target_sp) + { + Mutex::Locker api_locker(target_sp->GetAPIMutex()); + process_sp = target_sp->GetProcessSP(); + sb_process.SetSP(process_sp); + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBCommandInterpreter(%p)::GetProcess () => SBProcess(%p)", + m_opaque_ptr, process_sp.get()); + + + return sb_process; +} + +SBDebugger +SBCommandInterpreter::GetDebugger () +{ + SBDebugger sb_debugger; + if (m_opaque_ptr) + sb_debugger.reset(m_opaque_ptr->GetDebugger().shared_from_this()); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBCommandInterpreter(%p)::GetDebugger () => SBDebugger(%p)", + m_opaque_ptr, sb_debugger.get()); + + + return sb_debugger; +} + +CommandInterpreter * +SBCommandInterpreter::get () +{ + return m_opaque_ptr; +} + +CommandInterpreter & +SBCommandInterpreter::ref () +{ + assert (m_opaque_ptr); + return *m_opaque_ptr; +} + +void +SBCommandInterpreter::reset (lldb_private::CommandInterpreter *interpreter) +{ + m_opaque_ptr = interpreter; +} + +void +SBCommandInterpreter::SourceInitFileInHomeDirectory (SBCommandReturnObject &result) +{ + result.Clear(); + if (m_opaque_ptr) + { + TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); + Mutex::Locker api_locker; + if (target_sp) + api_locker.Lock(target_sp->GetAPIMutex()); + m_opaque_ptr->SourceInitFile (false, result.ref()); + } + else + { + result->AppendError ("SBCommandInterpreter is not valid"); + result->SetStatus (eReturnStatusFailed); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInHomeDirectory (&SBCommandReturnObject(%p))", + m_opaque_ptr, result.get()); + +} + +void +SBCommandInterpreter::SourceInitFileInCurrentWorkingDirectory (SBCommandReturnObject &result) +{ + result.Clear(); + if (m_opaque_ptr) + { + TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget()); + Mutex::Locker api_locker; + if (target_sp) + api_locker.Lock(target_sp->GetAPIMutex()); + m_opaque_ptr->SourceInitFile (true, result.ref()); + } + else + { + result->AppendError ("SBCommandInterpreter is not valid"); + result->SetStatus (eReturnStatusFailed); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBCommandInterpreter(%p)::SourceInitFileInCurrentWorkingDirectory (&SBCommandReturnObject(%p))", + m_opaque_ptr, result.get()); +} + +SBBroadcaster +SBCommandInterpreter::GetBroadcaster () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBroadcaster broadcaster (m_opaque_ptr, false); + + if (log) + log->Printf ("SBCommandInterpreter(%p)::GetBroadcaster() => SBBroadcaster(%p)", + m_opaque_ptr, broadcaster.get()); + + return broadcaster; +} + +const char * +SBCommandInterpreter::GetBroadcasterClass () +{ + return Communication::GetStaticBroadcasterClass().AsCString(); +} + +const char * +SBCommandInterpreter::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type) +{ + return CommandObject::GetArgumentTypeAsCString (arg_type); +} + +const char * +SBCommandInterpreter::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type) +{ + return CommandObject::GetArgumentDescriptionAsCString (arg_type); +} + +bool +SBCommandInterpreter::SetCommandOverrideCallback (const char *command_name, + lldb::CommandOverrideCallback callback, + void *baton) +{ + if (command_name && command_name[0] && m_opaque_ptr) + { + std::string command_name_str (command_name); + CommandObject *cmd_obj = m_opaque_ptr->GetCommandObjectForCommand(command_name_str); + if (cmd_obj) + { + assert(command_name_str.empty()); + cmd_obj->SetOverrideCallback (callback, baton); + return true; + } + } + return false; +} + +#ifndef LLDB_DISABLE_PYTHON + +// Defined in the SWIG source file +extern "C" void +init_lldb(void); + +#else + +extern "C" void init_lldb(void); + +// Usually defined in the SWIG source file, but we have sripting disabled +extern "C" void +init_lldb(void) +{ +} + +#endif + +void +SBCommandInterpreter::InitializeSWIG () +{ + static bool g_initialized = false; + if (!g_initialized) + { + g_initialized = true; +#ifndef LLDB_DISABLE_PYTHON + ScriptInterpreter::InitializeInterpreter (init_lldb); +#endif + } +} + +lldb::SBCommand +SBCommandInterpreter::AddMultiwordCommand (const char* name, const char* help) +{ + CommandObjectMultiword *new_command = new CommandObjectMultiword(*m_opaque_ptr,name,help); + new_command->SetRemovable (true); + lldb::CommandObjectSP new_command_sp(new_command); + if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) + return lldb::SBCommand(new_command_sp); + return lldb::SBCommand(); +} + +lldb::SBCommand +SBCommandInterpreter::AddCommand (const char* name, lldb::SBCommandPluginInterface* impl, const char* help) +{ + lldb::CommandObjectSP new_command_sp; + new_command_sp.reset(new CommandPluginInterfaceImplementation(*m_opaque_ptr,name,impl,help)); + + if (new_command_sp && m_opaque_ptr->AddUserCommand(name, new_command_sp, true)) + return lldb::SBCommand(new_command_sp); + return lldb::SBCommand(); +} + +SBCommand::SBCommand () +{} + +SBCommand::SBCommand (lldb::CommandObjectSP cmd_sp) : m_opaque_sp (cmd_sp) +{} + +bool +SBCommand::IsValid () +{ + return (bool)m_opaque_sp; +} + +const char* +SBCommand::GetName () +{ + if (IsValid ()) + return m_opaque_sp->GetCommandName (); + return NULL; +} + +const char* +SBCommand::GetHelp () +{ + if (IsValid ()) + return m_opaque_sp->GetHelp (); + return NULL; +} + +lldb::SBCommand +SBCommand::AddMultiwordCommand (const char* name, const char* help) +{ + if (!IsValid ()) + return lldb::SBCommand(); + if (m_opaque_sp->IsMultiwordObject() == false) + return lldb::SBCommand(); + CommandObjectMultiword *new_command = new CommandObjectMultiword(m_opaque_sp->GetCommandInterpreter(),name,help); + new_command->SetRemovable (true); + lldb::CommandObjectSP new_command_sp(new_command); + if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp)) + return lldb::SBCommand(new_command_sp); + return lldb::SBCommand(); +} + +lldb::SBCommand +SBCommand::AddCommand (const char* name, lldb::SBCommandPluginInterface *impl, const char* help) +{ + if (!IsValid ()) + return lldb::SBCommand(); + if (m_opaque_sp->IsMultiwordObject() == false) + return lldb::SBCommand(); + lldb::CommandObjectSP new_command_sp; + new_command_sp.reset(new CommandPluginInterfaceImplementation(m_opaque_sp->GetCommandInterpreter(),name,impl,help)); + if (new_command_sp && m_opaque_sp->LoadSubCommand(name,new_command_sp)) + return lldb::SBCommand(new_command_sp); + return lldb::SBCommand(); +} + diff --git a/source/API/SBCommandReturnObject.cpp b/source/API/SBCommandReturnObject.cpp new file mode 100644 index 000000000000..83d65637d3f2 --- /dev/null +++ b/source/API/SBCommandReturnObject.cpp @@ -0,0 +1,352 @@ +//===-- SBCommandReturnObject.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/SBCommandReturnObject.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBStream.h" + +#include "lldb/Core/Error.h" +#include "lldb/Core/Log.h" +#include "lldb/Interpreter/CommandReturnObject.h" + +using namespace lldb; +using namespace lldb_private; + +SBCommandReturnObject::SBCommandReturnObject () : + m_opaque_ap (new CommandReturnObject ()) +{ +} + +SBCommandReturnObject::SBCommandReturnObject (const SBCommandReturnObject &rhs): + m_opaque_ap () +{ + if (rhs.m_opaque_ap.get()) + m_opaque_ap.reset (new CommandReturnObject (*rhs.m_opaque_ap)); +} + +SBCommandReturnObject::SBCommandReturnObject (CommandReturnObject *ptr) : + m_opaque_ap (ptr) +{ +} + +CommandReturnObject * +SBCommandReturnObject::Release () +{ + return m_opaque_ap.release(); +} + +const SBCommandReturnObject & +SBCommandReturnObject::operator = (const SBCommandReturnObject &rhs) +{ + if (this != &rhs) + { + if (rhs.m_opaque_ap.get()) + m_opaque_ap.reset (new CommandReturnObject (*rhs.m_opaque_ap)); + else + m_opaque_ap.reset(); + } + return *this; +} + + +SBCommandReturnObject::~SBCommandReturnObject () +{ + // m_opaque_ap will automatically delete any pointer it owns +} + +bool +SBCommandReturnObject::IsValid() const +{ + return m_opaque_ap.get() != NULL; +} + + +const char * +SBCommandReturnObject::GetOutput () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (m_opaque_ap.get()) + { + if (log) + log->Printf ("SBCommandReturnObject(%p)::GetOutput () => \"%s\"", m_opaque_ap.get(), + m_opaque_ap->GetOutputData()); + + return m_opaque_ap->GetOutputData(); + } + + if (log) + log->Printf ("SBCommandReturnObject(%p)::GetOutput () => NULL", m_opaque_ap.get()); + + return NULL; +} + +const char * +SBCommandReturnObject::GetError () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (m_opaque_ap.get()) + { + if (log) + log->Printf ("SBCommandReturnObject(%p)::GetError () => \"%s\"", m_opaque_ap.get(), + m_opaque_ap->GetErrorData()); + + return m_opaque_ap->GetErrorData(); + } + + if (log) + log->Printf ("SBCommandReturnObject(%p)::GetError () => NULL", m_opaque_ap.get()); + + return NULL; +} + +size_t +SBCommandReturnObject::GetOutputSize () +{ + if (m_opaque_ap.get()) + return strlen (m_opaque_ap->GetOutputData()); + return 0; +} + +size_t +SBCommandReturnObject::GetErrorSize () +{ + if (m_opaque_ap.get()) + return strlen(m_opaque_ap->GetErrorData()); + return 0; +} + +size_t +SBCommandReturnObject::PutOutput (FILE *fh) +{ + if (fh) + { + size_t num_bytes = GetOutputSize (); + if (num_bytes) + return ::fprintf (fh, "%s", GetOutput()); + } + return 0; +} + +size_t +SBCommandReturnObject::PutError (FILE *fh) +{ + if (fh) + { + size_t num_bytes = GetErrorSize (); + if (num_bytes) + return ::fprintf (fh, "%s", GetError()); + } + return 0; +} + +void +SBCommandReturnObject::Clear() +{ + if (m_opaque_ap.get()) + m_opaque_ap->Clear(); +} + +lldb::ReturnStatus +SBCommandReturnObject::GetStatus() +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetStatus(); + return lldb::eReturnStatusInvalid; +} + +void +SBCommandReturnObject::SetStatus(lldb::ReturnStatus status) +{ + if (m_opaque_ap.get()) + m_opaque_ap->SetStatus(status); +} + +bool +SBCommandReturnObject::Succeeded () +{ + if (m_opaque_ap.get()) + return m_opaque_ap->Succeeded(); + return false; +} + +bool +SBCommandReturnObject::HasResult () +{ + if (m_opaque_ap.get()) + return m_opaque_ap->HasResult(); + return false; +} + +void +SBCommandReturnObject::AppendMessage (const char *message) +{ + if (m_opaque_ap.get()) + m_opaque_ap->AppendMessage (message); +} + +void +SBCommandReturnObject::AppendWarning (const char *message) +{ + if (m_opaque_ap.get()) + m_opaque_ap->AppendWarning (message); +} + +CommandReturnObject * +SBCommandReturnObject::operator ->() const +{ + return m_opaque_ap.get(); +} + +CommandReturnObject * +SBCommandReturnObject::get() const +{ + return m_opaque_ap.get(); +} + +CommandReturnObject & +SBCommandReturnObject::operator *() const +{ + assert(m_opaque_ap.get()); + return *(m_opaque_ap.get()); +} + + +CommandReturnObject & +SBCommandReturnObject::ref() const +{ + assert(m_opaque_ap.get()); + return *(m_opaque_ap.get()); +} + + +void +SBCommandReturnObject::SetLLDBObjectPtr (CommandReturnObject *ptr) +{ + if (m_opaque_ap.get()) + m_opaque_ap.reset (ptr); +} + +bool +SBCommandReturnObject::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + if (m_opaque_ap.get()) + { + description.Printf ("Status: "); + lldb::ReturnStatus status = m_opaque_ap->GetStatus(); + if (status == lldb::eReturnStatusStarted) + strm.PutCString ("Started"); + else if (status == lldb::eReturnStatusInvalid) + strm.PutCString ("Invalid"); + else if (m_opaque_ap->Succeeded()) + strm.PutCString ("Success"); + else + strm.PutCString ("Fail"); + + if (GetOutputSize() > 0) + strm.Printf ("\nOutput Message:\n%s", GetOutput()); + + if (GetErrorSize() > 0) + strm.Printf ("\nError Message:\n%s", GetError()); + } + else + strm.PutCString ("No value"); + + return true; +} + +void +SBCommandReturnObject::SetImmediateOutputFile (FILE *fh) +{ + if (m_opaque_ap.get()) + m_opaque_ap->SetImmediateOutputFile (fh); +} + +void +SBCommandReturnObject::SetImmediateErrorFile (FILE *fh) +{ + if (m_opaque_ap.get()) + m_opaque_ap->SetImmediateErrorFile (fh); +} + +void +SBCommandReturnObject::PutCString(const char* string, int len) +{ + if (m_opaque_ap.get()) + { + if (len == 0 || string == NULL || *string == 0) + { + return; + } + else if (len > 0) + { + std::string buffer(string, len); + m_opaque_ap->AppendMessage(buffer.c_str()); + } + else + m_opaque_ap->AppendMessage(string); + } +} + +const char * +SBCommandReturnObject::GetOutput (bool only_if_no_immediate) +{ + if (!m_opaque_ap.get()) + return NULL; + if (only_if_no_immediate == false || m_opaque_ap->GetImmediateOutputStream().get() == NULL) + return GetOutput(); + return NULL; +} + +const char * +SBCommandReturnObject::GetError (bool only_if_no_immediate) +{ + if (!m_opaque_ap.get()) + return NULL; + if (only_if_no_immediate == false || m_opaque_ap->GetImmediateErrorStream().get() == NULL) + return GetError(); + return NULL; +} + +size_t +SBCommandReturnObject::Printf(const char* format, ...) +{ + if (m_opaque_ap.get()) + { + va_list args; + va_start (args, format); + size_t result = m_opaque_ap->GetOutputStream().PrintfVarArg(format, args); + va_end (args); + return result; + } + return 0; +} + +void +SBCommandReturnObject::SetError (lldb::SBError &error, const char *fallback_error_cstr) +{ + if (m_opaque_ap.get()) + { + if (error.IsValid()) + m_opaque_ap->SetError(error.ref(), fallback_error_cstr); + else if (fallback_error_cstr) + m_opaque_ap->SetError(Error(), fallback_error_cstr); + } +} + +void +SBCommandReturnObject::SetError (const char *error_cstr) +{ + if (m_opaque_ap.get() && error_cstr) + m_opaque_ap->SetError(error_cstr); +} + diff --git a/source/API/SBCommunication.cpp b/source/API/SBCommunication.cpp new file mode 100644 index 000000000000..10feae5d4ebb --- /dev/null +++ b/source/API/SBCommunication.cpp @@ -0,0 +1,285 @@ +//===-- SBCommunication.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/SBCommunication.h" +#include "lldb/API/SBBroadcaster.h" +#include "lldb/Core/Communication.h" +#include "lldb/Core/ConnectionFileDescriptor.h" +#include "lldb/Core/Log.h" + +using namespace lldb; +using namespace lldb_private; + + + +SBCommunication::SBCommunication() : + m_opaque (NULL), + m_opaque_owned (false) +{ +} + +SBCommunication::SBCommunication(const char * broadcaster_name) : + m_opaque (new Communication (broadcaster_name)), + m_opaque_owned (true) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBCommunication::SBCommunication (broadcaster_name=\"%s\") => " + "SBCommunication(%p)", broadcaster_name, m_opaque); +} + +SBCommunication::~SBCommunication() +{ + if (m_opaque && m_opaque_owned) + delete m_opaque; + m_opaque = NULL; + m_opaque_owned = false; +} + +bool +SBCommunication::IsValid () const +{ + return m_opaque != NULL; +} + +bool +SBCommunication::GetCloseOnEOF () +{ + if (m_opaque) + return m_opaque->GetCloseOnEOF (); + return false; +} + +void +SBCommunication::SetCloseOnEOF (bool b) +{ + if (m_opaque) + m_opaque->SetCloseOnEOF (b); +} + +ConnectionStatus +SBCommunication::Connect (const char *url) +{ + if (m_opaque) + { + if (!m_opaque->HasConnection ()) + m_opaque->SetConnection (new ConnectionFileDescriptor()); + return m_opaque->Connect (url, NULL); + } + return eConnectionStatusNoConnection; +} + +ConnectionStatus +SBCommunication::AdoptFileDesriptor (int fd, bool owns_fd) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ConnectionStatus status = eConnectionStatusNoConnection; + if (m_opaque) + { + if (m_opaque->HasConnection ()) + { + if (m_opaque->IsConnected()) + m_opaque->Disconnect(); + } + m_opaque->SetConnection (new ConnectionFileDescriptor (fd, owns_fd)); + if (m_opaque->IsConnected()) + status = eConnectionStatusSuccess; + else + status = eConnectionStatusLostConnection; + } + + if (log) + log->Printf ("SBCommunication(%p)::AdoptFileDescriptor (fd=%d, ownd_fd=%i) => %s", + m_opaque, fd, owns_fd, Communication::ConnectionStatusAsCString (status)); + + return status; +} + + +ConnectionStatus +SBCommunication::Disconnect () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ConnectionStatus status= eConnectionStatusNoConnection; + if (m_opaque) + status = m_opaque->Disconnect (); + + if (log) + log->Printf ("SBCommunication(%p)::Disconnect () => %s", m_opaque, + Communication::ConnectionStatusAsCString (status)); + + return status; +} + +bool +SBCommunication::IsConnected () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool result = false; + if (m_opaque) + result = m_opaque->IsConnected (); + + if (log) + log->Printf ("SBCommunication(%p)::IsConnected () => %i", m_opaque, result); + + return false; +} + +size_t +SBCommunication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 ", timeout_usec=%u, &status)...", + m_opaque, + dst, + (uint64_t)dst_len, + timeout_usec); + size_t bytes_read = 0; + if (m_opaque) + bytes_read = m_opaque->Read (dst, dst_len, timeout_usec, status, NULL); + else + status = eConnectionStatusNoConnection; + + if (log) + log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 ", timeout_usec=%u, &status=%s) => %" PRIu64, + m_opaque, + dst, + (uint64_t)dst_len, + timeout_usec, + Communication::ConnectionStatusAsCString (status), + (uint64_t)bytes_read); + return bytes_read; +} + + +size_t +SBCommunication::Write (const void *src, size_t src_len, ConnectionStatus &status) +{ + size_t bytes_written = 0; + if (m_opaque) + bytes_written = m_opaque->Write (src, src_len, status, NULL); + else + status = eConnectionStatusNoConnection; + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBCommunication(%p)::Write (src=%p, src_len=%" PRIu64 ", &status=%s) => %" PRIu64, + m_opaque, src, (uint64_t)src_len, Communication::ConnectionStatusAsCString (status), (uint64_t)bytes_written); + + return 0; +} + +bool +SBCommunication::ReadThreadStart () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool success = false; + if (m_opaque) + success = m_opaque->StartReadThread (); + + if (log) + log->Printf ("SBCommunication(%p)::ReadThreadStart () => %i", m_opaque, success); + + return success; +} + + +bool +SBCommunication::ReadThreadStop () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBCommunication(%p)::ReadThreadStop ()...", m_opaque); + + bool success = false; + if (m_opaque) + success = m_opaque->StopReadThread (); + + if (log) + log->Printf ("SBCommunication(%p)::ReadThreadStop () => %i", m_opaque, success); + + return success; +} + +bool +SBCommunication::ReadThreadIsRunning () +{ + bool result = false; + if (m_opaque) + result = m_opaque->ReadThreadIsRunning (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBCommunication(%p)::ReadThreadIsRunning () => %i", m_opaque, result); + return result; +} + +bool +SBCommunication::SetReadThreadBytesReceivedCallback +( + ReadThreadBytesReceived callback, + void *callback_baton +) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool result = false; + if (m_opaque) + { + m_opaque->SetReadThreadBytesReceivedCallback (callback, callback_baton); + result = true; + } + + if (log) + log->Printf ("SBCommunication(%p)::SetReadThreadBytesReceivedCallback (callback=%p, baton=%p) => %i", + m_opaque, callback, callback_baton, result); + + return result; +} + +SBBroadcaster +SBCommunication::GetBroadcaster () +{ + SBBroadcaster broadcaster (m_opaque, false); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBCommunication(%p)::GetBroadcaster () => SBBroadcaster (%p)", + m_opaque, broadcaster.get()); + + return broadcaster; +} + +const char * +SBCommunication::GetBroadcasterClass () +{ + return Communication::GetStaticBroadcasterClass().AsCString(); +} + +// +//void +//SBCommunication::CreateIfNeeded () +//{ +// if (m_opaque == NULL) +// { +// static uint32_t g_broadcaster_num; +// char broadcaster_name[256]; +// ::snprintf (name, broadcaster_name, "%p SBCommunication", this); +// m_opaque = new Communication (broadcaster_name); +// m_opaque_owned = true; +// } +// assert (m_opaque); +//} +// +// diff --git a/source/API/SBCompileUnit.cpp b/source/API/SBCompileUnit.cpp new file mode 100644 index 000000000000..9f7487746a85 --- /dev/null +++ b/source/API/SBCompileUnit.cpp @@ -0,0 +1,278 @@ +//===-- SBCompileUnit.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/SBCompileUnit.h" +#include "lldb/API/SBLineEntry.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/LineEntry.h" +#include "lldb/Symbol/LineTable.h" +#include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/Type.h" + +using namespace lldb; +using namespace lldb_private; + + +SBCompileUnit::SBCompileUnit () : + m_opaque_ptr (NULL) +{ +} + +SBCompileUnit::SBCompileUnit (lldb_private::CompileUnit *lldb_object_ptr) : + m_opaque_ptr (lldb_object_ptr) +{ +} + +SBCompileUnit::SBCompileUnit(const SBCompileUnit &rhs) : + m_opaque_ptr (rhs.m_opaque_ptr) +{ +} + +const SBCompileUnit & +SBCompileUnit::operator = (const SBCompileUnit &rhs) +{ + m_opaque_ptr = rhs.m_opaque_ptr; + return *this; +} + + +SBCompileUnit::~SBCompileUnit () +{ + m_opaque_ptr = NULL; +} + +SBFileSpec +SBCompileUnit::GetFileSpec () const +{ + SBFileSpec file_spec; + if (m_opaque_ptr) + file_spec.SetFileSpec(*m_opaque_ptr); + return file_spec; +} + +uint32_t +SBCompileUnit::GetNumLineEntries () const +{ + if (m_opaque_ptr) + { + LineTable *line_table = m_opaque_ptr->GetLineTable (); + if (line_table) + return line_table->GetSize(); + } + return 0; +} + +SBLineEntry +SBCompileUnit::GetLineEntryAtIndex (uint32_t idx) const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBLineEntry sb_line_entry; + if (m_opaque_ptr) + { + LineTable *line_table = m_opaque_ptr->GetLineTable (); + if (line_table) + { + LineEntry line_entry; + if (line_table->GetLineEntryAtIndex(idx, line_entry)) + sb_line_entry.SetLineEntry(line_entry); + } + } + + if (log) + { + SBStream sstr; + sb_line_entry.GetDescription (sstr); + log->Printf ("SBCompileUnit(%p)::GetLineEntryAtIndex (idx=%u) => SBLineEntry(%p): '%s'", + m_opaque_ptr, idx, sb_line_entry.get(), sstr.GetData()); + } + + return sb_line_entry; +} + +uint32_t +SBCompileUnit::FindLineEntryIndex (uint32_t start_idx, uint32_t line, SBFileSpec *inline_file_spec) const +{ + const bool exact = true; + return FindLineEntryIndex (start_idx, line, inline_file_spec, exact); +} + +uint32_t +SBCompileUnit::FindLineEntryIndex (uint32_t start_idx, uint32_t line, SBFileSpec *inline_file_spec, bool exact) const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t index = UINT32_MAX; + if (m_opaque_ptr) + { + FileSpec file_spec; + if (inline_file_spec && inline_file_spec->IsValid()) + file_spec = inline_file_spec->ref(); + else + file_spec = *m_opaque_ptr; + + + index = m_opaque_ptr->FindLineEntry (start_idx, + line, + inline_file_spec ? inline_file_spec->get() : NULL, + exact, + NULL); + } + + if (log) + { + SBStream sstr; + if (index == UINT32_MAX) + { + log->Printf ("SBCompileUnit(%p)::FindLineEntryIndex (start_idx=%u, line=%u, SBFileSpec(%p)) => NOT FOUND", + m_opaque_ptr, start_idx, line, inline_file_spec ? inline_file_spec->get() : NULL); + } + else + { + log->Printf ("SBCompileUnit(%p)::FindLineEntryIndex (start_idx=%u, line=%u, SBFileSpec(%p)) => %u", + m_opaque_ptr, start_idx, line, inline_file_spec ? inline_file_spec->get() : NULL, index); + } + } + + return index; +} + +uint32_t +SBCompileUnit::GetNumSupportFiles () const +{ + if (m_opaque_ptr) + { + FileSpecList& support_files = m_opaque_ptr->GetSupportFiles (); + return support_files.GetSize(); + } + return 0; +} + + + +lldb::SBTypeList +SBCompileUnit::GetTypes (uint32_t type_mask) +{ + SBTypeList sb_type_list; + + if (m_opaque_ptr) + { + ModuleSP module_sp (m_opaque_ptr->GetModule()); + if (module_sp) + { + SymbolVendor* vendor = module_sp->GetSymbolVendor(); + if (vendor) + { + TypeList type_list; + vendor->GetTypes (m_opaque_ptr, type_mask, type_list); + sb_type_list.m_opaque_ap->Append(type_list); + } + } + } + return sb_type_list; +} + + + + +SBFileSpec +SBCompileUnit::GetSupportFileAtIndex (uint32_t idx) const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBFileSpec sb_file_spec; + if (m_opaque_ptr) + { + FileSpecList &support_files = m_opaque_ptr->GetSupportFiles (); + FileSpec file_spec = support_files.GetFileSpecAtIndex(idx); + sb_file_spec.SetFileSpec(file_spec); + } + + if (log) + { + SBStream sstr; + sb_file_spec.GetDescription (sstr); + log->Printf ("SBCompileUnit(%p)::GetGetFileSpecAtIndex (idx=%u) => SBFileSpec(%p): '%s'", + m_opaque_ptr, idx, sb_file_spec.get(), sstr.GetData()); + } + + return sb_file_spec; +} + +uint32_t +SBCompileUnit::FindSupportFileIndex (uint32_t start_idx, const SBFileSpec &sb_file, bool full) +{ + if (m_opaque_ptr) + { + FileSpecList &support_files = m_opaque_ptr->GetSupportFiles (); + return support_files.FindFileIndex(start_idx, sb_file.ref(), full); + } + return 0; +} + +bool +SBCompileUnit::IsValid () const +{ + return m_opaque_ptr != NULL; +} + +bool +SBCompileUnit::operator == (const SBCompileUnit &rhs) const +{ + return m_opaque_ptr == rhs.m_opaque_ptr; +} + +bool +SBCompileUnit::operator != (const SBCompileUnit &rhs) const +{ + return m_opaque_ptr != rhs.m_opaque_ptr; +} + +const lldb_private::CompileUnit * +SBCompileUnit::operator->() const +{ + return m_opaque_ptr; +} + +const lldb_private::CompileUnit & +SBCompileUnit::operator*() const +{ + return *m_opaque_ptr; +} + +lldb_private::CompileUnit * +SBCompileUnit::get () +{ + return m_opaque_ptr; +} + +void +SBCompileUnit::reset (lldb_private::CompileUnit *lldb_object_ptr) +{ + m_opaque_ptr = lldb_object_ptr; +} + + +bool +SBCompileUnit::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + if (m_opaque_ptr) + { + m_opaque_ptr->Dump (&strm, false); + } + else + strm.PutCString ("No value"); + + return true; +} diff --git a/source/API/SBData.cpp b/source/API/SBData.cpp new file mode 100644 index 000000000000..5b2f075158b8 --- /dev/null +++ b/source/API/SBData.cpp @@ -0,0 +1,785 @@ +//===-- SBData.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/SBData.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBStream.h" + +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" + + +using namespace lldb; +using namespace lldb_private; + +SBData::SBData () : + m_opaque_sp(new DataExtractor()) +{ +} + +SBData::SBData (const lldb::DataExtractorSP& data_sp) : + m_opaque_sp (data_sp) +{ +} + +SBData::SBData(const SBData &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +const SBData & +SBData::operator = (const SBData &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +SBData::~SBData () +{ +} + +void +SBData::SetOpaque (const lldb::DataExtractorSP &data_sp) +{ + m_opaque_sp = data_sp; +} + +lldb_private::DataExtractor * +SBData::get() const +{ + return m_opaque_sp.get(); +} + +lldb_private::DataExtractor * +SBData::operator->() const +{ + return m_opaque_sp.operator->(); +} + +lldb::DataExtractorSP & +SBData::operator*() +{ + return m_opaque_sp; +} + +const lldb::DataExtractorSP & +SBData::operator*() const +{ + return m_opaque_sp; +} + +bool +SBData::IsValid() +{ + return m_opaque_sp.get() != NULL; +} + +uint8_t +SBData::GetAddressByteSize () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint8_t value = 0; + if (m_opaque_sp.get()) + value = m_opaque_sp->GetAddressByteSize(); + if (log) + log->Printf ("SBData::GetAddressByteSize () => " + "(%i)", value); + return value; +} + +void +SBData::SetAddressByteSize (uint8_t addr_byte_size) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (m_opaque_sp.get()) + m_opaque_sp->SetAddressByteSize(addr_byte_size); + if (log) + log->Printf ("SBData::SetAddressByteSize (%i)", addr_byte_size); +} + +void +SBData::Clear () +{ + if (m_opaque_sp.get()) + m_opaque_sp->Clear(); +} + +size_t +SBData::GetByteSize () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + size_t value = 0; + if (m_opaque_sp.get()) + value = m_opaque_sp->GetByteSize(); + if (log) + log->Printf ("SBData::GetByteSize () => " + "(%lu)", value); + return value; +} + +lldb::ByteOrder +SBData::GetByteOrder () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::ByteOrder value = eByteOrderInvalid; + if (m_opaque_sp.get()) + value = m_opaque_sp->GetByteOrder(); + if (log) + log->Printf ("SBData::GetByteOrder () => " + "(%i)", value); + return value; +} + +void +SBData::SetByteOrder (lldb::ByteOrder endian) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (m_opaque_sp.get()) + m_opaque_sp->SetByteOrder(endian); + if (log) + log->Printf ("SBData::GetByteOrder (%i)", endian); +} + + +float +SBData::GetFloat (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + float value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetFloat(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetFloat (error=%p,offset=%" PRIu64 ") => " + "(%f)", error.get(), offset, value); + return value; +} + +double +SBData::GetDouble (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + double value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetDouble(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetDouble (error=%p,offset=%" PRIu64 ") => " + "(%f)", error.get(), offset, value); + return value; +} + +long double +SBData::GetLongDouble (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + long double value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetLongDouble(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetLongDouble (error=%p,offset=%" PRIu64 ") => " + "(%Lf)", error.get(), offset, value); + return value; +} + +lldb::addr_t +SBData::GetAddress (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::addr_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetAddress(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetAddress (error=%p,offset=%" PRIu64 ") => " + "(%p)", error.get(), offset, (void*)value); + return value; +} + +uint8_t +SBData::GetUnsignedInt8 (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint8_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetU8(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetUnsignedInt8 (error=%p,offset=%" PRIu64 ") => " + "(%c)", error.get(), offset, value); + return value; +} + +uint16_t +SBData::GetUnsignedInt16 (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint16_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetU16(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetUnsignedInt16 (error=%p,offset=%" PRIu64 ") => " + "(%hd)", error.get(), offset, value); + return value; +} + +uint32_t +SBData::GetUnsignedInt32 (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint32_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetU32(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetUnsignedInt32 (error=%p,offset=%" PRIu64 ") => " + "(%d)", error.get(), offset, value); + return value; +} + +uint64_t +SBData::GetUnsignedInt64 (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + uint64_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetU64(&offset); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetUnsignedInt64 (error=%p,offset=%" PRIu64 ") => " + "(%" PRId64 ")", error.get(), offset, value); + return value; +} + +int8_t +SBData::GetSignedInt8 (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + int8_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = (int8_t)m_opaque_sp->GetMaxS64(&offset, 1); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetSignedInt8 (error=%p,offset=%" PRIu64 ") => " + "(%c)", error.get(), offset, value); + return value; +} + +int16_t +SBData::GetSignedInt16 (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + int16_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = (int16_t)m_opaque_sp->GetMaxS64(&offset, 2); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetSignedInt16 (error=%p,offset=%" PRIu64 ") => " + "(%hd)", error.get(), offset, value); + return value; +} + +int32_t +SBData::GetSignedInt32 (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + int32_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = (int32_t)m_opaque_sp->GetMaxS64(&offset, 4); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetSignedInt32 (error=%p,offset=%" PRIu64 ") => " + "(%d)", error.get(), offset, value); + return value; +} + +int64_t +SBData::GetSignedInt64 (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + int64_t value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = (int64_t)m_opaque_sp->GetMaxS64(&offset, 8); + if (offset == old_offset) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetSignedInt64 (error=%p,offset=%" PRIu64 ") => " + "(%" PRId64 ")", error.get(), offset, value); + return value; +} + +const char* +SBData::GetString (lldb::SBError& error, lldb::offset_t offset) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char* value = 0; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + value = m_opaque_sp->GetCStr(&offset); + if (offset == old_offset || (value == NULL)) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::GetString (error=%p,offset=%" PRIu64 ") => " + "(%p)", error.get(), offset, value); + return value; +} + +bool +SBData::GetDescription (lldb::SBStream &description, lldb::addr_t base_addr) +{ + Stream &strm = description.ref(); + + if (m_opaque_sp) + { + m_opaque_sp->Dump (&strm, + 0, + lldb::eFormatBytesWithASCII, + 1, + m_opaque_sp->GetByteSize(), + 16, + base_addr, + 0, + 0); + } + else + strm.PutCString ("No value"); + + return true; +} + +size_t +SBData::ReadRawData (lldb::SBError& error, + lldb::offset_t offset, + void *buf, + size_t size) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + void* ok = NULL; + if (!m_opaque_sp.get()) + { + error.SetErrorString("no value to read from"); + } + else + { + uint32_t old_offset = offset; + ok = m_opaque_sp->GetU8(&offset, buf, size); + if ((offset == old_offset) || (ok == NULL)) + error.SetErrorString("unable to read data"); + } + if (log) + log->Printf ("SBData::ReadRawData (error=%p,offset=%" PRIu64 ",buf=%p,size=%lu) => " + "(%p)", error.get(), offset, buf, size, ok); + return ok ? size : 0; +} + +void +SBData::SetData (lldb::SBError& error, + const void *buf, + size_t size, + lldb::ByteOrder endian, + uint8_t addr_size) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (!m_opaque_sp.get()) + m_opaque_sp.reset(new DataExtractor(buf, size, endian, addr_size)); + else + m_opaque_sp->SetData(buf, size, endian); + if (log) + log->Printf ("SBData::SetData (error=%p,buf=%p,size=%lu,endian=%d,addr_size=%c) => " + "(%p)", error.get(), buf, size, endian, addr_size, m_opaque_sp.get()); +} + +bool +SBData::Append (const SBData& rhs) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool value = false; + if (m_opaque_sp.get() && rhs.m_opaque_sp.get()) + value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp); + if (log) + log->Printf ("SBData::Append (rhs=%p) => " + "(%s)", rhs.get(), value ? "true" : "false"); + return value; +} + +lldb::SBData +SBData::CreateDataFromCString (lldb::ByteOrder endian, uint32_t addr_byte_size, const char* data) +{ + if (!data || !data[0]) + return SBData(); + + uint32_t data_len = strlen(data); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBData::CreateDataFromUInt64Array (lldb::ByteOrder endian, uint32_t addr_byte_size, uint64_t* array, size_t array_len) +{ + if (!array || array_len == 0) + return SBData(); + + size_t data_len = array_len * sizeof(uint64_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBData::CreateDataFromUInt32Array (lldb::ByteOrder endian, uint32_t addr_byte_size, uint32_t* array, size_t array_len) +{ + if (!array || array_len == 0) + return SBData(); + + size_t data_len = array_len * sizeof(uint32_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBData::CreateDataFromSInt64Array (lldb::ByteOrder endian, uint32_t addr_byte_size, int64_t* array, size_t array_len) +{ + if (!array || array_len == 0) + return SBData(); + + size_t data_len = array_len * sizeof(int64_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBData::CreateDataFromSInt32Array (lldb::ByteOrder endian, uint32_t addr_byte_size, int32_t* array, size_t array_len) +{ + if (!array || array_len == 0) + return SBData(); + + size_t data_len = array_len * sizeof(int32_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size)); + + SBData ret(data_sp); + + return ret; +} + +lldb::SBData +SBData::CreateDataFromDoubleArray (lldb::ByteOrder endian, uint32_t addr_byte_size, double* array, size_t array_len) +{ + if (!array || array_len == 0) + return SBData(); + + size_t data_len = array_len * sizeof(double); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + lldb::DataExtractorSP data_sp(new DataExtractor(buffer_sp, endian, addr_byte_size)); + + SBData ret(data_sp); + + return ret; +} + +bool +SBData::SetDataFromCString (const char* data) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (!data) + { + if (log) + log->Printf ("SBData::SetDataFromCString (data=%p) => " + "false", data); + return false; + } + + size_t data_len = strlen(data); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(data, data_len)); + + if (!m_opaque_sp.get()) + m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); + else + m_opaque_sp->SetData(buffer_sp); + + if (log) + log->Printf ("SBData::SetDataFromCString (data=%p) => " + "true", data); + + return true; +} + +bool +SBData::SetDataFromUInt64Array (uint64_t* array, size_t array_len) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (!array || array_len == 0) + { + if (log) + log->Printf ("SBData::SetDataFromUInt64Array (array=%p, array_len = %lu) => " + "false", array, array_len); + return false; + } + + size_t data_len = array_len * sizeof(uint64_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + + if (!m_opaque_sp.get()) + m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); + else + m_opaque_sp->SetData(buffer_sp); + + if (log) + log->Printf ("SBData::SetDataFromUInt64Array (array=%p, array_len = %lu) => " + "true", array, array_len); + + return true; +} + +bool +SBData::SetDataFromUInt32Array (uint32_t* array, size_t array_len) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (!array || array_len == 0) + { + if (log) + log->Printf ("SBData::SetDataFromUInt32Array (array=%p, array_len = %lu) => " + "false", array, array_len); + return false; + } + + size_t data_len = array_len * sizeof(uint32_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + + if (!m_opaque_sp.get()) + m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); + else + m_opaque_sp->SetData(buffer_sp); + + if (log) + log->Printf ("SBData::SetDataFromUInt32Array (array=%p, array_len = %lu) => " + "true", array, array_len); + + return true; +} + +bool +SBData::SetDataFromSInt64Array (int64_t* array, size_t array_len) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (!array || array_len == 0) + { + if (log) + log->Printf ("SBData::SetDataFromSInt64Array (array=%p, array_len = %lu) => " + "false", array, array_len); + return false; + } + + size_t data_len = array_len * sizeof(int64_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + + if (!m_opaque_sp.get()) + m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); + else + m_opaque_sp->SetData(buffer_sp); + + if (log) + log->Printf ("SBData::SetDataFromSInt64Array (array=%p, array_len = %lu) => " + "true", array, array_len); + + return true; +} + +bool +SBData::SetDataFromSInt32Array (int32_t* array, size_t array_len) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (!array || array_len == 0) + { + if (log) + log->Printf ("SBData::SetDataFromSInt32Array (array=%p, array_len = %lu) => " + "false", array, array_len); + return false; + } + + size_t data_len = array_len * sizeof(int32_t); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + + if (!m_opaque_sp.get()) + m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); + else + m_opaque_sp->SetData(buffer_sp); + + if (log) + log->Printf ("SBData::SetDataFromSInt32Array (array=%p, array_len = %lu) => " + "true", array, array_len); + + return true; +} + +bool +SBData::SetDataFromDoubleArray (double* array, size_t array_len) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (!array || array_len == 0) + { + if (log) + log->Printf ("SBData::SetDataFromDoubleArray (array=%p, array_len = %lu) => " + "false", array, array_len); + return false; + } + + size_t data_len = array_len * sizeof(double); + + lldb::DataBufferSP buffer_sp(new DataBufferHeap(array, data_len)); + + if (!m_opaque_sp.get()) + m_opaque_sp.reset(new DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize())); + else + m_opaque_sp->SetData(buffer_sp); + + if (log) + log->Printf ("SBData::SetDataFromDoubleArray (array=%p, array_len = %lu) => " + "true", array, array_len); + + return true; +} diff --git a/source/API/SBDebugger.cpp b/source/API/SBDebugger.cpp new file mode 100644 index 000000000000..f5e71d5f1a07 --- /dev/null +++ b/source/API/SBDebugger.cpp @@ -0,0 +1,1264 @@ +//===-- SBDebugger.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/lldb-python.h" + +#include "lldb/API/SBDebugger.h" + +#include "lldb/lldb-private.h" + +#include "lldb/API/SBListener.h" +#include "lldb/API/SBBroadcaster.h" +#include "lldb/API/SBCommandInterpreter.h" +#include "lldb/API/SBCommandReturnObject.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBFrame.h" +#include "lldb/API/SBInputReader.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBSourceManager.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBThread.h" +#include "lldb/API/SBTypeCategory.h" +#include "lldb/API/SBTypeFormat.h" +#include "lldb/API/SBTypeFilter.h" +#include "lldb/API/SBTypeNameSpecifier.h" +#include "lldb/API/SBTypeSummary.h" +#include "lldb/API/SBTypeSynthetic.h" + + +#include "lldb/Core/Debugger.h" +#include "lldb/Core/State.h" +#include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/OptionGroupPlatform.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/TargetList.h" + +using namespace lldb; +using namespace lldb_private; + +void +SBDebugger::Initialize () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger::Initialize ()"); + + SBCommandInterpreter::InitializeSWIG (); + + Debugger::Initialize(); +} + +void +SBDebugger::Terminate () +{ + Debugger::Terminate(); +} + +void +SBDebugger::Clear () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::Clear ()", m_opaque_sp.get()); + + if (m_opaque_sp) + m_opaque_sp->CleanUpInputReaders (); + + m_opaque_sp.reset(); +} + +SBDebugger +SBDebugger::Create() +{ + return SBDebugger::Create(false, NULL, NULL); +} + +SBDebugger +SBDebugger::Create(bool source_init_files) +{ + return SBDebugger::Create (source_init_files, NULL, NULL); +} + +SBDebugger +SBDebugger::Create(bool source_init_files, lldb::LogOutputCallback callback, void *baton) + +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBDebugger debugger; + debugger.reset(Debugger::CreateInstance(callback, baton)); + + if (log) + { + SBStream sstr; + debugger.GetDescription (sstr); + log->Printf ("SBDebugger::Create () => SBDebugger(%p): %s", debugger.m_opaque_sp.get(), sstr.GetData()); + } + + SBCommandInterpreter interp = debugger.GetCommandInterpreter(); + if (source_init_files) + { + interp.get()->SkipLLDBInitFiles(false); + interp.get()->SkipAppInitFiles (false); + SBCommandReturnObject result; + interp.SourceInitFileInHomeDirectory(result); + } + else + { + interp.get()->SkipLLDBInitFiles(true); + interp.get()->SkipAppInitFiles (true); + } + return debugger; +} + +void +SBDebugger::Destroy (SBDebugger &debugger) +{ + Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + { + SBStream sstr; + debugger.GetDescription (sstr); + log->Printf ("SBDebugger::Destroy () => SBDebugger(%p): %s", debugger.m_opaque_sp.get(), sstr.GetData()); + } + + Debugger::Destroy (debugger.m_opaque_sp); + + if (debugger.m_opaque_sp.get() != NULL) + debugger.m_opaque_sp.reset(); +} + +void +SBDebugger::MemoryPressureDetected () +{ + // Since this function can be call asynchronously, we allow it to be + // non-mandatory. We have seen deadlocks with this function when called + // so we need to safeguard against this until we can determine what is + // causing the deadlocks. + Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const bool mandatory = false; + if (log) + { + log->Printf ("SBDebugger::MemoryPressureDetected (), mandatory = %d", mandatory); + } + + ModuleList::RemoveOrphanSharedModules(mandatory); +} + +SBDebugger::SBDebugger () : + m_opaque_sp () +{ +} + +SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp) : + m_opaque_sp(debugger_sp) +{ +} + +SBDebugger::SBDebugger(const SBDebugger &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +SBDebugger & +SBDebugger::operator = (const SBDebugger &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } + return *this; +} + +SBDebugger::~SBDebugger () +{ +} + +bool +SBDebugger::IsValid() const +{ + return m_opaque_sp.get() != NULL; +} + + +void +SBDebugger::SetAsync (bool b) +{ + if (m_opaque_sp) + m_opaque_sp->SetAsyncExecution(b); +} + +bool +SBDebugger::GetAsync () +{ + if (m_opaque_sp) + return m_opaque_sp->GetAsyncExecution(); + else + return false; +} + +void +SBDebugger::SkipLLDBInitFiles (bool b) +{ + if (m_opaque_sp) + m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles (b); +} + +void +SBDebugger::SkipAppInitFiles (bool b) +{ + if (m_opaque_sp) + m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles (b); +} + +// Shouldn't really be settable after initialization as this could cause lots of problems; don't want users +// trying to switch modes in the middle of a debugging session. +void +SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(), + fh, transfer_ownership); + + if (m_opaque_sp) + m_opaque_sp->SetInputFileHandle (fh, transfer_ownership); +} + +void +SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + + if (log) + log->Printf ("SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(), + fh, transfer_ownership); + + if (m_opaque_sp) + m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership); +} + +void +SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + + if (log) + log->Printf ("SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(), + fh, transfer_ownership); + + if (m_opaque_sp) + m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership); +} + +FILE * +SBDebugger::GetInputFileHandle () +{ + if (m_opaque_sp) + return m_opaque_sp->GetInputFile().GetStream(); + return NULL; +} + +FILE * +SBDebugger::GetOutputFileHandle () +{ + if (m_opaque_sp) + return m_opaque_sp->GetOutputFile().GetStream(); + return NULL; +} + +FILE * +SBDebugger::GetErrorFileHandle () +{ + if (m_opaque_sp) + return m_opaque_sp->GetErrorFile().GetStream(); + return NULL; +} + +void +SBDebugger::SaveInputTerminalState() +{ + if (m_opaque_sp) + m_opaque_sp->SaveInputTerminalState(); +} + +void +SBDebugger::RestoreInputTerminalState() +{ + if (m_opaque_sp) + m_opaque_sp->RestoreInputTerminalState(); + +} +SBCommandInterpreter +SBDebugger::GetCommandInterpreter () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBCommandInterpreter sb_interpreter; + if (m_opaque_sp) + sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter()); + + if (log) + log->Printf ("SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)", + m_opaque_sp.get(), sb_interpreter.get()); + + return sb_interpreter; +} + +void +SBDebugger::HandleCommand (const char *command) +{ + if (m_opaque_sp) + { + TargetSP target_sp (m_opaque_sp->GetSelectedTarget()); + Mutex::Locker api_locker; + if (target_sp) + api_locker.Lock(target_sp->GetAPIMutex()); + + SBCommandInterpreter sb_interpreter(GetCommandInterpreter ()); + SBCommandReturnObject result; + + sb_interpreter.HandleCommand (command, result, false); + + if (GetErrorFileHandle() != NULL) + result.PutError (GetErrorFileHandle()); + if (GetOutputFileHandle() != NULL) + result.PutOutput (GetOutputFileHandle()); + + if (m_opaque_sp->GetAsyncExecution() == false) + { + SBProcess process(GetCommandInterpreter().GetProcess ()); + ProcessSP process_sp (process.GetSP()); + if (process_sp) + { + EventSP event_sp; + Listener &lldb_listener = m_opaque_sp->GetListener(); + while (lldb_listener.GetNextEventForBroadcaster (process_sp.get(), event_sp)) + { + SBEvent event(event_sp); + HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle()); + } + } + } + } +} + +SBListener +SBDebugger::GetListener () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBListener sb_listener; + if (m_opaque_sp) + sb_listener.reset(&m_opaque_sp->GetListener(), false); + + if (log) + log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)", m_opaque_sp.get(), + sb_listener.get()); + + return sb_listener; +} + +void +SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err) +{ + if (!process.IsValid()) + return; + + TargetSP target_sp (process.GetTarget().GetSP()); + if (!target_sp) + return; + + const uint32_t event_type = event.GetType(); + char stdio_buffer[1024]; + size_t len; + + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + + if (event_type & (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) + { + // Drain stdout when we stop just in case we have any bytes + while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0) + if (out != NULL) + ::fwrite (stdio_buffer, 1, len, out); + } + + if (event_type & (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) + { + // Drain stderr when we stop just in case we have any bytes + while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0) + if (err != NULL) + ::fwrite (stdio_buffer, 1, len, err); + } + + if (event_type & Process::eBroadcastBitStateChanged) + { + StateType event_state = SBProcess::GetStateFromEvent (event); + + if (event_state == eStateInvalid) + return; + + bool is_stopped = StateIsStoppedState (event_state); + if (!is_stopped) + process.ReportEventState (event, out); + } +} + +SBSourceManager +SBDebugger::GetSourceManager () +{ + SBSourceManager sb_source_manager (*this); + return sb_source_manager; +} + + +bool +SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len) +{ + if (arch_name && arch_name_len) + { + ArchSpec default_arch = Target::GetDefaultArchitecture (); + + if (default_arch.IsValid()) + { + const std::string &triple_str = default_arch.GetTriple().str(); + if (!triple_str.empty()) + ::snprintf (arch_name, arch_name_len, "%s", triple_str.c_str()); + else + ::snprintf (arch_name, arch_name_len, "%s", default_arch.GetArchitectureName()); + return true; + } + } + if (arch_name && arch_name_len) + arch_name[0] = '\0'; + return false; +} + + +bool +SBDebugger::SetDefaultArchitecture (const char *arch_name) +{ + if (arch_name) + { + ArchSpec arch (arch_name); + if (arch.IsValid()) + { + Target::SetDefaultArchitecture (arch); + return true; + } + } + return false; +} + +ScriptLanguage +SBDebugger::GetScriptingLanguage (const char *script_language_name) +{ + + return Args::StringToScriptLanguage (script_language_name, + eScriptLanguageDefault, + NULL); +} + +const char * +SBDebugger::GetVersionString () +{ + return GetVersion(); +} + +const char * +SBDebugger::StateAsCString (StateType state) +{ + return lldb_private::StateAsCString (state); +} + +bool +SBDebugger::StateIsRunningState (StateType state) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const bool result = lldb_private::StateIsRunningState (state); + if (log) + log->Printf ("SBDebugger::StateIsRunningState (state=%s) => %i", + StateAsCString (state), result); + + return result; +} + +bool +SBDebugger::StateIsStoppedState (StateType state) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const bool result = lldb_private::StateIsStoppedState (state, false); + if (log) + log->Printf ("SBDebugger::StateIsStoppedState (state=%s) => %i", + StateAsCString (state), result); + + return result; +} + +lldb::SBTarget +SBDebugger::CreateTarget (const char *filename, + const char *target_triple, + const char *platform_name, + bool add_dependent_modules, + lldb::SBError& sb_error) +{ + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + sb_error.Clear(); + OptionGroupPlatform platform_options (false); + platform_options.SetPlatformName (platform_name); + + sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, + filename, + target_triple, + add_dependent_modules, + &platform_options, + target_sp); + + if (sb_error.Success()) + sb_target.SetSP (target_sp); + } + else + { + sb_error.SetErrorString("invalid target"); + } + + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, platform_name=%s, add_dependent_modules=%u, error=%s) => SBTarget(%p)", + m_opaque_sp.get(), + filename, + target_triple, + platform_name, + add_dependent_modules, + sb_error.GetCString(), + target_sp.get()); + } + + return sb_target; +} + +SBTarget +SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename, + const char *target_triple) +{ + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + const bool add_dependent_modules = true; + Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, + filename, + target_triple, + add_dependent_modules, + NULL, + target_sp)); + sb_target.SetSP (target_sp); + } + + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple (filename=\"%s\", triple=%s) => SBTarget(%p)", + m_opaque_sp.get(), filename, target_triple, target_sp.get()); + } + + return sb_target; +} + +SBTarget +SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *arch_cstr) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + Error error; + const bool add_dependent_modules = true; + + error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, + filename, + arch_cstr, + add_dependent_modules, + NULL, + target_sp); + + if (error.Success()) + { + m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get()); + sb_target.SetSP (target_sp); + } + } + + if (log) + { + log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", arch=%s) => SBTarget(%p)", + m_opaque_sp.get(), filename, arch_cstr, target_sp.get()); + } + + return sb_target; +} + +SBTarget +SBDebugger::CreateTarget (const char *filename) +{ + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + ArchSpec arch = Target::GetDefaultArchitecture (); + Error error; + const bool add_dependent_modules = true; + + PlatformSP platform_sp(m_opaque_sp->GetPlatformList().GetSelectedPlatform()); + error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, + filename, + arch, + add_dependent_modules, + platform_sp, + target_sp); + + if (error.Success()) + { + m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get()); + sb_target.SetSP (target_sp); + } + } + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", + m_opaque_sp.get(), filename, target_sp.get()); + } + return sb_target; +} + +bool +SBDebugger::DeleteTarget (lldb::SBTarget &target) +{ + bool result = false; + if (m_opaque_sp) + { + TargetSP target_sp(target.GetSP()); + if (target_sp) + { + // No need to lock, the target list is thread safe + result = m_opaque_sp->GetTargetList().DeleteTarget (target_sp); + target_sp->Destroy(); + target.Clear(); + const bool mandatory = true; + ModuleList::RemoveOrphanSharedModules(mandatory); + } + } + + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + log->Printf ("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", m_opaque_sp.get(), target.m_opaque_sp.get(), result); + } + + return result; +} +SBTarget +SBDebugger::GetTargetAtIndex (uint32_t idx) +{ + SBTarget sb_target; + if (m_opaque_sp) + { + // No need to lock, the target list is thread safe + sb_target.SetSP (m_opaque_sp->GetTargetList().GetTargetAtIndex (idx)); + } + return sb_target; +} + +uint32_t +SBDebugger::GetIndexOfTarget (lldb::SBTarget target) +{ + + lldb::TargetSP target_sp = target.GetSP(); + if (!target_sp) + return UINT32_MAX; + + if (!m_opaque_sp) + return UINT32_MAX; + + return m_opaque_sp->GetTargetList().GetIndexOfTarget (target.GetSP()); +} + +SBTarget +SBDebugger::FindTargetWithProcessID (pid_t pid) +{ + SBTarget sb_target; + if (m_opaque_sp) + { + // No need to lock, the target list is thread safe + sb_target.SetSP (m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid)); + } + return sb_target; +} + +SBTarget +SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name) +{ + SBTarget sb_target; + if (m_opaque_sp && filename && filename[0]) + { + // No need to lock, the target list is thread safe + ArchSpec arch (arch_name, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get()); + TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename, false), arch_name ? &arch : NULL)); + sb_target.SetSP (target_sp); + } + return sb_target; +} + +SBTarget +SBDebugger::FindTargetWithLLDBProcess (const ProcessSP &process_sp) +{ + SBTarget sb_target; + if (m_opaque_sp) + { + // No need to lock, the target list is thread safe + sb_target.SetSP (m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get())); + } + return sb_target; +} + + +uint32_t +SBDebugger::GetNumTargets () +{ + if (m_opaque_sp) + { + // No need to lock, the target list is thread safe + return m_opaque_sp->GetTargetList().GetNumTargets (); + } + return 0; +} + +SBTarget +SBDebugger::GetSelectedTarget () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + // No need to lock, the target list is thread safe + target_sp = m_opaque_sp->GetTargetList().GetSelectedTarget (); + sb_target.SetSP (target_sp); + } + + if (log) + { + SBStream sstr; + sb_target.GetDescription (sstr, eDescriptionLevelBrief); + log->Printf ("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", m_opaque_sp.get(), + target_sp.get(), sstr.GetData()); + } + + return sb_target; +} + +void +SBDebugger::SetSelectedTarget (SBTarget &sb_target) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + TargetSP target_sp (sb_target.GetSP()); + if (m_opaque_sp) + { + m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get()); + } + if (log) + { + SBStream sstr; + sb_target.GetDescription (sstr, eDescriptionLevelBrief); + log->Printf ("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", m_opaque_sp.get(), + target_sp.get(), sstr.GetData()); + } +} + +void +SBDebugger::DispatchInput (void* baton, const void *data, size_t data_len) +{ + DispatchInput (data,data_len); +} + +void +SBDebugger::DispatchInput (const void *data, size_t data_len) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", size_t=%" PRIu64 ")", + m_opaque_sp.get(), + (int) data_len, + (const char *) data, + (uint64_t)data_len); + + if (m_opaque_sp) + m_opaque_sp->DispatchInput ((const char *) data, data_len); +} + +void +SBDebugger::DispatchInputInterrupt () +{ + if (m_opaque_sp) + m_opaque_sp->DispatchInputInterrupt (); +} + +void +SBDebugger::DispatchInputEndOfFile () +{ + if (m_opaque_sp) + m_opaque_sp->DispatchInputEndOfFile (); +} + +bool +SBDebugger::InputReaderIsTopReader (const lldb::SBInputReader &reader) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::InputReaderIsTopReader (SBInputReader(%p))", m_opaque_sp.get(), &reader); + + if (m_opaque_sp && reader.IsValid()) + { + InputReaderSP reader_sp (*reader); + return m_opaque_sp->InputReaderIsTopReader (reader_sp); + } + + return false; +} + + +void +SBDebugger::PushInputReader (SBInputReader &reader) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::PushInputReader (SBInputReader(%p))", m_opaque_sp.get(), &reader); + + if (m_opaque_sp && reader.IsValid()) + { + TargetSP target_sp (m_opaque_sp->GetSelectedTarget()); + Mutex::Locker api_locker; + if (target_sp) + api_locker.Lock(target_sp->GetAPIMutex()); + InputReaderSP reader_sp(*reader); + m_opaque_sp->PushInputReader (reader_sp); + } +} + +void +SBDebugger::NotifyTopInputReader (InputReaderAction notification) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::NotifyTopInputReader (%d)", m_opaque_sp.get(), notification); + + if (m_opaque_sp) + m_opaque_sp->NotifyTopInputReader (notification); +} + +void +SBDebugger::reset (const DebuggerSP &debugger_sp) +{ + m_opaque_sp = debugger_sp; +} + +Debugger * +SBDebugger::get () const +{ + return m_opaque_sp.get(); +} + +Debugger & +SBDebugger::ref () const +{ + assert (m_opaque_sp.get()); + return *m_opaque_sp; +} + +const lldb::DebuggerSP & +SBDebugger::get_sp () const +{ + return m_opaque_sp; +} + +SBDebugger +SBDebugger::FindDebuggerWithID (int id) +{ + // No need to lock, the debugger list is thread safe + SBDebugger sb_debugger; + DebuggerSP debugger_sp = Debugger::FindDebuggerWithID (id); + if (debugger_sp) + sb_debugger.reset (debugger_sp); + return sb_debugger; +} + +const char * +SBDebugger::GetInstanceName() +{ + if (m_opaque_sp) + return m_opaque_sp->GetInstanceName().AsCString(); + else + return NULL; +} + +SBError +SBDebugger::SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name) +{ + SBError sb_error; + DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName (ConstString(debugger_instance_name))); + Error error; + if (debugger_sp) + { + ExecutionContext exe_ctx (debugger_sp->GetCommandInterpreter().GetExecutionContext()); + error = debugger_sp->SetPropertyValue (&exe_ctx, + eVarSetOperationAssign, + var_name, + value); + } + else + { + error.SetErrorStringWithFormat ("invalid debugger instance name '%s'", debugger_instance_name); + } + if (error.Fail()) + sb_error.SetError(error); + return sb_error; +} + +SBStringList +SBDebugger::GetInternalVariableValue (const char *var_name, const char *debugger_instance_name) +{ + SBStringList ret_value; + DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName (ConstString(debugger_instance_name))); + Error error; + if (debugger_sp) + { + ExecutionContext exe_ctx (debugger_sp->GetCommandInterpreter().GetExecutionContext()); + lldb::OptionValueSP value_sp (debugger_sp->GetPropertyValue (&exe_ctx, + var_name, + false, + error)); + if (value_sp) + { + StreamString value_strm; + value_sp->DumpValue (&exe_ctx, value_strm, OptionValue::eDumpOptionValue); + const std::string &value_str = value_strm.GetString(); + if (!value_str.empty()) + { + StringList string_list; + string_list.SplitIntoLines(value_str.c_str(), value_str.size()); + return SBStringList(&string_list); + } + } + } + return SBStringList(); +} + +uint32_t +SBDebugger::GetTerminalWidth () const +{ + if (m_opaque_sp) + return m_opaque_sp->GetTerminalWidth (); + return 0; +} + +void +SBDebugger::SetTerminalWidth (uint32_t term_width) +{ + if (m_opaque_sp) + m_opaque_sp->SetTerminalWidth (term_width); +} + +const char * +SBDebugger::GetPrompt() const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::GetPrompt () => \"%s\"", m_opaque_sp.get(), + (m_opaque_sp ? m_opaque_sp->GetPrompt() : "")); + + if (m_opaque_sp) + return m_opaque_sp->GetPrompt (); + return 0; +} + +void +SBDebugger::SetPrompt (const char *prompt) +{ + if (m_opaque_sp) + m_opaque_sp->SetPrompt (prompt); +} + + +ScriptLanguage +SBDebugger::GetScriptLanguage() const +{ + if (m_opaque_sp) + return m_opaque_sp->GetScriptLanguage (); + return eScriptLanguageNone; +} + +void +SBDebugger::SetScriptLanguage (ScriptLanguage script_lang) +{ + if (m_opaque_sp) + { + m_opaque_sp->SetScriptLanguage (script_lang); + } +} + +bool +SBDebugger::SetUseExternalEditor (bool value) +{ + if (m_opaque_sp) + return m_opaque_sp->SetUseExternalEditor (value); + return false; +} + +bool +SBDebugger::GetUseExternalEditor () +{ + if (m_opaque_sp) + return m_opaque_sp->GetUseExternalEditor (); + return false; +} + +bool +SBDebugger::SetUseColor (bool value) +{ + if (m_opaque_sp) + return m_opaque_sp->SetUseColor (value); + return false; +} + +bool +SBDebugger::GetUseColor () const +{ + if (m_opaque_sp) + return m_opaque_sp->GetUseColor (); + return false; +} + +bool +SBDebugger::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + if (m_opaque_sp) + { + const char *name = m_opaque_sp->GetInstanceName().AsCString(); + user_id_t id = m_opaque_sp->GetID(); + strm.Printf ("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id); + } + else + strm.PutCString ("No value"); + + return true; +} + +user_id_t +SBDebugger::GetID() +{ + if (m_opaque_sp) + return m_opaque_sp->GetID(); + return LLDB_INVALID_UID; +} + + +SBError +SBDebugger::SetCurrentPlatform (const char *platform_name) +{ + SBError sb_error; + if (m_opaque_sp) + { + PlatformSP platform_sp (Platform::Create (platform_name, sb_error.ref())); + + if (platform_sp) + { + bool make_selected = true; + m_opaque_sp->GetPlatformList().Append (platform_sp, make_selected); + } + } + return sb_error; +} + +bool +SBDebugger::SetCurrentPlatformSDKRoot (const char *sysroot) +{ + if (m_opaque_sp) + { + PlatformSP platform_sp (m_opaque_sp->GetPlatformList().GetSelectedPlatform()); + + if (platform_sp) + { + platform_sp->SetSDKRootDirectory (ConstString (sysroot)); + return true; + } + } + return false; +} + +bool +SBDebugger::GetCloseInputOnEOF () const +{ + if (m_opaque_sp) + return m_opaque_sp->GetCloseInputOnEOF (); + return false; +} + +void +SBDebugger::SetCloseInputOnEOF (bool b) +{ + if (m_opaque_sp) + m_opaque_sp->SetCloseInputOnEOF (b); +} + +SBTypeCategory +SBDebugger::GetCategory (const char* category_name) +{ + if (!category_name || *category_name == 0) + return SBTypeCategory(); + + TypeCategoryImplSP category_sp; + + if (DataVisualization::Categories::GetCategory(ConstString(category_name), category_sp, false)) + return SBTypeCategory(category_sp); + else + return SBTypeCategory(); +} + +SBTypeCategory +SBDebugger::CreateCategory (const char* category_name) +{ + if (!category_name || *category_name == 0) + return SBTypeCategory(); + + TypeCategoryImplSP category_sp; + + if (DataVisualization::Categories::GetCategory(ConstString(category_name), category_sp, true)) + return SBTypeCategory(category_sp); + else + return SBTypeCategory(); +} + +bool +SBDebugger::DeleteCategory (const char* category_name) +{ + if (!category_name || *category_name == 0) + return false; + + return DataVisualization::Categories::Delete(ConstString(category_name)); +} + +uint32_t +SBDebugger::GetNumCategories() +{ + return DataVisualization::Categories::GetCount(); +} + +SBTypeCategory +SBDebugger::GetCategoryAtIndex (uint32_t index) +{ + return SBTypeCategory(DataVisualization::Categories::GetCategoryAtIndex(index)); +} + +SBTypeCategory +SBDebugger::GetDefaultCategory() +{ + return GetCategory("default"); +} + +SBTypeFormat +SBDebugger::GetFormatForType (SBTypeNameSpecifier type_name) +{ + SBTypeCategory default_category_sb = GetDefaultCategory(); + if (default_category_sb.GetEnabled()) + return default_category_sb.GetFormatForType(type_name); + return SBTypeFormat(); +} + +#ifndef LLDB_DISABLE_PYTHON +SBTypeSummary +SBDebugger::GetSummaryForType (SBTypeNameSpecifier type_name) +{ + if (type_name.IsValid() == false) + return SBTypeSummary(); + return SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP())); +} +#endif // LLDB_DISABLE_PYTHON + +SBTypeFilter +SBDebugger::GetFilterForType (SBTypeNameSpecifier type_name) +{ + if (type_name.IsValid() == false) + return SBTypeFilter(); + return SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP())); +} + +#ifndef LLDB_DISABLE_PYTHON +SBTypeSynthetic +SBDebugger::GetSyntheticForType (SBTypeNameSpecifier type_name) +{ + if (type_name.IsValid() == false) + return SBTypeSynthetic(); + return SBTypeSynthetic(DataVisualization::GetSyntheticForType(type_name.GetSP())); +} +#endif // LLDB_DISABLE_PYTHON + +bool +SBDebugger::EnableLog (const char *channel, const char **categories) +{ + if (m_opaque_sp) + { + uint32_t log_options = LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; + StreamString errors; + return m_opaque_sp->EnableLog (channel, categories, NULL, log_options, errors); + + } + else + return false; +} + +void +SBDebugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton) +{ + if (m_opaque_sp) + { + return m_opaque_sp->SetLoggingCallback (log_callback, baton); + } +} + + diff --git a/source/API/SBDeclaration.cpp b/source/API/SBDeclaration.cpp new file mode 100644 index 000000000000..fc90156e75ad --- /dev/null +++ b/source/API/SBDeclaration.cpp @@ -0,0 +1,206 @@ +//===-- SBDeclaration.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/SBDeclaration.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Symbol/Declaration.h" + +#include <limits.h> + +using namespace lldb; +using namespace lldb_private; + + +SBDeclaration::SBDeclaration () : + m_opaque_ap () +{ +} + +SBDeclaration::SBDeclaration (const SBDeclaration &rhs) : + m_opaque_ap () +{ + if (rhs.IsValid()) + ref() = rhs.ref(); +} + +SBDeclaration::SBDeclaration (const lldb_private::Declaration *lldb_object_ptr) : + m_opaque_ap () +{ + if (lldb_object_ptr) + ref() = *lldb_object_ptr; +} + +const SBDeclaration & +SBDeclaration::operator = (const SBDeclaration &rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + ref() = rhs.ref(); + else + m_opaque_ap.reset(); + } + return *this; +} + +void +SBDeclaration::SetDeclaration (const lldb_private::Declaration &lldb_object_ref) +{ + ref() = lldb_object_ref; +} + + +SBDeclaration::~SBDeclaration () +{ +} + + +bool +SBDeclaration::IsValid () const +{ + return m_opaque_ap.get() && m_opaque_ap->IsValid(); +} + + +SBFileSpec +SBDeclaration::GetFileSpec () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBFileSpec sb_file_spec; + if (m_opaque_ap.get() && m_opaque_ap->GetFile()) + sb_file_spec.SetFileSpec(m_opaque_ap->GetFile()); + + if (log) + { + SBStream sstr; + sb_file_spec.GetDescription (sstr); + log->Printf ("SBLineEntry(%p)::GetFileSpec () => SBFileSpec(%p): %s", m_opaque_ap.get(), + sb_file_spec.get(), sstr.GetData()); + } + + return sb_file_spec; +} + +uint32_t +SBDeclaration::GetLine () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t line = 0; + if (m_opaque_ap.get()) + line = m_opaque_ap->GetLine(); + + if (log) + log->Printf ("SBLineEntry(%p)::GetLine () => %u", m_opaque_ap.get(), line); + + return line; +} + + +uint32_t +SBDeclaration::GetColumn () const +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetColumn(); + return 0; +} + +void +SBDeclaration::SetFileSpec (lldb::SBFileSpec filespec) +{ + if (filespec.IsValid()) + ref().SetFile(filespec.ref()); + else + ref().SetFile(FileSpec()); +} +void +SBDeclaration::SetLine (uint32_t line) +{ + ref().SetLine(line); +} + +void +SBDeclaration::SetColumn (uint32_t column) +{ + ref().SetColumn(column); +} + + + +bool +SBDeclaration::operator == (const SBDeclaration &rhs) const +{ + lldb_private::Declaration *lhs_ptr = m_opaque_ap.get(); + lldb_private::Declaration *rhs_ptr = rhs.m_opaque_ap.get(); + + if (lhs_ptr && rhs_ptr) + return lldb_private::Declaration::Compare (*lhs_ptr, *rhs_ptr) == 0; + + return lhs_ptr == rhs_ptr; +} + +bool +SBDeclaration::operator != (const SBDeclaration &rhs) const +{ + lldb_private::Declaration *lhs_ptr = m_opaque_ap.get(); + lldb_private::Declaration *rhs_ptr = rhs.m_opaque_ap.get(); + + if (lhs_ptr && rhs_ptr) + return lldb_private::Declaration::Compare (*lhs_ptr, *rhs_ptr) != 0; + + return lhs_ptr != rhs_ptr; +} + +const lldb_private::Declaration * +SBDeclaration::operator->() const +{ + return m_opaque_ap.get(); +} + +lldb_private::Declaration & +SBDeclaration::ref() +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new lldb_private::Declaration ()); + return *m_opaque_ap; +} + +const lldb_private::Declaration & +SBDeclaration::ref() const +{ + return *m_opaque_ap; +} + +bool +SBDeclaration::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + if (m_opaque_ap.get()) + { + char file_path[PATH_MAX*2]; + m_opaque_ap->GetFile().GetPath (file_path, sizeof (file_path)); + strm.Printf ("%s:%u", file_path, GetLine()); + if (GetColumn() > 0) + strm.Printf (":%u", GetColumn()); + } + else + strm.PutCString ("No value"); + + return true; +} + +lldb_private::Declaration * +SBDeclaration::get () +{ + return m_opaque_ap.get(); +} diff --git a/source/API/SBError.cpp b/source/API/SBError.cpp new file mode 100644 index 000000000000..bd6b54300f60 --- /dev/null +++ b/source/API/SBError.cpp @@ -0,0 +1,233 @@ +//===-- SBError.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/SBError.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Log.h" + +#include <stdarg.h> + +using namespace lldb; +using namespace lldb_private; + + +SBError::SBError () : + m_opaque_ap () +{ +} + +SBError::SBError (const SBError &rhs) : + m_opaque_ap () +{ + if (rhs.IsValid()) + m_opaque_ap.reset (new Error(*rhs)); +} + + +SBError::~SBError() +{ +} + +const SBError & +SBError::operator = (const SBError &rhs) +{ + if (rhs.IsValid()) + { + if (m_opaque_ap.get()) + *m_opaque_ap = *rhs; + else + m_opaque_ap.reset (new Error(*rhs)); + } + else + m_opaque_ap.reset(); + + return *this; +} + + +const char * +SBError::GetCString () const +{ + if (m_opaque_ap.get()) + return m_opaque_ap->AsCString(); + return NULL; +} + +void +SBError::Clear () +{ + if (m_opaque_ap.get()) + m_opaque_ap->Clear(); +} + +bool +SBError::Fail () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool ret_value = false; + if (m_opaque_ap.get()) + ret_value = m_opaque_ap->Fail(); + + if (log) + log->Printf ("SBError(%p)::Fail () => %i", m_opaque_ap.get(), ret_value); + + return ret_value; +} + +bool +SBError::Success () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool ret_value = true; + if (m_opaque_ap.get()) + ret_value = m_opaque_ap->Success(); + + if (log) + log->Printf ("SBError(%p)::Success () => %i", m_opaque_ap.get(), ret_value); + + return ret_value; +} + +uint32_t +SBError::GetError () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t err = 0; + if (m_opaque_ap.get()) + err = m_opaque_ap->GetError(); + + if (log) + log->Printf ("SBError(%p)::GetError () => 0x%8.8x", m_opaque_ap.get(), err); + + + return err; +} + +ErrorType +SBError::GetType () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ErrorType err_type = eErrorTypeInvalid; + if (m_opaque_ap.get()) + err_type = m_opaque_ap->GetType(); + + if (log) + log->Printf ("SBError(%p)::GetType () => %i", m_opaque_ap.get(), err_type); + + return err_type; +} + +void +SBError::SetError (uint32_t err, ErrorType type) +{ + CreateIfNeeded (); + m_opaque_ap->SetError (err, type); +} + +void +SBError::SetError (const Error &lldb_error) +{ + CreateIfNeeded (); + *m_opaque_ap = lldb_error; +} + + +void +SBError::SetErrorToErrno () +{ + CreateIfNeeded (); + m_opaque_ap->SetErrorToErrno (); +} + +void +SBError::SetErrorToGenericError () +{ + CreateIfNeeded (); + m_opaque_ap->SetErrorToErrno (); +} + +void +SBError::SetErrorString (const char *err_str) +{ + CreateIfNeeded (); + m_opaque_ap->SetErrorString (err_str); +} + +int +SBError::SetErrorStringWithFormat (const char *format, ...) +{ + CreateIfNeeded (); + va_list args; + va_start (args, format); + int num_chars = m_opaque_ap->SetErrorStringWithVarArg (format, args); + va_end (args); + return num_chars; +} + +bool +SBError::IsValid () const +{ + return m_opaque_ap.get() != NULL; +} + +void +SBError::CreateIfNeeded () +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset(new Error ()); +} + + +lldb_private::Error * +SBError::operator->() +{ + return m_opaque_ap.get(); +} + +lldb_private::Error * +SBError::get() +{ + return m_opaque_ap.get(); +} + +lldb_private::Error & +SBError::ref() +{ + CreateIfNeeded(); + return *m_opaque_ap; +} + +const lldb_private::Error & +SBError::operator*() const +{ + // Be sure to call "IsValid()" before calling this function or it will crash + return *m_opaque_ap; +} + +bool +SBError::GetDescription (SBStream &description) +{ + if (m_opaque_ap.get()) + { + if (m_opaque_ap->Success()) + description.Printf ("success"); + else + { + const char * err_string = GetCString(); + description.Printf ("error: %s", (err_string != NULL ? err_string : "")); + } + } + else + description.Printf ("error: <NULL>"); + + return true; +} diff --git a/source/API/SBEvent.cpp b/source/API/SBEvent.cpp new file mode 100644 index 000000000000..d5d4a84bc1fd --- /dev/null +++ b/source/API/SBEvent.cpp @@ -0,0 +1,245 @@ +//===-- SBEvent.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/lldb-python.h" + +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBBroadcaster.h" +#include "lldb/API/SBStream.h" + +#include "lldb/Core/Event.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Target/Process.h" +#include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Interpreter/CommandInterpreter.h" + +using namespace lldb; +using namespace lldb_private; + + +SBEvent::SBEvent () : + m_event_sp (), + m_opaque_ptr (NULL) +{ +} + +SBEvent::SBEvent (uint32_t event_type, const char *cstr, uint32_t cstr_len) : + m_event_sp (new Event (event_type, new EventDataBytes (cstr, cstr_len))), + m_opaque_ptr (m_event_sp.get()) +{ +} + +SBEvent::SBEvent (EventSP &event_sp) : + m_event_sp (event_sp), + m_opaque_ptr (event_sp.get()) +{ +} + +SBEvent::SBEvent (const SBEvent &rhs) : + m_event_sp (rhs.m_event_sp), + m_opaque_ptr (rhs.m_opaque_ptr) +{ + +} + +const SBEvent & +SBEvent::operator = (const SBEvent &rhs) +{ + if (this != &rhs) + { + m_event_sp = rhs.m_event_sp; + m_opaque_ptr = rhs.m_opaque_ptr; + } + return *this; +} + +SBEvent::~SBEvent() +{ +} + +const char * +SBEvent::GetDataFlavor () +{ + Event *lldb_event = get(); + if (lldb_event) + { + EventData *event_data = lldb_event->GetData(); + if (event_data) + return lldb_event->GetData()->GetFlavor().AsCString(); + } + return NULL; +} + +uint32_t +SBEvent::GetType () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const Event *lldb_event = get(); + uint32_t event_type = 0; + if (lldb_event) + event_type = lldb_event->GetType(); + + if (log) + { + StreamString sstr; + if (lldb_event && lldb_event->GetBroadcaster() && lldb_event->GetBroadcaster()->GetEventNames(sstr, event_type, true)) + log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x (%s)", get(), event_type, sstr.GetData()); + else + log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x", get(), event_type); + + } + + return event_type; +} + +SBBroadcaster +SBEvent::GetBroadcaster () const +{ + SBBroadcaster broadcaster; + const Event *lldb_event = get(); + if (lldb_event) + broadcaster.reset (lldb_event->GetBroadcaster(), false); + return broadcaster; +} + +const char * +SBEvent::GetBroadcasterClass () const +{ + const Event *lldb_event = get(); + if (lldb_event) + return lldb_event->GetBroadcaster()->GetBroadcasterClass().AsCString(); + else + return "unknown class"; +} + +bool +SBEvent::BroadcasterMatchesPtr (const SBBroadcaster *broadcaster) +{ + if (broadcaster) + return BroadcasterMatchesRef (*broadcaster); + return false; +} + +bool +SBEvent::BroadcasterMatchesRef (const SBBroadcaster &broadcaster) +{ + + Event *lldb_event = get(); + bool success = false; + if (lldb_event) + success = lldb_event->BroadcasterIs (broadcaster.get()); + + // For logging, this gets a little chatty so only enable this when verbose logging is on + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE)); + if (log) + log->Printf ("SBEvent(%p)::BroadcasterMatchesRef (SBBroadcaster(%p): %s) => %i", + get(), + broadcaster.get(), + broadcaster.GetName(), + success); + + return success; +} + +void +SBEvent::Clear() +{ + Event *lldb_event = get(); + if (lldb_event) + lldb_event->Clear(); +} + +EventSP & +SBEvent::GetSP () const +{ + return m_event_sp; +} + +Event * +SBEvent::get() const +{ + // There is a dangerous accessor call GetSharedPtr which can be used, so if + // we have anything valid in m_event_sp, we must use that since if it gets + // used by a function that puts something in there, then it won't update + // m_opaque_ptr... + if (m_event_sp) + m_opaque_ptr = m_event_sp.get(); + + return m_opaque_ptr; +} + +void +SBEvent::reset (EventSP &event_sp) +{ + m_event_sp = event_sp; + m_opaque_ptr = m_event_sp.get(); +} + +void +SBEvent::reset (Event* event_ptr) +{ + m_opaque_ptr = event_ptr; + m_event_sp.reset(); +} + +bool +SBEvent::IsValid() const +{ + // Do NOT use m_opaque_ptr directly!!! Must use the SBEvent::get() + // accessor. See comments in SBEvent::get().... + return SBEvent::get() != NULL; + +} + +const char * +SBEvent::GetCStringFromEvent (const SBEvent &event) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBEvent(%p)::GetCStringFromEvent () => \"%s\"", + event.get(), + reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event.get()))); + + return reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event.get())); +} + + +bool +SBEvent::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + if (get()) + { + m_opaque_ptr->Dump (&strm); + } + else + strm.PutCString ("No value"); + + return true; +} + +bool +SBEvent::GetDescription (SBStream &description) const +{ + Stream &strm = description.ref(); + + if (get()) + { + m_opaque_ptr->Dump (&strm); + } + else + strm.PutCString ("No value"); + + return true; +} diff --git a/source/API/SBExpressionOptions.cpp b/source/API/SBExpressionOptions.cpp new file mode 100644 index 000000000000..127b0cf13cdc --- /dev/null +++ b/source/API/SBExpressionOptions.cpp @@ -0,0 +1,126 @@ +//===-- SBExpressionOptions.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/SBExpressionOptions.h" +#include "lldb/API/SBStream.h" + +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + + +SBExpressionOptions::SBExpressionOptions () : + m_opaque_ap(new EvaluateExpressionOptions()) +{ +} + +SBExpressionOptions::SBExpressionOptions (const SBExpressionOptions &rhs) +{ + m_opaque_ap.reset(new EvaluateExpressionOptions()); + *(m_opaque_ap.get()) = rhs.ref(); +} + +const SBExpressionOptions & +SBExpressionOptions::operator = (const SBExpressionOptions &rhs) +{ + if (this != &rhs) + { + this->ref() = rhs.ref(); + } + return *this; +} + +SBExpressionOptions::~SBExpressionOptions() +{ +} + +bool +SBExpressionOptions::GetCoerceResultToId () const +{ + return m_opaque_ap->DoesCoerceToId (); +} + +void +SBExpressionOptions::SetCoerceResultToId (bool coerce) +{ + m_opaque_ap->SetCoerceToId (coerce); +} + +bool +SBExpressionOptions::GetUnwindOnError () const +{ + return m_opaque_ap->DoesUnwindOnError (); +} + +void +SBExpressionOptions::SetUnwindOnError (bool unwind) +{ + m_opaque_ap->SetUnwindOnError (unwind); +} + +bool +SBExpressionOptions::GetIgnoreBreakpoints () const +{ + return m_opaque_ap->DoesIgnoreBreakpoints (); +} + +void +SBExpressionOptions::SetIgnoreBreakpoints (bool ignore) +{ + m_opaque_ap->SetIgnoreBreakpoints (ignore); +} + +lldb::DynamicValueType +SBExpressionOptions::GetFetchDynamicValue () const +{ + return m_opaque_ap->GetUseDynamic (); +} + +void +SBExpressionOptions::SetFetchDynamicValue (lldb::DynamicValueType dynamic) +{ + m_opaque_ap->SetUseDynamic (dynamic); +} + +uint32_t +SBExpressionOptions::GetTimeoutInMicroSeconds () const +{ + return m_opaque_ap->GetTimeoutUsec (); +} + +void +SBExpressionOptions::SetTimeoutInMicroSeconds (uint32_t timeout) +{ + m_opaque_ap->SetTimeoutUsec (timeout); +} + +bool +SBExpressionOptions::GetTryAllThreads () const +{ + return m_opaque_ap->GetRunOthers (); +} + +void +SBExpressionOptions::SetTryAllThreads (bool run_others) +{ + m_opaque_ap->SetRunOthers (run_others); +} + +EvaluateExpressionOptions * +SBExpressionOptions::get() const +{ + return m_opaque_ap.get(); +} + +EvaluateExpressionOptions & +SBExpressionOptions::ref () const +{ + return *(m_opaque_ap.get()); +} diff --git a/source/API/SBFileSpec.cpp b/source/API/SBFileSpec.cpp new file mode 100644 index 000000000000..4413689501a8 --- /dev/null +++ b/source/API/SBFileSpec.cpp @@ -0,0 +1,181 @@ +//===-- SBFileSpec.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <limits.h> + +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBStream.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" + +using namespace lldb; +using namespace lldb_private; + + + +SBFileSpec::SBFileSpec () : + m_opaque_ap(new lldb_private::FileSpec()) +{ +} + +SBFileSpec::SBFileSpec (const SBFileSpec &rhs) : + m_opaque_ap(new lldb_private::FileSpec(*rhs.m_opaque_ap)) +{ +} + +SBFileSpec::SBFileSpec (const lldb_private::FileSpec& fspec) : + m_opaque_ap(new lldb_private::FileSpec(fspec)) +{ +} + +// Deprected!!! +SBFileSpec::SBFileSpec (const char *path) : + m_opaque_ap(new FileSpec (path, true)) +{ +} + +SBFileSpec::SBFileSpec (const char *path, bool resolve) : + m_opaque_ap(new FileSpec (path, resolve)) +{ +} + +SBFileSpec::~SBFileSpec () +{ +} + +const SBFileSpec & +SBFileSpec::operator = (const SBFileSpec &rhs) +{ + if (this != &rhs) + *m_opaque_ap = *rhs.m_opaque_ap; + return *this; +} + +bool +SBFileSpec::IsValid() const +{ + return *m_opaque_ap; +} + +bool +SBFileSpec::Exists () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool result = m_opaque_ap->Exists(); + + if (log) + log->Printf ("SBFileSpec(%p)::Exists () => %s", m_opaque_ap.get(), (result ? "true" : "false")); + + return result; +} + +bool +SBFileSpec::ResolveExecutableLocation () +{ + return m_opaque_ap->ResolveExecutableLocation (); +} + +int +SBFileSpec::ResolvePath (const char *src_path, char *dst_path, size_t dst_len) +{ + return lldb_private::FileSpec::Resolve (src_path, dst_path, dst_len); +} + +const char * +SBFileSpec::GetFilename() const +{ + const char *s = m_opaque_ap->GetFilename().AsCString(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (s) + log->Printf ("SBFileSpec(%p)::GetFilename () => \"%s\"", m_opaque_ap.get(), s); + else + log->Printf ("SBFileSpec(%p)::GetFilename () => NULL", m_opaque_ap.get()); + } + + return s; +} + +const char * +SBFileSpec::GetDirectory() const +{ + const char *s = m_opaque_ap->GetDirectory().AsCString(); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (s) + log->Printf ("SBFileSpec(%p)::GetDirectory () => \"%s\"", m_opaque_ap.get(), s); + else + log->Printf ("SBFileSpec(%p)::GetDirectory () => NULL", m_opaque_ap.get()); + } + return s; +} + +uint32_t +SBFileSpec::GetPath (char *dst_path, size_t dst_len) const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t result = m_opaque_ap->GetPath (dst_path, dst_len); + + if (log) + log->Printf ("SBFileSpec(%p)::GetPath (dst_path=\"%.*s\", dst_len=%" PRIu64 ") => %u", + m_opaque_ap.get(), result, dst_path, (uint64_t)dst_len, result); + + if (result == 0 && dst_path && dst_len > 0) + *dst_path = '\0'; + return result; +} + + +const lldb_private::FileSpec * +SBFileSpec::operator->() const +{ + return m_opaque_ap.get(); +} + +const lldb_private::FileSpec * +SBFileSpec::get() const +{ + return m_opaque_ap.get(); +} + + +const lldb_private::FileSpec & +SBFileSpec::operator*() const +{ + return *m_opaque_ap.get(); +} + +const lldb_private::FileSpec & +SBFileSpec::ref() const +{ + return *m_opaque_ap.get(); +} + + +void +SBFileSpec::SetFileSpec (const lldb_private::FileSpec& fs) +{ + *m_opaque_ap = fs; +} + +bool +SBFileSpec::GetDescription (SBStream &description) const +{ + Stream &strm = description.ref(); + char path[PATH_MAX]; + if (m_opaque_ap->GetPath(path, sizeof(path))) + strm.PutCString (path); + return true; +} diff --git a/source/API/SBFileSpecList.cpp b/source/API/SBFileSpecList.cpp new file mode 100644 index 000000000000..3ebf3cc80a2a --- /dev/null +++ b/source/API/SBFileSpecList.cpp @@ -0,0 +1,142 @@ +//===-- SBFileSpecListList.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <limits.h> + +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBFileSpecList.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/FileSpecList.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Host/FileSpec.h" + +using namespace lldb; +using namespace lldb_private; + + + +SBFileSpecList::SBFileSpecList () : + m_opaque_ap(new FileSpecList()) +{ +} + +SBFileSpecList::SBFileSpecList (const SBFileSpecList &rhs) : + m_opaque_ap() +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (rhs.m_opaque_ap.get()) + m_opaque_ap.reset (new FileSpecList (*(rhs.get()))); + + if (log) + { + log->Printf ("SBFileSpecList::SBFileSpecList (const SBFileSpecList rhs.ap=%p) => SBFileSpecList(%p)", + rhs.m_opaque_ap.get(), m_opaque_ap.get()); + } +} + +SBFileSpecList::~SBFileSpecList () +{ +} + +const SBFileSpecList & +SBFileSpecList::operator = (const SBFileSpecList &rhs) +{ + if (this != &rhs) + { + m_opaque_ap.reset (new lldb_private::FileSpecList(*(rhs.get()))); + } + return *this; +} + +uint32_t +SBFileSpecList::GetSize () const +{ + return m_opaque_ap->GetSize(); +} + +void +SBFileSpecList::Append (const SBFileSpec &sb_file) +{ + m_opaque_ap->Append (sb_file.ref()); +} + +bool +SBFileSpecList::AppendIfUnique (const SBFileSpec &sb_file) +{ + return m_opaque_ap->AppendIfUnique (sb_file.ref()); +} + +void +SBFileSpecList::Clear() +{ + m_opaque_ap->Clear(); +} + +uint32_t +SBFileSpecList::FindFileIndex (uint32_t idx, const SBFileSpec &sb_file, bool full) +{ + return m_opaque_ap->FindFileIndex (idx, sb_file.ref(), full); +} + +const SBFileSpec +SBFileSpecList::GetFileSpecAtIndex (uint32_t idx) const +{ + SBFileSpec new_spec; + new_spec.SetFileSpec(m_opaque_ap->GetFileSpecAtIndex(idx)); + return new_spec; +} + +const lldb_private::FileSpecList * +SBFileSpecList::operator->() const +{ + return m_opaque_ap.get(); +} + +const lldb_private::FileSpecList * +SBFileSpecList::get() const +{ + return m_opaque_ap.get(); +} + + +const lldb_private::FileSpecList & +SBFileSpecList::operator*() const +{ + return *m_opaque_ap.get(); +} + +const lldb_private::FileSpecList & +SBFileSpecList::ref() const +{ + return *m_opaque_ap.get(); +} + +bool +SBFileSpecList::GetDescription (SBStream &description) const +{ + Stream &strm = description.ref(); + + if (m_opaque_ap.get()) + { + uint32_t num_files = m_opaque_ap->GetSize(); + strm.Printf ("%d files: ", num_files); + for (uint32_t i = 0; i < num_files; i++) + { + char path[PATH_MAX]; + if (m_opaque_ap->GetFileSpecAtIndex(i).GetPath(path, sizeof(path))) + strm.Printf ("\n %s", path); + } + } + else + strm.PutCString ("No value"); + + return true; +} diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp new file mode 100644 index 000000000000..1a1a63bd0671 --- /dev/null +++ b/source/API/SBFrame.cpp @@ -0,0 +1,1526 @@ +//===-- SBFrame.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/SBFrame.h" + +#include <string> +#include <algorithm> + +#include "lldb/lldb-types.h" + +#include "lldb/Core/Address.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Expression/ClangUserExpression.h" +#include "lldb/Host/Host.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/StackID.h" +#include "lldb/Target/Thread.h" + +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBValue.h" +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBExpressionOptions.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBSymbolContext.h" +#include "lldb/API/SBThread.h" + +using namespace lldb; +using namespace lldb_private; + + +SBFrame::SBFrame () : + m_opaque_sp (new ExecutionContextRef()) +{ +} + +SBFrame::SBFrame (const StackFrameSP &lldb_object_sp) : + m_opaque_sp (new ExecutionContextRef (lldb_object_sp)) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + { + SBStream sstr; + GetDescription (sstr); + log->Printf ("SBFrame::SBFrame (sp=%p) => SBFrame(%p): %s", + lldb_object_sp.get(), lldb_object_sp.get(), sstr.GetData()); + + } +} + +SBFrame::SBFrame(const SBFrame &rhs) : + m_opaque_sp (new ExecutionContextRef (*rhs.m_opaque_sp)) +{ +} + +const SBFrame & +SBFrame::operator = (const SBFrame &rhs) +{ + if (this != &rhs) + *m_opaque_sp = *rhs.m_opaque_sp; + return *this; +} + +SBFrame::~SBFrame() +{ +} + +StackFrameSP +SBFrame::GetFrameSP() const +{ + if (m_opaque_sp) + return m_opaque_sp->GetFrameSP(); + return StackFrameSP(); +} + +void +SBFrame::SetFrameSP (const StackFrameSP &lldb_object_sp) +{ + return m_opaque_sp->SetFrameSP(lldb_object_sp); +} + +bool +SBFrame::IsValid() const +{ + return GetFrameSP().get() != NULL; +} + +SBSymbolContext +SBFrame::GetSymbolContext (uint32_t resolve_scope) const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBSymbolContext sb_sym_ctx; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext (resolve_scope)); + } + else + { + if (log) + log->Printf ("SBFrame::GetVariables () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetSymbolContext () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::GetSymbolContext (resolve_scope=0x%8.8x) => SBSymbolContext(%p)", + frame, resolve_scope, sb_sym_ctx.get()); + + return sb_sym_ctx; +} + +SBModule +SBFrame::GetModule () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBModule sb_module; + ModuleSP module_sp; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + module_sp = frame->GetSymbolContext (eSymbolContextModule).module_sp; + sb_module.SetSP (module_sp); + } + else + { + if (log) + log->Printf ("SBFrame::GetModule () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetModule () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::GetModule () => SBModule(%p)", + frame, module_sp.get()); + + return sb_module; +} + +SBCompileUnit +SBFrame::GetCompileUnit () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBCompileUnit sb_comp_unit; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + sb_comp_unit.reset (frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit); + } + else + { + if (log) + log->Printf ("SBFrame::GetCompileUnit () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetCompileUnit () => error: process is running"); + } + } + if (log) + log->Printf ("SBFrame(%p)::GetCompileUnit () => SBCompileUnit(%p)", + frame, sb_comp_unit.get()); + + return sb_comp_unit; +} + +SBFunction +SBFrame::GetFunction () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBFunction sb_function; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + sb_function.reset(frame->GetSymbolContext (eSymbolContextFunction).function); + } + else + { + if (log) + log->Printf ("SBFrame::GetFunction () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetFunction () => error: process is running"); + } + } + if (log) + log->Printf ("SBFrame(%p)::GetFunction () => SBFunction(%p)", + frame, sb_function.get()); + + return sb_function; +} + +SBSymbol +SBFrame::GetSymbol () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBSymbol sb_symbol; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + sb_symbol.reset(frame->GetSymbolContext (eSymbolContextSymbol).symbol); + } + else + { + if (log) + log->Printf ("SBFrame::GetSymbol () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetSymbol () => error: process is running"); + } + } + if (log) + log->Printf ("SBFrame(%p)::GetSymbol () => SBSymbol(%p)", + frame, sb_symbol.get()); + return sb_symbol; +} + +SBBlock +SBFrame::GetBlock () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBBlock sb_block; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + sb_block.SetPtr (frame->GetSymbolContext (eSymbolContextBlock).block); + } + else + { + if (log) + log->Printf ("SBFrame::GetBlock () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame(%p)::GetBlock () => error: process is running", frame); + } + } + if (log) + log->Printf ("SBFrame(%p)::GetBlock () => SBBlock(%p)", + frame, sb_block.GetPtr()); + return sb_block; +} + +SBBlock +SBFrame::GetFrameBlock () const +{ + SBBlock sb_block; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + sb_block.SetPtr(frame->GetFrameBlock ()); + } + else + { + if (log) + log->Printf ("SBFrame::GetFrameBlock () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetFrameBlock () => error: process is running"); + } + } + if (log) + log->Printf ("SBFrame(%p)::GetFrameBlock () => SBBlock(%p)", + frame, sb_block.GetPtr()); + return sb_block; +} + +SBLineEntry +SBFrame::GetLineEntry () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBLineEntry sb_line_entry; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + sb_line_entry.SetLineEntry (frame->GetSymbolContext (eSymbolContextLineEntry).line_entry); + } + else + { + if (log) + log->Printf ("SBFrame::GetLineEntry () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetLineEntry () => error: process is running"); + } + } + if (log) + log->Printf ("SBFrame(%p)::GetLineEntry () => SBLineEntry(%p)", + frame, sb_line_entry.get()); + return sb_line_entry; +} + +uint32_t +SBFrame::GetFrameID () const +{ + uint32_t frame_idx = UINT32_MAX; + + ExecutionContext exe_ctx(m_opaque_sp.get()); + StackFrame *frame = exe_ctx.GetFramePtr(); + if (frame) + frame_idx = frame->GetFrameIndex (); + + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBFrame(%p)::GetFrameID () => %u", + frame, frame_idx); + return frame_idx; +} + +addr_t +SBFrame::GetPC () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + addr_t addr = LLDB_INVALID_ADDRESS; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress (target); + } + else + { + if (log) + log->Printf ("SBFrame::GetPC () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetPC () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::GetPC () => 0x%" PRIx64, frame, addr); + + return addr; +} + +bool +SBFrame::SetPC (addr_t new_pc) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool ret_val = false; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + ret_val = frame->GetRegisterContext()->SetPC (new_pc); + } + else + { + if (log) + log->Printf ("SBFrame::SetPC () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::SetPC () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::SetPC (new_pc=0x%" PRIx64 ") => %i", + frame, new_pc, ret_val); + + return ret_val; +} + +addr_t +SBFrame::GetSP () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + addr_t addr = LLDB_INVALID_ADDRESS; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + addr = frame->GetRegisterContext()->GetSP(); + } + else + { + if (log) + log->Printf ("SBFrame::GetSP () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetSP () => error: process is running"); + } + } + if (log) + log->Printf ("SBFrame(%p)::GetSP () => 0x%" PRIx64, frame, addr); + + return addr; +} + + +addr_t +SBFrame::GetFP () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + addr_t addr = LLDB_INVALID_ADDRESS; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + addr = frame->GetRegisterContext()->GetFP(); + } + else + { + if (log) + log->Printf ("SBFrame::GetFP () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetFP () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::GetFP () => 0x%" PRIx64, frame, addr); + return addr; +} + + +SBAddress +SBFrame::GetPCAddress () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBAddress sb_addr; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = exe_ctx.GetFramePtr(); + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + sb_addr.SetAddress (&frame->GetFrameCodeAddress()); + } + else + { + if (log) + log->Printf ("SBFrame::GetPCAddress () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetPCAddress () => error: process is running"); + } + } + if (log) + log->Printf ("SBFrame(%p)::GetPCAddress () => SBAddress(%p)", frame, sb_addr.get()); + return sb_addr; +} + +void +SBFrame::Clear() +{ + m_opaque_sp->Clear(); +} + +lldb::SBValue +SBFrame::GetValueForVariablePath (const char *var_path) +{ + SBValue sb_value; + ExecutionContext exe_ctx(m_opaque_sp.get()); + StackFrame *frame = exe_ctx.GetFramePtr(); + Target *target = exe_ctx.GetTargetPtr(); + if (frame && target) + { + lldb::DynamicValueType use_dynamic = frame->CalculateTarget()->GetPreferDynamicValue(); + sb_value = GetValueForVariablePath (var_path, use_dynamic); + } + return sb_value; +} + +lldb::SBValue +SBFrame::GetValueForVariablePath (const char *var_path, DynamicValueType use_dynamic) +{ + SBValue sb_value; + Mutex::Locker api_locker; + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (var_path == NULL || var_path[0] == '\0') + { + if (log) + log->Printf ("SBFrame::GetValueForVariablePath called with empty variable path."); + return sb_value; + } + + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + VariableSP var_sp; + Error error; + ValueObjectSP value_sp (frame->GetValueForVariableExpressionPath (var_path, + eNoDynamicValues, + StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, + var_sp, + error)); + sb_value.SetSP(value_sp, use_dynamic); + } + else + { + if (log) + log->Printf ("SBFrame::GetValueForVariablePath () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetValueForVariablePath () => error: process is running"); + } + } + return sb_value; +} + +SBValue +SBFrame::FindVariable (const char *name) +{ + SBValue value; + ExecutionContext exe_ctx(m_opaque_sp.get()); + StackFrame *frame = exe_ctx.GetFramePtr(); + Target *target = exe_ctx.GetTargetPtr(); + if (frame && target) + { + lldb::DynamicValueType use_dynamic = frame->CalculateTarget()->GetPreferDynamicValue(); + value = FindVariable (name, use_dynamic); + } + return value; +} + + +SBValue +SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + VariableSP var_sp; + SBValue sb_value; + + if (name == NULL || name[0] == '\0') + { + if (log) + log->Printf ("SBFrame::FindVariable called with empty name"); + return sb_value; + } + + ValueObjectSP value_sp; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + VariableList variable_list; + SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); + + if (sc.block) + { + const bool can_create = true; + const bool get_parent_variables = true; + const bool stop_if_block_is_inlined_function = true; + + if (sc.block->AppendVariables (can_create, + get_parent_variables, + stop_if_block_is_inlined_function, + &variable_list)) + { + var_sp = variable_list.FindVariable (ConstString(name)); + } + } + + if (var_sp) + { + value_sp = frame->GetValueObjectForFrameVariable(var_sp, eNoDynamicValues); + sb_value.SetSP(value_sp, use_dynamic); + } + } + else + { + if (log) + log->Printf ("SBFrame::FindVariable () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::FindVariable () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::FindVariable (name=\"%s\") => SBValue(%p)", + frame, name, value_sp.get()); + + return sb_value; +} + +SBValue +SBFrame::FindValue (const char *name, ValueType value_type) +{ + SBValue value; + ExecutionContext exe_ctx(m_opaque_sp.get()); + StackFrame *frame = exe_ctx.GetFramePtr(); + Target *target = exe_ctx.GetTargetPtr(); + if (frame && target) + { + lldb::DynamicValueType use_dynamic = frame->CalculateTarget()->GetPreferDynamicValue(); + value = FindValue (name, value_type, use_dynamic); + } + return value; +} + +SBValue +SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBValue sb_value; + + if (name == NULL || name[0] == '\0') + { + if (log) + log->Printf ("SBFrame::FindValue called with empty name."); + return sb_value; + } + + ValueObjectSP value_sp; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + switch (value_type) + { + case eValueTypeVariableGlobal: // global variable + case eValueTypeVariableStatic: // static variable + case eValueTypeVariableArgument: // function argument variables + case eValueTypeVariableLocal: // function local variables + { + VariableList *variable_list = frame->GetVariableList(true); + + SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); + + const bool can_create = true; + const bool get_parent_variables = true; + const bool stop_if_block_is_inlined_function = true; + + if (sc.block && sc.block->AppendVariables (can_create, + get_parent_variables, + stop_if_block_is_inlined_function, + variable_list)) + { + ConstString const_name(name); + const uint32_t num_variables = variable_list->GetSize(); + for (uint32_t i = 0; i < num_variables; ++i) + { + VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); + if (variable_sp && + variable_sp->GetScope() == value_type && + variable_sp->GetName() == const_name) + { + value_sp = frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues); + sb_value.SetSP (value_sp, use_dynamic); + break; + } + } + } + } + break; + + case eValueTypeRegister: // stack frame register value + { + RegisterContextSP reg_ctx (frame->GetRegisterContext()); + if (reg_ctx) + { + const uint32_t num_regs = reg_ctx->GetRegisterCount(); + for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) + { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); + if (reg_info && + ((reg_info->name && strcasecmp (reg_info->name, name) == 0) || + (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0))) + { + value_sp = ValueObjectRegister::Create (frame, reg_ctx, reg_idx); + sb_value.SetSP (value_sp); + break; + } + } + } + } + break; + + case eValueTypeRegisterSet: // A collection of stack frame register values + { + RegisterContextSP reg_ctx (frame->GetRegisterContext()); + if (reg_ctx) + { + const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); + for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) + { + const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx); + if (reg_set && + ((reg_set->name && strcasecmp (reg_set->name, name) == 0) || + (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0))) + { + value_sp = ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx); + sb_value.SetSP (value_sp); + break; + } + } + } + } + break; + + case eValueTypeConstResult: // constant result variables + { + ConstString const_name(name); + ClangExpressionVariableSP expr_var_sp (target->GetPersistentVariables().GetVariable (const_name)); + if (expr_var_sp) + { + value_sp = expr_var_sp->GetValueObject(); + sb_value.SetSP (value_sp, use_dynamic); + } + } + break; + + default: + break; + } + } + else + { + if (log) + log->Printf ("SBFrame::FindValue () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::FindValue () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::FindVariableInScope (name=\"%s\", value_type=%i) => SBValue(%p)", + frame, name, value_type, value_sp.get()); + + + return sb_value; +} + +bool +SBFrame::IsEqual (const SBFrame &that) const +{ + lldb::StackFrameSP this_sp = GetFrameSP(); + lldb::StackFrameSP that_sp = that.GetFrameSP(); + return (this_sp && that_sp && this_sp->GetStackID() == that_sp->GetStackID()); +} + +bool +SBFrame::operator == (const SBFrame &rhs) const +{ + return IsEqual(rhs); +} + +bool +SBFrame::operator != (const SBFrame &rhs) const +{ + return !IsEqual(rhs); +} + +SBThread +SBFrame::GetThread () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ExecutionContext exe_ctx(m_opaque_sp.get()); + ThreadSP thread_sp (exe_ctx.GetThreadSP()); + SBThread sb_thread (thread_sp); + + if (log) + { + SBStream sstr; + sb_thread.GetDescription (sstr); + log->Printf ("SBFrame(%p)::GetThread () => SBThread(%p): %s", + exe_ctx.GetFramePtr(), + thread_sp.get(), + sstr.GetData()); + } + + return sb_thread; +} + +const char * +SBFrame::Disassemble () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *disassembly = NULL; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + disassembly = frame->Disassemble(); + } + else + { + if (log) + log->Printf ("SBFrame::Disassemble () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::Disassemble () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::Disassemble () => %s", frame, disassembly); + + return disassembly; +} + + +SBValueList +SBFrame::GetVariables (bool arguments, + bool locals, + bool statics, + bool in_scope_only) +{ + SBValueList value_list; + ExecutionContext exe_ctx(m_opaque_sp.get()); + StackFrame *frame = exe_ctx.GetFramePtr(); + Target *target = exe_ctx.GetTargetPtr(); + if (frame && target) + { + lldb::DynamicValueType use_dynamic = frame->CalculateTarget()->GetPreferDynamicValue(); + value_list = GetVariables (arguments, locals, statics, in_scope_only, use_dynamic); + } + return value_list; +} + +SBValueList +SBFrame::GetVariables (bool arguments, + bool locals, + bool statics, + bool in_scope_only, + lldb::DynamicValueType use_dynamic) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBValueList value_list; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + + if (log) + log->Printf ("SBFrame::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)", + arguments, + locals, + statics, + in_scope_only); + + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + size_t i; + VariableList *variable_list = NULL; + variable_list = frame->GetVariableList(true); + if (variable_list) + { + const size_t num_variables = variable_list->GetSize(); + if (num_variables) + { + for (i = 0; i < num_variables; ++i) + { + VariableSP variable_sp (variable_list->GetVariableAtIndex(i)); + if (variable_sp) + { + bool add_variable = false; + switch (variable_sp->GetScope()) + { + case eValueTypeVariableGlobal: + case eValueTypeVariableStatic: + add_variable = statics; + break; + + case eValueTypeVariableArgument: + add_variable = arguments; + break; + + case eValueTypeVariableLocal: + add_variable = locals; + break; + + default: + break; + } + if (add_variable) + { + if (in_scope_only && !variable_sp->IsInScope(frame)) + continue; + + ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues)); + SBValue value_sb; + value_sb.SetSP(valobj_sp,use_dynamic); + value_list.Append(value_sb); + } + } + } + } + } + } + else + { + if (log) + log->Printf ("SBFrame::GetVariables () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetVariables () => error: process is running"); + } + } + + if (log) + { + log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", frame, value_list.opaque_ptr()); + } + + return value_list; +} + +SBValueList +SBFrame::GetRegisters () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBValueList value_list; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + RegisterContextSP reg_ctx (frame->GetRegisterContext()); + if (reg_ctx) + { + const uint32_t num_sets = reg_ctx->GetRegisterSetCount(); + for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) + { + value_list.Append(ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx)); + } + } + } + else + { + if (log) + log->Printf ("SBFrame::GetRegisters () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetRegisters () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::GetRegisters () => SBValueList(%p)", frame, value_list.opaque_ptr()); + + return value_list; +} + +SBValue +SBFrame::FindRegister (const char *name) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBValue result; + ValueObjectSP value_sp; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + RegisterContextSP reg_ctx (frame->GetRegisterContext()); + if (reg_ctx) + { + const uint32_t num_regs = reg_ctx->GetRegisterCount(); + for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) + { + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx); + if (reg_info && + ((reg_info->name && strcasecmp (reg_info->name, name) == 0) || + (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0))) + { + value_sp = ValueObjectRegister::Create (frame, reg_ctx, reg_idx); + result.SetSP (value_sp); + break; + } + } + } + } + else + { + if (log) + log->Printf ("SBFrame::FindRegister () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::FindRegister () => error: process is running"); + } + } + + if (log) + log->Printf ("SBFrame(%p)::FindRegister () => SBValue(%p)", frame, value_sp.get()); + + return result; +} + +bool +SBFrame::GetDescription (SBStream &description) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + Stream &strm = description.ref(); + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrame *frame; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + frame->DumpUsingSettingsFormat (&strm); + } + else + { + if (log) + log->Printf ("SBFrame::GetDescription () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetDescription () => error: process is running"); + } + + } + else + strm.PutCString ("No value"); + + return true; +} + +SBValue +SBFrame::EvaluateExpression (const char *expr) +{ + SBValue result; + ExecutionContext exe_ctx(m_opaque_sp.get()); + StackFrame *frame = exe_ctx.GetFramePtr(); + Target *target = exe_ctx.GetTargetPtr(); + if (frame && target) + { + SBExpressionOptions options; + lldb::DynamicValueType fetch_dynamic_value = frame->CalculateTarget()->GetPreferDynamicValue(); + options.SetFetchDynamicValue (fetch_dynamic_value); + options.SetUnwindOnError (true); + return EvaluateExpression (expr, options); + } + return result; +} + +SBValue +SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value) +{ + SBExpressionOptions options; + options.SetFetchDynamicValue (fetch_dynamic_value); + options.SetUnwindOnError (true); + return EvaluateExpression (expr, options); +} + +SBValue +SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dynamic_value, bool unwind_on_error) +{ + SBExpressionOptions options; + options.SetFetchDynamicValue (fetch_dynamic_value); + options.SetUnwindOnError (unwind_on_error); + return EvaluateExpression (expr, options); +} + +lldb::SBValue +SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &options) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Log *expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + ExecutionResults exe_results = eExecutionSetupError; + SBValue expr_result; + + if (expr == NULL || expr[0] == '\0') + { + if (log) + log->Printf ("SBFrame::EvaluateExpression called with an empty expression"); + return expr_result; + } + + ValueObjectSP expr_value_sp; + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (log) + log->Printf ("SBFrame()::EvaluateExpression (expr=\"%s\")...", expr); + + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { +#ifdef LLDB_CONFIGURATION_DEBUG + StreamString frame_description; + frame->DumpUsingSettingsFormat (&frame_description); + Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s", + expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str()); +#endif + exe_results = target->EvaluateExpression (expr, + frame, + expr_value_sp, + options.ref()); + expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue()); +#ifdef LLDB_CONFIGURATION_DEBUG + Host::SetCrashDescription (NULL); +#endif + } + else + { + if (log) + log->Printf ("SBFrame::EvaluateExpression () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::EvaluateExpression () => error: process is running"); + } + } + +#ifndef LLDB_DISABLE_PYTHON + if (expr_log) + expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is %s, summary %s **", + expr_result.GetValue(), + expr_result.GetSummary()); + + if (log) + log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", + frame, + expr, + expr_value_sp.get(), + exe_results); +#endif + + return expr_result; +} + +bool +SBFrame::IsInlined() +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ExecutionContext exe_ctx(m_opaque_sp.get()); + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + + Block *block = frame->GetSymbolContext(eSymbolContextBlock).block; + if (block) + return block->GetContainingInlinedBlock () != NULL; + } + else + { + if (log) + log->Printf ("SBFrame::IsInlined () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::IsInlined () => error: process is running"); + } + + } + return false; +} + +const char * +SBFrame::GetFunctionName() +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *name = NULL; + ExecutionContext exe_ctx(m_opaque_sp.get()); + StackFrame *frame = NULL; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) + { + frame = exe_ctx.GetFramePtr(); + if (frame) + { + SymbolContext sc (frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); + if (sc.block) + { + Block *inlined_block = sc.block->GetContainingInlinedBlock (); + if (inlined_block) + { + const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo(); + name = inlined_info->GetName().AsCString(); + } + } + + if (name == NULL) + { + if (sc.function) + name = sc.function->GetName().GetCString(); + } + + if (name == NULL) + { + if (sc.symbol) + name = sc.symbol->GetName().GetCString(); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetFunctionName () => error: could not reconstruct frame object for this SBFrame."); + } + } + else + { + if (log) + log->Printf ("SBFrame::GetFunctionName() => error: process is running"); + + } + } + return name; +} + diff --git a/source/API/SBFunction.cpp b/source/API/SBFunction.cpp new file mode 100644 index 000000000000..914d2d77f3ec --- /dev/null +++ b/source/API/SBFunction.cpp @@ -0,0 +1,225 @@ +//===-- SBFunction.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/SBFunction.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +SBFunction::SBFunction () : + m_opaque_ptr (NULL) +{ +} + +SBFunction::SBFunction (lldb_private::Function *lldb_object_ptr) : + m_opaque_ptr (lldb_object_ptr) +{ +} + +SBFunction::SBFunction (const lldb::SBFunction &rhs) : + m_opaque_ptr (rhs.m_opaque_ptr) +{ +} + +const SBFunction & +SBFunction::operator = (const SBFunction &rhs) +{ + m_opaque_ptr = rhs.m_opaque_ptr; + return *this; +} + +SBFunction::~SBFunction () +{ + m_opaque_ptr = NULL; +} + +bool +SBFunction::IsValid () const +{ + return m_opaque_ptr != NULL; +} + +const char * +SBFunction::GetName() const +{ + const char *cstr = NULL; + if (m_opaque_ptr) + cstr = m_opaque_ptr->GetMangled().GetName().AsCString(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (cstr) + log->Printf ("SBFunction(%p)::GetName () => \"%s\"", m_opaque_ptr, cstr); + else + log->Printf ("SBFunction(%p)::GetName () => NULL", m_opaque_ptr); + } + return cstr; +} + +const char * +SBFunction::GetMangledName () const +{ + const char *cstr = NULL; + if (m_opaque_ptr) + cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString(); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (cstr) + log->Printf ("SBFunction(%p)::GetMangledName () => \"%s\"", m_opaque_ptr, cstr); + else + log->Printf ("SBFunction(%p)::GetMangledName () => NULL", m_opaque_ptr); + } + return cstr; +} + +bool +SBFunction::operator == (const SBFunction &rhs) const +{ + return m_opaque_ptr == rhs.m_opaque_ptr; +} + +bool +SBFunction::operator != (const SBFunction &rhs) const +{ + return m_opaque_ptr != rhs.m_opaque_ptr; +} + +bool +SBFunction::GetDescription (SBStream &s) +{ + if (m_opaque_ptr) + { + s.Printf ("SBFunction: id = 0x%8.8" PRIx64 ", name = %s", + m_opaque_ptr->GetID(), + m_opaque_ptr->GetName().AsCString()); + Type *func_type = m_opaque_ptr->GetType(); + if (func_type) + s.Printf(", type = %s", func_type->GetName().AsCString()); + return true; + } + s.Printf ("No value"); + return false; +} + +SBInstructionList +SBFunction::GetInstructions (SBTarget target) +{ + return GetInstructions (target, NULL); +} + +SBInstructionList +SBFunction::GetInstructions (SBTarget target, const char *flavor) +{ + SBInstructionList sb_instructions; + if (m_opaque_ptr) + { + 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()); + } + ModuleSP module_sp (m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule()); + if (module_sp) + { + sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture(), + NULL, + flavor, + exe_ctx, + m_opaque_ptr->GetAddressRange())); + } + } + return sb_instructions; +} + +lldb_private::Function * +SBFunction::get () +{ + return m_opaque_ptr; +} + +void +SBFunction::reset (lldb_private::Function *lldb_object_ptr) +{ + m_opaque_ptr = lldb_object_ptr; +} + +SBAddress +SBFunction::GetStartAddress () +{ + SBAddress addr; + if (m_opaque_ptr) + addr.SetAddress (&m_opaque_ptr->GetAddressRange().GetBaseAddress()); + return addr; +} + +SBAddress +SBFunction::GetEndAddress () +{ + SBAddress addr; + if (m_opaque_ptr) + { + addr_t byte_size = m_opaque_ptr->GetAddressRange().GetByteSize(); + if (byte_size > 0) + { + addr.SetAddress (&m_opaque_ptr->GetAddressRange().GetBaseAddress()); + addr->Slide (byte_size); + } + } + return addr; +} + + +uint32_t +SBFunction::GetPrologueByteSize () +{ + if (m_opaque_ptr) + return m_opaque_ptr->GetPrologueByteSize(); + return 0; +} + +SBType +SBFunction::GetType () +{ + SBType sb_type; + if (m_opaque_ptr) + { + Type *function_type = m_opaque_ptr->GetType(); + if (function_type) + sb_type.ref().SetType (function_type->shared_from_this()); + } + return sb_type; +} + +SBBlock +SBFunction::GetBlock () +{ + SBBlock sb_block; + if (m_opaque_ptr) + sb_block.SetPtr (&m_opaque_ptr->GetBlock (true)); + return sb_block; +} + + + diff --git a/source/API/SBHostOS.cpp b/source/API/SBHostOS.cpp new file mode 100644 index 000000000000..a8f7db90a150 --- /dev/null +++ b/source/API/SBHostOS.cpp @@ -0,0 +1,85 @@ +//===-- SBHostOS.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/SBHostOS.h" +#include "lldb/API/SBError.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Core/Log.h" +#include "lldb/Host/Host.h" + +using namespace lldb; +using namespace lldb_private; + + + +SBFileSpec +SBHostOS::GetProgramFileSpec () +{ + SBFileSpec sb_filespec; + sb_filespec.SetFileSpec (Host::GetProgramFileSpec ()); + return sb_filespec; +} + +SBFileSpec +SBHostOS::GetLLDBPythonPath () +{ + SBFileSpec sb_lldb_python_filespec; + FileSpec lldb_python_spec; + if (Host::GetLLDBPath (ePathTypePythonDir, lldb_python_spec)) + { + sb_lldb_python_filespec.SetFileSpec (lldb_python_spec); + } + return sb_lldb_python_filespec; +} + +lldb::thread_t +SBHostOS::ThreadCreate +( + const char *name, + void *(*thread_function)(void *), + void *thread_arg, + SBError *error_ptr +) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBHostOS::ThreadCreate (name=\"%s\", thread_function=%p, thread_arg=%p, error_ptr=%p)", name, + thread_function, thread_arg, error_ptr); + + // FIXME: You should log the return value? + + return Host::ThreadCreate (name, thread_function, thread_arg, error_ptr ? error_ptr->get() : NULL); +} + +void +SBHostOS::ThreadCreated (const char *name) +{ + Host::ThreadCreated (name); +} + +bool +SBHostOS::ThreadCancel (lldb::thread_t thread, SBError *error_ptr) +{ + return Host::ThreadCancel (thread, error_ptr ? error_ptr->get() : NULL); +} + +bool +SBHostOS::ThreadDetach (lldb::thread_t thread, SBError *error_ptr) +{ + return Host::ThreadDetach (thread, error_ptr ? error_ptr->get() : NULL); +} + +bool +SBHostOS::ThreadJoin (lldb::thread_t thread, void **result, SBError *error_ptr) +{ + return Host::ThreadJoin (thread, result, error_ptr ? error_ptr->get() : NULL); +} + + diff --git a/source/API/SBInputReader.cpp b/source/API/SBInputReader.cpp new file mode 100644 index 000000000000..82b75c869f08 --- /dev/null +++ b/source/API/SBInputReader.cpp @@ -0,0 +1,216 @@ +//===-- SBInputReader.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/lldb-enumerations.h" + +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBInputReader.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" +#include "lldb/Core/InputReader.h" +#include "lldb/Core/Log.h" + + +using namespace lldb; +using namespace lldb_private; + +SBInputReader::SBInputReader () : + m_opaque_sp (), + m_callback_function (NULL), + m_callback_baton (NULL) + +{ +} + +SBInputReader::SBInputReader (const lldb::InputReaderSP &reader_sp) : + m_opaque_sp (reader_sp) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBInputReader::SBInputReader (reader_sp=%p) => SBInputReader(%p)", reader_sp.get(), + m_opaque_sp.get()); +} + +SBInputReader::SBInputReader (const SBInputReader &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf("SBInputReader::SBInputReader (rhs.sp=%p) => SBInputReader(%p)", + rhs.m_opaque_sp.get(), m_opaque_sp.get()); +} + +SBInputReader::~SBInputReader () +{ +} + +size_t +SBInputReader::PrivateCallback +( + void *baton, + InputReader &reader, + lldb::InputReaderAction notification, + const char *bytes, + size_t bytes_len +) +{ + SBInputReader *sb_reader = (SBInputReader *)baton; + return sb_reader->m_callback_function (sb_reader->m_callback_baton, + sb_reader, + notification, + bytes, + bytes_len); +} + +SBError +SBInputReader::Initialize +( + SBDebugger &debugger, + Callback callback_function, + void *callback_baton, + lldb::InputReaderGranularity granularity, + const char *end_token, + const char *prompt, + bool echo +) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf("SBInputReader(%p)::Initialize (SBDebugger(%p), callback_function=%p, callback_baton=%p, " + "granularity=%s, end_token=\"%s\", prompt=\"%s\", echo=%i)", + m_opaque_sp.get(), + debugger.get(), + callback_function, + callback_baton, + InputReader::GranularityAsCString (granularity), end_token, prompt, + echo); + + SBError sb_error; + m_opaque_sp.reset (new InputReader (debugger.ref())); + + m_callback_function = callback_function; + m_callback_baton = callback_baton; + + if (m_opaque_sp) + { + sb_error.SetError (m_opaque_sp->Initialize (SBInputReader::PrivateCallback, + this, + granularity, + end_token, + prompt, + echo)); + } + + if (sb_error.Fail()) + { + m_opaque_sp.reset (); + m_callback_function = NULL; + m_callback_baton = NULL; + } + + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBInputReader(%p)::Initialize (...) => SBError(%p): %s", m_opaque_sp.get(), + sb_error.get(), sstr.GetData()); + } + + return sb_error; +} + +bool +SBInputReader::IsValid () const +{ + return (m_opaque_sp.get() != NULL); +} + +const SBInputReader & +SBInputReader::operator = (const SBInputReader &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +InputReader * +SBInputReader::operator->() const +{ + return m_opaque_sp.get(); +} + +lldb::InputReaderSP & +SBInputReader::operator *() +{ + return m_opaque_sp; +} + +const lldb::InputReaderSP & +SBInputReader::operator *() const +{ + return m_opaque_sp; +} + +InputReader * +SBInputReader::get() const +{ + return m_opaque_sp.get(); +} + +InputReader & +SBInputReader::ref() const +{ + assert (m_opaque_sp.get()); + return *m_opaque_sp; +} + +bool +SBInputReader::IsDone () const +{ + if (m_opaque_sp) + return m_opaque_sp->IsDone(); + else + return true; +} + +void +SBInputReader::SetIsDone (bool value) +{ + if (m_opaque_sp) + m_opaque_sp->SetIsDone (value); +} + +bool +SBInputReader::IsActive () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool ret_value = false; + if (m_opaque_sp) + ret_value = m_opaque_sp->IsActive(); + + if (log) + log->Printf ("SBInputReader(%p)::IsActive () => %i", m_opaque_sp.get(), ret_value); + + return ret_value; +} + +InputReaderGranularity +SBInputReader::GetGranularity () +{ + if (m_opaque_sp) + return m_opaque_sp->GetGranularity(); + else + return eInputReaderGranularityInvalid; +} diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp new file mode 100644 index 000000000000..2334cc0d124a --- /dev/null +++ b/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; +} diff --git a/source/API/SBInstructionList.cpp b/source/API/SBInstructionList.cpp new file mode 100644 index 000000000000..fe22d9c29e4a --- /dev/null +++ b/source/API/SBInstructionList.cpp @@ -0,0 +1,132 @@ +//===-- SBInstructionList.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/SBInstructionList.h" +#include "lldb/API/SBInstruction.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/Stream.h" + +using namespace lldb; +using namespace lldb_private; + + +SBInstructionList::SBInstructionList () : + m_opaque_sp() +{ +} + +SBInstructionList::SBInstructionList(const SBInstructionList &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +const SBInstructionList & +SBInstructionList::operator = (const SBInstructionList &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + + +SBInstructionList::~SBInstructionList () +{ +} + +bool +SBInstructionList::IsValid () const +{ + return m_opaque_sp.get() != NULL; +} + +size_t +SBInstructionList::GetSize () +{ + if (m_opaque_sp) + return m_opaque_sp->GetInstructionList().GetSize(); + return 0; +} + +SBInstruction +SBInstructionList::GetInstructionAtIndex (uint32_t idx) +{ + SBInstruction inst; + if (m_opaque_sp && idx < m_opaque_sp->GetInstructionList().GetSize()) + inst.SetOpaque (m_opaque_sp->GetInstructionList().GetInstructionAtIndex (idx)); + return inst; +} + +void +SBInstructionList::Clear () +{ + m_opaque_sp.reset(); +} + +void +SBInstructionList::AppendInstruction (SBInstruction insn) +{ +} + +void +SBInstructionList::SetDisassembler (const lldb::DisassemblerSP &opaque_sp) +{ + m_opaque_sp = opaque_sp; +} + +void +SBInstructionList::Print (FILE *out) +{ + if (out == NULL) + return; +} + + +bool +SBInstructionList::GetDescription (lldb::SBStream &description) +{ + if (m_opaque_sp) + { + size_t num_instructions = GetSize (); + if (num_instructions) + { + // Call the ref() to make sure a stream is created if one deesn't + // exist already inside description... + Stream &sref = description.ref(); + const uint32_t max_opcode_byte_size = m_opaque_sp->GetInstructionList().GetMaxOpcocdeByteSize(); + for (size_t i=0; i<num_instructions; ++i) + { + Instruction *inst = m_opaque_sp->GetInstructionList().GetInstructionAtIndex (i).get(); + if (inst == NULL) + break; + inst->Dump (&sref, max_opcode_byte_size, true, false, NULL); + sref.EOL(); + } + return true; + } + } + return false; +} + + +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/API/SBLineEntry.cpp b/source/API/SBLineEntry.cpp new file mode 100644 index 000000000000..0864a2e006c3 --- /dev/null +++ b/source/API/SBLineEntry.cpp @@ -0,0 +1,250 @@ +//===-- SBLineEntry.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <limits.h> + +#include "lldb/API/SBLineEntry.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Core/Log.h" +#include "lldb/Symbol/LineEntry.h" + +using namespace lldb; +using namespace lldb_private; + + +SBLineEntry::SBLineEntry () : + m_opaque_ap () +{ +} + +SBLineEntry::SBLineEntry (const SBLineEntry &rhs) : + m_opaque_ap () +{ + if (rhs.IsValid()) + ref() = rhs.ref(); +} + +SBLineEntry::SBLineEntry (const lldb_private::LineEntry *lldb_object_ptr) : + m_opaque_ap () +{ + if (lldb_object_ptr) + ref() = *lldb_object_ptr; +} + +const SBLineEntry & +SBLineEntry::operator = (const SBLineEntry &rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + ref() = rhs.ref(); + else + m_opaque_ap.reset(); + } + return *this; +} + +void +SBLineEntry::SetLineEntry (const lldb_private::LineEntry &lldb_object_ref) +{ + ref() = lldb_object_ref; +} + + +SBLineEntry::~SBLineEntry () +{ +} + + +SBAddress +SBLineEntry::GetStartAddress () const +{ + + SBAddress sb_address; + if (m_opaque_ap.get()) + sb_address.SetAddress(&m_opaque_ap->range.GetBaseAddress()); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + StreamString sstr; + const Address *addr = sb_address.get(); + if (addr) + addr->Dump (&sstr, NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4); + log->Printf ("SBLineEntry(%p)::GetStartAddress () => SBAddress (%p): %s", + m_opaque_ap.get(), sb_address.get(), sstr.GetData()); + } + + return sb_address; +} + +SBAddress +SBLineEntry::GetEndAddress () const +{ + SBAddress sb_address; + if (m_opaque_ap.get()) + { + sb_address.SetAddress(&m_opaque_ap->range.GetBaseAddress()); + sb_address.OffsetAddress(m_opaque_ap->range.GetByteSize()); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + StreamString sstr; + const Address *addr = sb_address.get(); + if (addr) + addr->Dump (&sstr, NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4); + log->Printf ("SBLineEntry(%p)::GetEndAddress () => SBAddress (%p): %s", + m_opaque_ap.get(), sb_address.get(), sstr.GetData()); + } + return sb_address; +} + +bool +SBLineEntry::IsValid () const +{ + return m_opaque_ap.get() && m_opaque_ap->IsValid(); +} + + +SBFileSpec +SBLineEntry::GetFileSpec () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBFileSpec sb_file_spec; + if (m_opaque_ap.get() && m_opaque_ap->file) + sb_file_spec.SetFileSpec(m_opaque_ap->file); + + if (log) + { + SBStream sstr; + sb_file_spec.GetDescription (sstr); + log->Printf ("SBLineEntry(%p)::GetFileSpec () => SBFileSpec(%p): %s", m_opaque_ap.get(), + sb_file_spec.get(), sstr.GetData()); + } + + return sb_file_spec; +} + +uint32_t +SBLineEntry::GetLine () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t line = 0; + if (m_opaque_ap.get()) + line = m_opaque_ap->line; + + if (log) + log->Printf ("SBLineEntry(%p)::GetLine () => %u", m_opaque_ap.get(), line); + + return line; +} + + +uint32_t +SBLineEntry::GetColumn () const +{ + if (m_opaque_ap.get()) + return m_opaque_ap->column; + return 0; +} + +void +SBLineEntry::SetFileSpec (lldb::SBFileSpec filespec) +{ + if (filespec.IsValid()) + ref().file = filespec.ref(); + else + ref().file.Clear(); +} +void +SBLineEntry::SetLine (uint32_t line) +{ + ref().line = line; +} + +void +SBLineEntry::SetColumn (uint32_t column) +{ + ref().line = column; +} + + + +bool +SBLineEntry::operator == (const SBLineEntry &rhs) const +{ + lldb_private::LineEntry *lhs_ptr = m_opaque_ap.get(); + lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_ap.get(); + + if (lhs_ptr && rhs_ptr) + return lldb_private::LineEntry::Compare (*lhs_ptr, *rhs_ptr) == 0; + + return lhs_ptr == rhs_ptr; +} + +bool +SBLineEntry::operator != (const SBLineEntry &rhs) const +{ + lldb_private::LineEntry *lhs_ptr = m_opaque_ap.get(); + lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_ap.get(); + + if (lhs_ptr && rhs_ptr) + return lldb_private::LineEntry::Compare (*lhs_ptr, *rhs_ptr) != 0; + + return lhs_ptr != rhs_ptr; +} + +const lldb_private::LineEntry * +SBLineEntry::operator->() const +{ + return m_opaque_ap.get(); +} + +lldb_private::LineEntry & +SBLineEntry::ref() +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new lldb_private::LineEntry ()); + return *m_opaque_ap; +} + +const lldb_private::LineEntry & +SBLineEntry::ref() const +{ + return *m_opaque_ap; +} + +bool +SBLineEntry::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + if (m_opaque_ap.get()) + { + char file_path[PATH_MAX*2]; + m_opaque_ap->file.GetPath (file_path, sizeof (file_path)); + strm.Printf ("%s:%u", file_path, GetLine()); + if (GetColumn() > 0) + strm.Printf (":%u", GetColumn()); + } + else + strm.PutCString ("No value"); + + return true; +} + +lldb_private::LineEntry * +SBLineEntry::get () +{ + return m_opaque_ap.get(); +} diff --git a/source/API/SBListener.cpp b/source/API/SBListener.cpp new file mode 100644 index 000000000000..2e67b4c24e86 --- /dev/null +++ b/source/API/SBListener.cpp @@ -0,0 +1,443 @@ +//===-- SBListener.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/lldb-python.h" + +#include "lldb/API/SBListener.h" +#include "lldb/API/SBBroadcaster.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Broadcaster.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Listener.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Host/TimeValue.h" + + +using namespace lldb; +using namespace lldb_private; + + +SBListener::SBListener () : + m_opaque_sp (), + m_opaque_ptr (NULL) +{ +} + +SBListener::SBListener (const char *name) : + m_opaque_sp (new Listener (name)), + m_opaque_ptr (NULL) +{ + m_opaque_ptr = m_opaque_sp.get(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBListener::SBListener (name=\"%s\") => SBListener(%p)", + name, m_opaque_ptr); +} + + +SBListener::SBListener (const SBListener &rhs) : + m_opaque_sp (rhs.m_opaque_sp), + m_opaque_ptr (rhs.m_opaque_ptr) +{ +} + +const lldb::SBListener & +SBListener::operator = (const lldb::SBListener &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + m_opaque_ptr = rhs.m_opaque_ptr; + } + return *this; +} + +SBListener::SBListener (Listener &listener) : + m_opaque_sp (), + m_opaque_ptr (&listener) +{ +} + +SBListener::~SBListener () +{ +} + +bool +SBListener::IsValid() const +{ + return m_opaque_ptr != NULL; +} + +void +SBListener::AddEvent (const SBEvent &event) +{ + EventSP &event_sp = event.GetSP (); + if (event_sp) + m_opaque_ptr->AddEvent (event_sp); +} + +void +SBListener::Clear () +{ + if (m_opaque_ptr) + m_opaque_ptr->Clear (); +} + +uint32_t +SBListener::StartListeningForEventClass (SBDebugger &debugger, + const char *broadcaster_class, + uint32_t event_mask) +{ + if (m_opaque_ptr) + { + Debugger *lldb_debugger = debugger.get(); + if (!lldb_debugger) + return 0; + BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask); + return m_opaque_ptr->StartListeningForEventSpec (*lldb_debugger, event_spec); + } + else + return 0; +} + +bool +SBListener::StopListeningForEventClass (SBDebugger &debugger, + const char *broadcaster_class, + uint32_t event_mask) +{ + if (m_opaque_ptr) + { + Debugger *lldb_debugger = debugger.get(); + if (!lldb_debugger) + return false; + BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask); + return m_opaque_ptr->StopListeningForEventSpec (*lldb_debugger, event_spec); + } + else + return false; +} + +uint32_t +SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask) +{ + uint32_t acquired_event_mask = 0; + if (m_opaque_ptr && broadcaster.IsValid()) + { + acquired_event_mask = m_opaque_ptr->StartListeningForEvents (broadcaster.get(), event_mask); + } + + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); + if (log) + { + StreamString sstr_requested; + StreamString sstr_acquired; + + Broadcaster *lldb_broadcaster = broadcaster.get(); + if (lldb_broadcaster) + { + const bool got_requested_names = lldb_broadcaster->GetEventNames (sstr_requested, event_mask, false); + const bool got_acquired_names = lldb_broadcaster->GetEventNames (sstr_acquired, acquired_event_mask, false); + log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p): %s, event_mask=0x%8.8x%s%s%s) => 0x%8.8x%s%s%s", + m_opaque_ptr, + lldb_broadcaster, + lldb_broadcaster->GetBroadcasterName().GetCString(), + event_mask, + got_requested_names ? " (" : "", + sstr_requested.GetData(), + got_requested_names ? ")" : "", + acquired_event_mask, + got_acquired_names ? " (" : "", + sstr_acquired.GetData(), + got_acquired_names ? ")" : ""); + } + else + { + log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p), event_mask=0x%8.8x) => 0x%8.8x", + m_opaque_ptr, + lldb_broadcaster, + event_mask, + acquired_event_mask); + + } + } + + return acquired_event_mask; +} + +bool +SBListener::StopListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask) +{ + if (m_opaque_ptr && broadcaster.IsValid()) + { + return m_opaque_ptr->StopListeningForEvents (broadcaster.get(), event_mask); + } + return false; +} + +bool +SBListener::WaitForEvent (uint32_t timeout_secs, SBEvent &event) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (timeout_secs == UINT32_MAX) + { + log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p))...", + m_opaque_ptr, event.get()); + } + else + { + log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p))...", + m_opaque_ptr, timeout_secs, event.get()); + } + } + bool success = false; + + if (m_opaque_ptr) + { + TimeValue time_value; + if (timeout_secs != UINT32_MAX) + { + assert (timeout_secs != 0); // Take this out after all calls with timeout set to zero have been removed.... + time_value = TimeValue::Now(); + time_value.OffsetWithSeconds (timeout_secs); + } + EventSP event_sp; + if (m_opaque_ptr->WaitForEvent (time_value.IsValid() ? &time_value : NULL, event_sp)) + { + event.reset (event_sp); + success = true; + } + } + + if (log) + { + if (timeout_secs == UINT32_MAX) + { + log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p)) => %i", + m_opaque_ptr, event.get(), success); + } + else + { + log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p)) => %i", + m_opaque_ptr, timeout_secs, event.get(), success); + } + } + if (!success) + event.reset (NULL); + return success; +} + +bool +SBListener::WaitForEventForBroadcaster +( + uint32_t num_seconds, + const SBBroadcaster &broadcaster, + SBEvent &event +) +{ + if (m_opaque_ptr && broadcaster.IsValid()) + { + TimeValue time_value; + if (num_seconds != UINT32_MAX) + { + time_value = TimeValue::Now(); + time_value.OffsetWithSeconds (num_seconds); + } + EventSP event_sp; + if (m_opaque_ptr->WaitForEventForBroadcaster (time_value.IsValid() ? &time_value : NULL, + broadcaster.get(), + event_sp)) + { + event.reset (event_sp); + return true; + } + + } + event.reset (NULL); + return false; +} + +bool +SBListener::WaitForEventForBroadcasterWithType +( + uint32_t num_seconds, + const SBBroadcaster &broadcaster, + uint32_t event_type_mask, + SBEvent &event +) +{ + if (m_opaque_ptr && broadcaster.IsValid()) + { + TimeValue time_value; + if (num_seconds != UINT32_MAX) + { + time_value = TimeValue::Now(); + time_value.OffsetWithSeconds (num_seconds); + } + EventSP event_sp; + if (m_opaque_ptr->WaitForEventForBroadcasterWithType (time_value.IsValid() ? &time_value : NULL, + broadcaster.get(), + event_type_mask, + event_sp)) + { + event.reset (event_sp); + return true; + } + } + event.reset (NULL); + return false; +} + +bool +SBListener::PeekAtNextEvent (SBEvent &event) +{ + if (m_opaque_ptr) + { + event.reset (m_opaque_ptr->PeekAtNextEvent ()); + return event.IsValid(); + } + event.reset (NULL); + return false; +} + +bool +SBListener::PeekAtNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event) +{ + if (m_opaque_ptr && broadcaster.IsValid()) + { + event.reset (m_opaque_ptr->PeekAtNextEventForBroadcaster (broadcaster.get())); + return event.IsValid(); + } + event.reset (NULL); + return false; +} + +bool +SBListener::PeekAtNextEventForBroadcasterWithType (const SBBroadcaster &broadcaster, uint32_t event_type_mask, + SBEvent &event) +{ + if (m_opaque_ptr && broadcaster.IsValid()) + { + event.reset(m_opaque_ptr->PeekAtNextEventForBroadcasterWithType (broadcaster.get(), event_type_mask)); + return event.IsValid(); + } + event.reset (NULL); + return false; +} + +bool +SBListener::GetNextEvent (SBEvent &event) +{ + if (m_opaque_ptr) + { + EventSP event_sp; + if (m_opaque_ptr->GetNextEvent (event_sp)) + { + event.reset (event_sp); + return true; + } + } + event.reset (NULL); + return false; +} + +bool +SBListener::GetNextEventForBroadcaster (const SBBroadcaster &broadcaster, SBEvent &event) +{ + if (m_opaque_ptr && broadcaster.IsValid()) + { + EventSP event_sp; + if (m_opaque_ptr->GetNextEventForBroadcaster (broadcaster.get(), event_sp)) + { + event.reset (event_sp); + return true; + } + } + event.reset (NULL); + return false; +} + +bool +SBListener::GetNextEventForBroadcasterWithType +( + const SBBroadcaster &broadcaster, + uint32_t event_type_mask, + SBEvent &event +) +{ + if (m_opaque_ptr && broadcaster.IsValid()) + { + EventSP event_sp; + if (m_opaque_ptr->GetNextEventForBroadcasterWithType (broadcaster.get(), + event_type_mask, + event_sp)) + { + event.reset (event_sp); + return true; + } + } + event.reset (NULL); + return false; +} + +bool +SBListener::HandleBroadcastEvent (const SBEvent &event) +{ + if (m_opaque_ptr) + return m_opaque_ptr->HandleBroadcastEvent (event.GetSP()); + return false; +} + +Listener * +SBListener::operator->() const +{ + return m_opaque_ptr; +} + +Listener * +SBListener::get() const +{ + return m_opaque_ptr; +} + +void +SBListener::reset(Listener *listener, bool owns) +{ + if (owns) + m_opaque_sp.reset (listener); + else + m_opaque_sp.reset (); + m_opaque_ptr = listener; +} + +Listener & +SBListener::ref() const +{ + return *m_opaque_ptr; +} + +Listener & +SBListener::operator *() +{ + return *m_opaque_ptr; +} + +const Listener & +SBListener::operator *() const +{ + return *m_opaque_ptr; +} + + diff --git a/source/API/SBModule.cpp b/source/API/SBModule.cpp new file mode 100644 index 000000000000..5f5fc9292cdb --- /dev/null +++ b/source/API/SBModule.cpp @@ -0,0 +1,655 @@ +//===-- SBModule.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/SBModule.h" +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBModuleSpec.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBSymbolContextList.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Core/ValueObjectList.h" +#include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/Symtab.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + + +SBModule::SBModule () : + m_opaque_sp () +{ +} + +SBModule::SBModule (const lldb::ModuleSP& module_sp) : + m_opaque_sp (module_sp) +{ +} + +SBModule::SBModule(const SBModuleSpec &module_spec) : + m_opaque_sp () +{ + ModuleSP module_sp; + Error error = ModuleList::GetSharedModule (*module_spec.m_opaque_ap, + module_sp, + NULL, + NULL, + NULL); + if (module_sp) + SetSP(module_sp); +} + +SBModule::SBModule(const SBModule &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr) : + m_opaque_sp () +{ + ProcessSP process_sp (process.GetSP()); + if (process_sp) + { + m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(), header_addr); + if (m_opaque_sp) + { + Target &target = process_sp->GetTarget(); + bool changed = false; + m_opaque_sp->SetLoadAddress(target, 0, changed); + target.GetImages().Append(m_opaque_sp); + } + } +} + +const SBModule & +SBModule::operator = (const SBModule &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +SBModule::~SBModule () +{ +} + +bool +SBModule::IsValid () const +{ + return m_opaque_sp.get() != NULL; +} + +void +SBModule::Clear() +{ + m_opaque_sp.reset(); +} + +SBFileSpec +SBModule::GetFileSpec () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBFileSpec file_spec; + ModuleSP module_sp (GetSP ()); + if (module_sp) + file_spec.SetFileSpec(module_sp->GetFileSpec()); + + if (log) + { + log->Printf ("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)", + module_sp.get(), file_spec.get()); + } + + return file_spec; +} + +lldb::SBFileSpec +SBModule::GetPlatformFileSpec () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBFileSpec file_spec; + ModuleSP module_sp (GetSP ()); + if (module_sp) + file_spec.SetFileSpec(module_sp->GetPlatformFileSpec()); + + if (log) + { + log->Printf ("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)", + module_sp.get(), file_spec.get()); + } + + return file_spec; + +} + +bool +SBModule::SetPlatformFileSpec (const lldb::SBFileSpec &platform_file) +{ + bool result = false; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + module_sp->SetPlatformFileSpec(*platform_file); + result = true; + } + + if (log) + { + log->Printf ("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s)) => %i", + module_sp.get(), + platform_file.get(), + platform_file->GetPath().c_str(), + result); + } + return result; +} + + + +const uint8_t * +SBModule::GetUUIDBytes () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const uint8_t *uuid_bytes = NULL; + ModuleSP module_sp (GetSP ()); + if (module_sp) + uuid_bytes = (const uint8_t *)module_sp->GetUUID().GetBytes(); + + if (log) + { + if (uuid_bytes) + { + StreamString s; + module_sp->GetUUID().Dump (&s); + log->Printf ("SBModule(%p)::GetUUIDBytes () => %s", module_sp.get(), s.GetData()); + } + else + log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", module_sp.get()); + } + return uuid_bytes; +} + + +const char * +SBModule::GetUUIDString () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + static char uuid_string_buffer[80]; + const char *uuid_c_string = NULL; + std::string uuid_string; + ModuleSP module_sp (GetSP ()); + if (module_sp) + uuid_string = module_sp->GetUUID().GetAsString(); + + if (!uuid_string.empty()) + { + strncpy (uuid_string_buffer, uuid_string.c_str(), sizeof (uuid_string_buffer)); + uuid_c_string = uuid_string_buffer; + } + + if (log) + { + if (!uuid_string.empty()) + { + StreamString s; + module_sp->GetUUID().Dump (&s); + log->Printf ("SBModule(%p)::GetUUIDString () => %s", module_sp.get(), s.GetData()); + } + else + log->Printf ("SBModule(%p)::GetUUIDString () => NULL", module_sp.get()); + } + return uuid_c_string; +} + + +bool +SBModule::operator == (const SBModule &rhs) const +{ + if (m_opaque_sp) + return m_opaque_sp.get() == rhs.m_opaque_sp.get(); + return false; +} + +bool +SBModule::operator != (const SBModule &rhs) const +{ + if (m_opaque_sp) + return m_opaque_sp.get() != rhs.m_opaque_sp.get(); + return false; +} + +ModuleSP +SBModule::GetSP () const +{ + return m_opaque_sp; +} + +void +SBModule::SetSP (const ModuleSP &module_sp) +{ + m_opaque_sp = module_sp; +} + +SBAddress +SBModule::ResolveFileAddress (lldb::addr_t vm_addr) +{ + lldb::SBAddress sb_addr; + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + Address addr; + if (module_sp->ResolveFileAddress (vm_addr, addr)) + sb_addr.ref() = addr; + } + return sb_addr; +} + +SBSymbolContext +SBModule::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope) +{ + SBSymbolContext sb_sc; + ModuleSP module_sp (GetSP ()); + if (module_sp && addr.IsValid()) + module_sp->ResolveSymbolContextForAddress (addr.ref(), resolve_scope, *sb_sc); + return sb_sc; +} + +bool +SBModule::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + module_sp->GetDescription (&strm); + } + else + strm.PutCString ("No value"); + + return true; +} + +uint32_t +SBModule::GetNumCompileUnits() +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + return module_sp->GetNumCompileUnits (); + } + return 0; +} + +SBCompileUnit +SBModule::GetCompileUnitAtIndex (uint32_t index) +{ + SBCompileUnit sb_cu; + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex (index); + sb_cu.reset(cu_sp.get()); + } + return sb_cu; +} + +static Symtab * +GetUnifiedSymbolTable (const lldb::ModuleSP& module_sp) +{ + if (module_sp) + { + SymbolVendor *symbols = module_sp->GetSymbolVendor(); + if (symbols) + return symbols->GetSymtab(); + } + return NULL; +} + +size_t +SBModule::GetNumSymbols () +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + Symtab *symtab = GetUnifiedSymbolTable (module_sp); + if (symtab) + return symtab->GetNumSymbols(); + } + return 0; +} + +SBSymbol +SBModule::GetSymbolAtIndex (size_t idx) +{ + SBSymbol sb_symbol; + ModuleSP module_sp (GetSP ()); + Symtab *symtab = GetUnifiedSymbolTable (module_sp); + if (symtab) + sb_symbol.SetSymbol(symtab->SymbolAtIndex (idx)); + return sb_symbol; +} + +lldb::SBSymbol +SBModule::FindSymbol (const char *name, + lldb::SymbolType symbol_type) +{ + SBSymbol sb_symbol; + if (name && name[0]) + { + ModuleSP module_sp (GetSP ()); + Symtab *symtab = GetUnifiedSymbolTable (module_sp); + if (symtab) + sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType(ConstString(name), symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny)); + } + return sb_symbol; +} + + +lldb::SBSymbolContextList +SBModule::FindSymbols (const char *name, lldb::SymbolType symbol_type) +{ + SBSymbolContextList sb_sc_list; + if (name && name[0]) + { + ModuleSP module_sp (GetSP ()); + Symtab *symtab = GetUnifiedSymbolTable (module_sp); + if (symtab) + { + std::vector<uint32_t> matching_symbol_indexes; + const size_t num_matches = symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type, matching_symbol_indexes); + if (num_matches) + { + SymbolContext sc; + sc.module_sp = module_sp; + SymbolContextList &sc_list = *sb_sc_list; + for (size_t i=0; i<num_matches; ++i) + { + sc.symbol = symtab->SymbolAtIndex (matching_symbol_indexes[i]); + if (sc.symbol) + sc_list.Append(sc); + } + } + } + } + return sb_sc_list; + +} + + + +size_t +SBModule::GetNumSections () +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + // Give the symbol vendor a chance to add to the unified section list. + module_sp->GetSymbolVendor(); + SectionList *section_list = module_sp->GetSectionList(); + if (section_list) + return section_list->GetSize(); + } + return 0; +} + +SBSection +SBModule::GetSectionAtIndex (size_t idx) +{ + SBSection sb_section; + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + // Give the symbol vendor a chance to add to the unified section list. + module_sp->GetSymbolVendor(); + SectionList *section_list = module_sp->GetSectionList (); + + if (section_list) + sb_section.SetSP(section_list->GetSectionAtIndex (idx)); + } + return sb_section; +} + +lldb::SBSymbolContextList +SBModule::FindFunctions (const char *name, + uint32_t name_type_mask) +{ + lldb::SBSymbolContextList sb_sc_list; + ModuleSP module_sp (GetSP ()); + if (name && module_sp) + { + const bool append = true; + const bool symbols_ok = true; + const bool inlines_ok = true; + module_sp->FindFunctions (ConstString(name), + NULL, + name_type_mask, + symbols_ok, + inlines_ok, + append, + *sb_sc_list); + } + return sb_sc_list; +} + + +SBValueList +SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches) +{ + SBValueList sb_value_list; + ModuleSP module_sp (GetSP ()); + if (name && module_sp) + { + VariableList variable_list; + const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name), + NULL, + false, + max_matches, + variable_list); + + if (match_count > 0) + { + for (uint32_t i=0; i<match_count; ++i) + { + lldb::ValueObjectSP valobj_sp; + TargetSP target_sp (target.GetSP()); + valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i)); + if (valobj_sp) + sb_value_list.Append(SBValue(valobj_sp)); + } + } + } + + return sb_value_list; +} + +lldb::SBValue +SBModule::FindFirstGlobalVariable (lldb::SBTarget &target, const char *name) +{ + SBValueList sb_value_list(FindGlobalVariables(target, name, 1)); + if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0) + return sb_value_list.GetValueAtIndex(0); + return SBValue(); +} + +lldb::SBType +SBModule::FindFirstType (const char *name_cstr) +{ + SBType sb_type; + ModuleSP module_sp (GetSP ()); + if (name_cstr && module_sp) + { + SymbolContext sc; + const bool exact_match = false; + ConstString name(name_cstr); + + sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match)); + + if (!sb_type.IsValid()) + sb_type = SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name)); + } + return sb_type; +} + +lldb::SBType +SBModule::GetBasicType(lldb::BasicType type) +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + return SBType (ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type)); + return SBType(); +} + +lldb::SBTypeList +SBModule::FindTypes (const char *type) +{ + SBTypeList retval; + + ModuleSP module_sp (GetSP ()); + if (type && module_sp) + { + SymbolContext sc; + TypeList type_list; + const bool exact_match = false; + ConstString name(type); + const uint32_t num_matches = module_sp->FindTypes (sc, + name, + exact_match, + UINT32_MAX, + type_list); + + if (num_matches > 0) + { + for (size_t idx = 0; idx < num_matches; idx++) + { + TypeSP type_sp (type_list.GetTypeAtIndex(idx)); + if (type_sp) + retval.Append(SBType(type_sp)); + } + } + else + { + SBType sb_type(ClangASTContext::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name)); + if (sb_type.IsValid()) + retval.Append(sb_type); + } + } + + return retval; +} + +lldb::SBTypeList +SBModule::GetTypes (uint32_t type_mask) +{ + SBTypeList sb_type_list; + + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + SymbolVendor* vendor = module_sp->GetSymbolVendor(); + if (vendor) + { + TypeList type_list; + vendor->GetTypes (NULL, type_mask, type_list); + sb_type_list.m_opaque_ap->Append(type_list); + } + } + return sb_type_list; +} + +SBSection +SBModule::FindSection (const char *sect_name) +{ + SBSection sb_section; + + ModuleSP module_sp (GetSP ()); + if (sect_name && module_sp) + { + // Give the symbol vendor a chance to add to the unified section list. + module_sp->GetSymbolVendor(); + SectionList *section_list = module_sp->GetSectionList(); + if (section_list) + { + ConstString const_sect_name(sect_name); + SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); + if (section_sp) + { + sb_section.SetSP (section_sp); + } + } + } + return sb_section; +} + +lldb::ByteOrder +SBModule::GetByteOrder () +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + return module_sp->GetArchitecture().GetByteOrder(); + return eByteOrderInvalid; +} + +const char * +SBModule::GetTriple () +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + std::string triple (module_sp->GetArchitecture().GetTriple().str()); + // Unique the string so we don't run into ownership issues since + // the const strings put the string into the string pool once and + // the strings never comes out + ConstString const_triple (triple.c_str()); + return const_triple.GetCString(); + } + return NULL; +} + +uint32_t +SBModule::GetAddressByteSize() +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + return module_sp->GetArchitecture().GetAddressByteSize(); + return sizeof(void*); +} + + +uint32_t +SBModule::GetVersion (uint32_t *versions, uint32_t num_versions) +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + return module_sp->GetVersion(versions, num_versions); + else + { + if (versions && num_versions) + { + for (uint32_t i=0; i<num_versions; ++i) + versions[i] = UINT32_MAX; + } + return 0; + } +} + diff --git a/source/API/SBModuleSpec.cpp b/source/API/SBModuleSpec.cpp new file mode 100644 index 000000000000..654a8ca6ec86 --- /dev/null +++ b/source/API/SBModuleSpec.cpp @@ -0,0 +1,230 @@ +//===-- SBModuleSpec.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/SBModuleSpec.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/Stream.h" +#include "lldb/Host/Host.h" +#include "lldb/Symbol/ObjectFile.h" + +using namespace lldb; +using namespace lldb_private; + + +SBModuleSpec::SBModuleSpec () : + m_opaque_ap (new lldb_private::ModuleSpec()) +{ +} + +SBModuleSpec::SBModuleSpec(const SBModuleSpec &rhs) : + m_opaque_ap (new lldb_private::ModuleSpec(*rhs.m_opaque_ap)) +{ +} + +const SBModuleSpec & +SBModuleSpec::operator = (const SBModuleSpec &rhs) +{ + if (this != &rhs) + *m_opaque_ap = *(rhs.m_opaque_ap); + return *this; +} + +SBModuleSpec::~SBModuleSpec () +{ +} + +bool +SBModuleSpec::IsValid () const +{ + return *m_opaque_ap; +} + +void +SBModuleSpec::Clear() +{ + m_opaque_ap->Clear(); +} + +SBFileSpec +SBModuleSpec::GetFileSpec () +{ + SBFileSpec sb_spec(m_opaque_ap->GetFileSpec()); + return sb_spec; +} + +void +SBModuleSpec::SetFileSpec (const lldb::SBFileSpec &sb_spec) +{ + m_opaque_ap->GetFileSpec() = *sb_spec; +} + +lldb::SBFileSpec +SBModuleSpec::GetPlatformFileSpec () +{ + return SBFileSpec(m_opaque_ap->GetPlatformFileSpec()); +} + +void +SBModuleSpec::SetPlatformFileSpec (const lldb::SBFileSpec &sb_spec) +{ + m_opaque_ap->GetPlatformFileSpec() = *sb_spec; +} + +lldb::SBFileSpec +SBModuleSpec::GetSymbolFileSpec () +{ + return SBFileSpec(m_opaque_ap->GetSymbolFileSpec()); +} + +void +SBModuleSpec::SetSymbolFileSpec (const lldb::SBFileSpec &sb_spec) +{ + m_opaque_ap->GetSymbolFileSpec() = *sb_spec; +} + +const char * +SBModuleSpec::GetObjectName () +{ + return m_opaque_ap->GetObjectName().GetCString(); +} + +void +SBModuleSpec::SetObjectName (const char *name) +{ + m_opaque_ap->GetObjectName().SetCString(name); +} + +const char * +SBModuleSpec::GetTriple () +{ + std::string triple (m_opaque_ap->GetArchitecture().GetTriple().str()); + // Unique the string so we don't run into ownership issues since + // the const strings put the string into the string pool once and + // the strings never comes out + ConstString const_triple (triple.c_str()); + return const_triple.GetCString(); +} + +void +SBModuleSpec::SetTriple (const char *triple) +{ + m_opaque_ap->GetArchitecture().SetTriple(triple); +} + +const uint8_t * +SBModuleSpec::GetUUIDBytes () +{ + return (const uint8_t *)m_opaque_ap->GetUUID().GetBytes(); +} + +size_t +SBModuleSpec::GetUUIDLength () +{ + return m_opaque_ap->GetUUID().GetByteSize(); +} + +bool +SBModuleSpec::SetUUIDBytes (const uint8_t *uuid, size_t uuid_len) +{ + return m_opaque_ap->GetUUID().SetBytes(uuid, uuid_len); +} + +bool +SBModuleSpec::GetDescription (lldb::SBStream &description) +{ + m_opaque_ap->Dump (description.ref()); + return true; +} + +SBModuleSpecList::SBModuleSpecList() : + m_opaque_ap(new ModuleSpecList()) +{ + +} + +SBModuleSpecList::SBModuleSpecList (const SBModuleSpecList &rhs) : + m_opaque_ap(new ModuleSpecList(*rhs.m_opaque_ap)) +{ + +} + +SBModuleSpecList & +SBModuleSpecList::operator = (const SBModuleSpecList &rhs) +{ + if (this != &rhs) + *m_opaque_ap = *rhs.m_opaque_ap; + return *this; +} + +SBModuleSpecList::~SBModuleSpecList() +{ + +} + +SBModuleSpecList +SBModuleSpecList::GetModuleSpecifications (const char *path) +{ + SBModuleSpecList specs; + FileSpec file_spec(path, true); + Host::ResolveExecutableInBundle(file_spec); + ObjectFile::GetModuleSpecifications(file_spec, 0, 0, *specs.m_opaque_ap); + return specs; +} + +void +SBModuleSpecList::Append (const SBModuleSpec &spec) +{ + m_opaque_ap->Append (*spec.m_opaque_ap); +} + +void +SBModuleSpecList::Append (const SBModuleSpecList &spec_list) +{ + m_opaque_ap->Append (*spec_list.m_opaque_ap); +} + +size_t +SBModuleSpecList::GetSize() +{ + return m_opaque_ap->GetSize(); +} + +SBModuleSpec +SBModuleSpecList::GetSpecAtIndex (size_t i) +{ + SBModuleSpec sb_module_spec; + m_opaque_ap->GetModuleSpecAtIndex(i, *sb_module_spec.m_opaque_ap); + return sb_module_spec; +} + +SBModuleSpec +SBModuleSpecList::FindFirstMatchingSpec (const SBModuleSpec &match_spec) +{ + SBModuleSpec sb_module_spec; + m_opaque_ap->FindMatchingModuleSpec(*match_spec.m_opaque_ap, *sb_module_spec.m_opaque_ap); + return sb_module_spec; +} + +SBModuleSpecList +SBModuleSpecList::FindMatchingSpecs (const SBModuleSpec &match_spec) +{ + SBModuleSpecList specs; + m_opaque_ap->FindMatchingModuleSpecs(*match_spec.m_opaque_ap, *specs.m_opaque_ap); + return specs; + +} + +bool +SBModuleSpecList::GetDescription (lldb::SBStream &description) +{ + m_opaque_ap->Dump (description.ref()); + return true; +} diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp new file mode 100644 index 000000000000..259eb5e97034 --- /dev/null +++ b/source/API/SBProcess.cpp @@ -0,0 +1,1256 @@ +//===-- SBProcess.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/lldb-python.h" + +#include "lldb/API/SBProcess.h" + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-types.h" + +#include "lldb/Interpreter/Args.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/State.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" + +// Project includes + +#include "lldb/API/SBBroadcaster.h" +#include "lldb/API/SBCommandReturnObject.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBThread.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" + +using namespace lldb; +using namespace lldb_private; + + +SBProcess::SBProcess () : + m_opaque_wp() +{ +} + + +//---------------------------------------------------------------------- +// SBProcess constructor +//---------------------------------------------------------------------- + +SBProcess::SBProcess (const SBProcess& rhs) : + m_opaque_wp (rhs.m_opaque_wp) +{ +} + + +SBProcess::SBProcess (const lldb::ProcessSP &process_sp) : + m_opaque_wp (process_sp) +{ +} + +const SBProcess& +SBProcess::operator = (const SBProcess& rhs) +{ + if (this != &rhs) + m_opaque_wp = rhs.m_opaque_wp; + return *this; +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBProcess::~SBProcess() +{ +} + +const char * +SBProcess::GetBroadcasterClassName () +{ + return Process::GetStaticBroadcasterClass().AsCString(); +} + +const char * +SBProcess::GetPluginName () +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + return process_sp->GetPluginName().GetCString(); + } + return "<Unknown>"; +} + +const char * +SBProcess::GetShortPluginName () +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + return process_sp->GetPluginName().GetCString(); + } + return "<Unknown>"; +} + + +lldb::ProcessSP +SBProcess::GetSP() const +{ + return m_opaque_wp.lock(); +} + +void +SBProcess::SetSP (const ProcessSP &process_sp) +{ + m_opaque_wp = process_sp; +} + +void +SBProcess::Clear () +{ + m_opaque_wp.reset(); +} + + +bool +SBProcess::IsValid() const +{ + ProcessSP process_sp(m_opaque_wp.lock()); + return ((bool) process_sp && process_sp->IsValid()); +} + +bool +SBProcess::RemoteLaunch (char const **argv, + char const **envp, + const char *stdin_path, + const char *stdout_path, + const char *stderr_path, + const char *working_directory, + uint32_t launch_flags, + bool stop_at_entry, + lldb::SBError& error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) { + log->Printf ("SBProcess(%p)::RemoteLaunch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...", + m_opaque_wp.lock().get(), + argv, + envp, + stdin_path ? stdin_path : "NULL", + stdout_path ? stdout_path : "NULL", + stderr_path ? stderr_path : "NULL", + working_directory ? working_directory : "NULL", + launch_flags, + stop_at_entry, + error.get()); + } + + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + if (process_sp->GetState() == eStateConnected) + { + if (stop_at_entry) + launch_flags |= eLaunchFlagStopAtEntry; + ProcessLaunchInfo launch_info (stdin_path, + stdout_path, + stderr_path, + working_directory, + launch_flags); + Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer(); + if (exe_module) + launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); + if (argv) + launch_info.GetArguments().AppendArguments (argv); + if (envp) + launch_info.GetEnvironmentEntries ().SetArguments (envp); + error.SetError (process_sp->Launch (launch_info)); + } + else + { + error.SetErrorString ("must be in eStateConnected to call RemoteLaunch"); + } + } + else + { + error.SetErrorString ("unable to attach pid"); + } + + if (log) { + SBStream sstr; + error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::RemoteLaunch (...) => SBError (%p): %s", process_sp.get(), error.get(), sstr.GetData()); + } + + return error.Success(); +} + +bool +SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + if (process_sp->GetState() == eStateConnected) + { + ProcessAttachInfo attach_info; + attach_info.SetProcessID (pid); + error.SetError (process_sp->Attach (attach_info)); + } + else + { + error.SetErrorString ("must be in eStateConnected to call RemoteAttachToProcessWithID"); + } + } + else + { + error.SetErrorString ("unable to attach pid"); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) { + SBStream sstr; + error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::RemoteAttachToProcessWithID (%" PRIu64 ") => SBError (%p): %s", process_sp.get(), pid, error.get(), sstr.GetData()); + } + + return error.Success(); +} + + +uint32_t +SBProcess::GetNumThreads () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num_threads = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + num_threads = process_sp->GetThreadList().GetSize(can_update); + } + + if (log) + log->Printf ("SBProcess(%p)::GetNumThreads () => %d", process_sp.get(), num_threads); + + return num_threads; +} + +SBThread +SBProcess::GetSelectedThread () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + thread_sp = process_sp->GetThreadList().GetSelectedThread(); + sb_thread.SetThread (thread_sp); + } + + if (log) + { + log->Printf ("SBProcess(%p)::GetSelectedThread () => SBThread(%p)", process_sp.get(), thread_sp.get()); + } + + return sb_thread; +} + +SBThread +SBProcess::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + thread_sp = process_sp->CreateOSPluginThread(tid, context); + sb_thread.SetThread (thread_sp); + } + + if (log) + log->Printf ("SBProcess(%p)::CreateOSPluginThread (tid=0x%" PRIx64 ", context=0x%" PRIx64 ") => SBThread(%p)", process_sp.get(), tid, context, thread_sp.get()); + + return sb_thread; +} + +SBTarget +SBProcess::GetTarget() const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBTarget sb_target; + TargetSP target_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + target_sp = process_sp->GetTarget().shared_from_this(); + sb_target.SetSP (target_sp); + } + + if (log) + log->Printf ("SBProcess(%p)::GetTarget () => SBTarget(%p)", process_sp.get(), target_sp.get()); + + return sb_target; +} + + +size_t +SBProcess::PutSTDIN (const char *src, size_t src_len) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + size_t ret_val = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Error error; + ret_val = process_sp->PutSTDIN (src, src_len, error); + } + + if (log) + log->Printf ("SBProcess(%p)::PutSTDIN (src=\"%s\", src_len=%d) => %lu", + process_sp.get(), + src, + (uint32_t) src_len, + ret_val); + + return ret_val; +} + +size_t +SBProcess::GetSTDOUT (char *dst, size_t dst_len) const +{ + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Error error; + bytes_read = process_sp->GetSTDOUT (dst, dst_len, error); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetSTDOUT (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64, + process_sp.get(), + (int) bytes_read, + dst, + (uint64_t)dst_len, + (uint64_t)bytes_read); + + return bytes_read; +} + +size_t +SBProcess::GetSTDERR (char *dst, size_t dst_len) const +{ + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Error error; + bytes_read = process_sp->GetSTDERR (dst, dst_len, error); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetSTDERR (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64, + process_sp.get(), + (int) bytes_read, + dst, + (uint64_t)dst_len, + (uint64_t)bytes_read); + + return bytes_read; +} + +size_t +SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const +{ + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Error error; + bytes_read = process_sp->GetAsyncProfileData (dst, dst_len, error); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetProfileData (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64, + process_sp.get(), + (int) bytes_read, + dst, + (uint64_t)dst_len, + (uint64_t)bytes_read); + + return bytes_read; +} + +void +SBProcess::ReportEventState (const SBEvent &event, FILE *out) const +{ + if (out == NULL) + return; + + ProcessSP process_sp(GetSP()); + if (process_sp) + { + const StateType event_state = SBProcess::GetStateFromEvent (event); + char message[1024]; + int message_len = ::snprintf (message, + sizeof (message), + "Process %" PRIu64 " %s\n", + process_sp->GetID(), + SBDebugger::StateAsCString (event_state)); + + if (message_len > 0) + ::fwrite (message, 1, message_len, out); + } +} + +void +SBProcess::AppendEventStateReport (const SBEvent &event, SBCommandReturnObject &result) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + const StateType event_state = SBProcess::GetStateFromEvent (event); + char message[1024]; + ::snprintf (message, + sizeof (message), + "Process %" PRIu64 " %s\n", + process_sp->GetID(), + SBDebugger::StateAsCString (event_state)); + + result.AppendMessage (message); + } +} + +bool +SBProcess::SetSelectedThread (const SBThread &thread) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + return process_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID()); + } + return false; +} + +bool +SBProcess::SetSelectedThreadByID (lldb::tid_t tid) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool ret_val = false; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + ret_val = process_sp->GetThreadList().SetSelectedThreadByID (tid); + } + + if (log) + log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%4.4" PRIx64 ") => %s", + process_sp.get(), tid, (ret_val ? "true" : "false")); + + return ret_val; +} + +bool +SBProcess::SetSelectedThreadByIndexID (uint32_t index_id) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool ret_val = false; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + ret_val = process_sp->GetThreadList().SetSelectedThreadByIndexID (index_id); + } + + if (log) + log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%x) => %s", + process_sp.get(), index_id, (ret_val ? "true" : "false")); + + return ret_val; +} + +SBThread +SBProcess::GetThreadAtIndex (size_t index) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + thread_sp = process_sp->GetThreadList().GetThreadAtIndex(index, can_update); + sb_thread.SetThread (thread_sp); + } + + if (log) + { + log->Printf ("SBProcess(%p)::GetThreadAtIndex (index=%d) => SBThread(%p)", + process_sp.get(), (uint32_t) index, thread_sp.get()); + } + + return sb_thread; +} + +uint32_t +SBProcess::GetStopID(bool include_expression_stops) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + if (include_expression_stops) + return process_sp->GetStopID(); + else + return process_sp->GetLastNaturalStopID(); + } + return 0; +} + +StateType +SBProcess::GetState () +{ + + StateType ret_val = eStateInvalid; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + ret_val = process_sp->GetState(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetState () => %s", + process_sp.get(), + lldb_private::StateAsCString (ret_val)); + + return ret_val; +} + + +int +SBProcess::GetExitStatus () +{ + int exit_status = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + exit_status = process_sp->GetExitStatus (); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetExitStatus () => %i (0x%8.8x)", + process_sp.get(), exit_status, exit_status); + + return exit_status; +} + +const char * +SBProcess::GetExitDescription () +{ + const char *exit_desc = NULL; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + exit_desc = process_sp->GetExitDescription (); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetExitDescription () => %s", + process_sp.get(), exit_desc); + return exit_desc; +} + +lldb::pid_t +SBProcess::GetProcessID () +{ + lldb::pid_t ret_val = LLDB_INVALID_PROCESS_ID; + ProcessSP process_sp(GetSP()); + if (process_sp) + ret_val = process_sp->GetID(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetProcessID () => %" PRIu64, process_sp.get(), ret_val); + + return ret_val; +} + +uint32_t +SBProcess::GetUniqueID() +{ + uint32_t ret_val = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + ret_val = process_sp->GetUniqueID(); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetUniqueID () => %" PRIu32, process_sp.get(), ret_val); + return ret_val; +} + +ByteOrder +SBProcess::GetByteOrder () const +{ + ByteOrder byteOrder = eByteOrderInvalid; + ProcessSP process_sp(GetSP()); + if (process_sp) + byteOrder = process_sp->GetTarget().GetArchitecture().GetByteOrder(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetByteOrder () => %d", process_sp.get(), byteOrder); + + return byteOrder; +} + +uint32_t +SBProcess::GetAddressByteSize () const +{ + uint32_t size = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + size = process_sp->GetTarget().GetArchitecture().GetAddressByteSize(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::GetAddressByteSize () => %d", process_sp.get(), size); + + return size; +} + +SBError +SBProcess::Continue () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBError sb_error; + ProcessSP process_sp(GetSP()); + + if (log) + log->Printf ("SBProcess(%p)::Continue ()...", process_sp.get()); + + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + + Error error (process_sp->Resume()); + if (error.Success()) + { + if (process_sp->GetTarget().GetDebugger().GetAsyncExecution () == false) + { + if (log) + log->Printf ("SBProcess(%p)::Continue () waiting for process to stop...", process_sp.get()); + process_sp->WaitForProcessToStop (NULL); + } + } + sb_error.SetError(error); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Continue () => SBError (%p): %s", process_sp.get(), sb_error.get(), sstr.GetData()); + } + + return sb_error; +} + + +SBError +SBProcess::Destroy () +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError(process_sp->Destroy()); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Destroy () => SBError (%p): %s", + process_sp.get(), + sb_error.get(), + sstr.GetData()); + } + + return sb_error; +} + + +SBError +SBProcess::Stop () +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->Halt()); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Stop () => SBError (%p): %s", + process_sp.get(), + sb_error.get(), + sstr.GetData()); + } + + return sb_error; +} + +SBError +SBProcess::Kill () +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->Destroy()); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Kill () => SBError (%p): %s", + process_sp.get(), + sb_error.get(), + sstr.GetData()); + } + + return sb_error; +} + +SBError +SBProcess::Detach () +{ + // FIXME: This should come from a process default. + bool keep_stopped = false; + return Detach (keep_stopped); +} + +SBError +SBProcess::Detach (bool keep_stopped) +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->Detach(keep_stopped)); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + return sb_error; +} + +SBError +SBProcess::Signal (int signo) +{ + SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->Signal (signo)); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Signal (signo=%i) => SBError (%p): %s", + process_sp.get(), + signo, + sb_error.get(), + sstr.GetData()); + } + return sb_error; +} + +void +SBProcess::SendAsyncInterrupt () +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + process_sp->SendAsyncInterrupt (); + } +} + +SBThread +SBProcess::GetThreadByID (tid_t tid) +{ + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + Process::StopLocker stop_locker; + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); + thread_sp = process_sp->GetThreadList().FindThreadByID (tid, can_update); + sb_thread.SetThread (thread_sp); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4" PRIx64 ") => SBThread (%p)", + process_sp.get(), + tid, + thread_sp.get()); + } + + return sb_thread; +} + +SBThread +SBProcess::GetThreadByIndexID (uint32_t index_id) +{ + SBThread sb_thread; + ThreadSP thread_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + Process::StopLocker stop_locker; + const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock()); + thread_sp = process_sp->GetThreadList().FindThreadByIndexID (index_id, can_update); + sb_thread.SetThread (thread_sp); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%x) => SBThread (%p)", + process_sp.get(), + index_id, + thread_sp.get()); + } + + return sb_thread; +} + +StateType +SBProcess::GetStateFromEvent (const SBEvent &event) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + StateType ret_val = Process::ProcessEventData::GetStateFromEvent (event.get()); + + if (log) + log->Printf ("SBProcess::GetStateFromEvent (event.sp=%p) => %s", event.get(), + lldb_private::StateAsCString (ret_val)); + + return ret_val; +} + +bool +SBProcess::GetRestartedFromEvent (const SBEvent &event) +{ + return Process::ProcessEventData::GetRestartedFromEvent (event.get()); +} + +size_t +SBProcess::GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event) +{ + return Process::ProcessEventData::GetNumRestartedReasons(event.get()); +} + +const char * +SBProcess::GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx) +{ + return Process::ProcessEventData::GetRestartedReasonAtIndex(event.get(), idx); +} + +SBProcess +SBProcess::GetProcessFromEvent (const SBEvent &event) +{ + SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get())); + return process; +} + +bool +SBProcess::EventIsProcessEvent (const SBEvent &event) +{ + return strcmp (event.GetBroadcasterClass(), SBProcess::GetBroadcasterClass()) == 0; +} + +SBBroadcaster +SBProcess::GetBroadcaster () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ProcessSP process_sp(GetSP()); + + SBBroadcaster broadcaster(process_sp.get(), false); + + if (log) + log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)", process_sp.get(), + broadcaster.get()); + + return broadcaster; +} + +const char * +SBProcess::GetBroadcasterClass () +{ + return Process::GetStaticBroadcasterClass().AsCString(); +} + +size_t +SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + size_t bytes_read = 0; + + ProcessSP process_sp(GetSP()); + + if (log) + { + log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p))...", + process_sp.get(), + addr, + dst, + (uint64_t)dst_len, + sb_error.get()); + } + + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + bytes_read = process_sp->ReadMemory (addr, dst, dst_len, sb_error.ref()); + } + else + { + if (log) + log->Printf ("SBProcess(%p)::ReadMemory() => error: process is running", process_sp.get()); + sb_error.SetErrorString("process is running"); + } + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64, + process_sp.get(), + addr, + dst, + (uint64_t)dst_len, + sb_error.get(), + sstr.GetData(), + (uint64_t)bytes_read); + } + + return bytes_read; +} + +size_t +SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &sb_error) +{ + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + bytes_read = process_sp->ReadCStringFromMemory (addr, (char *)buf, size, sb_error.ref()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::ReadCStringFromMemory() => error: process is running", process_sp.get()); + sb_error.SetErrorString("process is running"); + } + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return bytes_read; +} + +uint64_t +SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &sb_error) +{ + uint64_t value = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + value = process_sp->ReadUnsignedIntegerFromMemory (addr, byte_size, 0, sb_error.ref()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::ReadUnsignedFromMemory() => error: process is running", process_sp.get()); + sb_error.SetErrorString("process is running"); + } + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return value; +} + +lldb::addr_t +SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &sb_error) +{ + lldb::addr_t ptr = LLDB_INVALID_ADDRESS; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + ptr = process_sp->ReadPointerFromMemory (addr, sb_error.ref()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::ReadPointerFromMemory() => error: process is running", process_sp.get()); + sb_error.SetErrorString("process is running"); + } + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return ptr; +} + +size_t +SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error) +{ + size_t bytes_written = 0; + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ProcessSP process_sp(GetSP()); + + if (log) + { + log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p))...", + process_sp.get(), + addr, + src, + (uint64_t)src_len, + sb_error.get()); + } + + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + bytes_written = process_sp->WriteMemory (addr, src, src_len, sb_error.ref()); + } + else + { + if (log) + log->Printf ("SBProcess(%p)::WriteMemory() => error: process is running", process_sp.get()); + sb_error.SetErrorString("process is running"); + } + } + + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64, + process_sp.get(), + addr, + src, + (uint64_t)src_len, + sb_error.get(), + sstr.GetData(), + (uint64_t)bytes_written); + } + + return bytes_written; +} + +bool +SBProcess::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + ProcessSP process_sp(GetSP()); + if (process_sp) + { + char path[PATH_MAX]; + GetTarget().GetExecutable().GetPath (path, sizeof(path)); + Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer(); + const char *exe_name = NULL; + if (exe_module) + exe_name = exe_module->GetFileSpec().GetFilename().AsCString(); + + strm.Printf ("SBProcess: pid = %" PRIu64 ", state = %s, threads = %d%s%s", + process_sp->GetID(), + lldb_private::StateAsCString (GetState()), + GetNumThreads(), + exe_name ? ", executable = " : "", + exe_name ? exe_name : ""); + } + else + strm.PutCString ("No value"); + + return true; +} + +uint32_t +SBProcess::GetNumSupportedHardwareWatchpoints (lldb::SBError &sb_error) const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError(process_sp->GetWatchpointSupportInfo (num)); + if (log) + log->Printf ("SBProcess(%p)::GetNumSupportedHardwareWatchpoints () => %u", + process_sp.get(), num); + } + else + { + sb_error.SetErrorString ("SBProcess is invalid"); + } + return num; +} + +uint32_t +SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error) +{ + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + return process_sp->LoadImage (*sb_image_spec, sb_error.ref()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::LoadImage() => error: process is running", process_sp.get()); + sb_error.SetErrorString("process is running"); + } + } + return LLDB_INVALID_IMAGE_TOKEN; +} + +lldb::SBError +SBProcess::UnloadImage (uint32_t image_token) +{ + lldb::SBError sb_error; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process_sp->GetRunLock())) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + sb_error.SetError (process_sp->UnloadImage (image_token)); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::UnloadImage() => error: process is running", process_sp.get()); + sb_error.SetErrorString("process is running"); + } + } + else + sb_error.SetErrorString("invalid process"); + return sb_error; +} diff --git a/source/API/SBSection.cpp b/source/API/SBSection.cpp new file mode 100644 index 000000000000..3fb84e81465c --- /dev/null +++ b/source/API/SBSection.cpp @@ -0,0 +1,291 @@ +//===-- SBSection.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/SBSection.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBTarget.h" +#include "lldb/Core/DataBuffer.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Symbol/ObjectFile.h" + + +using namespace lldb; +using namespace lldb_private; + + +SBSection::SBSection () : + m_opaque_wp () +{ +} + +SBSection::SBSection (const SBSection &rhs) : + m_opaque_wp (rhs.m_opaque_wp) +{ +} + + + +SBSection::SBSection (const lldb::SectionSP §ion_sp) : + m_opaque_wp () // Don't init with section_sp otherwise this will throw if section_sp doesn't contain a valid Section * +{ + if (section_sp) + m_opaque_wp = section_sp; +} + +const SBSection & +SBSection::operator = (const SBSection &rhs) +{ + m_opaque_wp = rhs.m_opaque_wp; + return *this; +} + +SBSection::~SBSection () +{ +} + +bool +SBSection::IsValid () const +{ + SectionSP section_sp (GetSP()); + return section_sp && section_sp->GetModule().get() != NULL; +} + +const char * +SBSection::GetName () +{ + SectionSP section_sp (GetSP()); + if (section_sp) + return section_sp->GetName().GetCString(); + return NULL; +} + +lldb::SBSection +SBSection::GetParent() +{ + lldb::SBSection sb_section; + SectionSP section_sp (GetSP()); + if (section_sp) + { + SectionSP parent_section_sp (section_sp->GetParent()); + if (parent_section_sp) + sb_section.SetSP(parent_section_sp); + } + return sb_section; +} + + +lldb::SBSection +SBSection::FindSubSection (const char *sect_name) +{ + lldb::SBSection sb_section; + if (sect_name) + { + SectionSP section_sp (GetSP()); + if (section_sp) + { + ConstString const_sect_name(sect_name); + sb_section.SetSP(section_sp->GetChildren ().FindSectionByName(const_sect_name)); + } + } + return sb_section; +} + +size_t +SBSection::GetNumSubSections () +{ + SectionSP section_sp (GetSP()); + if (section_sp) + return section_sp->GetChildren ().GetSize(); + return 0; +} + +lldb::SBSection +SBSection::GetSubSectionAtIndex (size_t idx) +{ + lldb::SBSection sb_section; + SectionSP section_sp (GetSP()); + if (section_sp) + sb_section.SetSP (section_sp->GetChildren ().GetSectionAtIndex(idx)); + return sb_section; +} + +lldb::SectionSP +SBSection::GetSP() const +{ + return m_opaque_wp.lock(); +} + +void +SBSection::SetSP(const lldb::SectionSP §ion_sp) +{ + m_opaque_wp = section_sp; +} + +lldb::addr_t +SBSection::GetFileAddress () +{ + lldb::addr_t file_addr = LLDB_INVALID_ADDRESS; + SectionSP section_sp (GetSP()); + if (section_sp) + return section_sp->GetFileAddress(); + return file_addr; +} + +lldb::addr_t +SBSection::GetLoadAddress (lldb::SBTarget &sb_target) +{ + TargetSP target_sp(sb_target.GetSP()); + if (target_sp) + { + SectionSP section_sp (GetSP()); + if (section_sp) + return section_sp->GetLoadBaseAddress(target_sp.get()); + } + return LLDB_INVALID_ADDRESS; + +} + + + +lldb::addr_t +SBSection::GetByteSize () +{ + SectionSP section_sp (GetSP()); + if (section_sp) + return section_sp->GetByteSize(); + return 0; +} + +uint64_t +SBSection::GetFileOffset () +{ + SectionSP section_sp (GetSP()); + if (section_sp) + { + ModuleSP module_sp (section_sp->GetModule()); + if (module_sp) + { + ObjectFile *objfile = module_sp->GetObjectFile(); + if (objfile) + return objfile->GetFileOffset() + section_sp->GetFileOffset(); + } + } + return UINT64_MAX; +} + +uint64_t +SBSection::GetFileByteSize () +{ + SectionSP section_sp (GetSP()); + if (section_sp) + return section_sp->GetFileSize(); + return 0; +} + +SBData +SBSection::GetSectionData () +{ + return GetSectionData (0, UINT64_MAX); +} + +SBData +SBSection::GetSectionData (uint64_t offset, uint64_t size) +{ + SBData sb_data; + SectionSP section_sp (GetSP()); + if (section_sp) + { + const uint64_t sect_file_size = section_sp->GetFileSize(); + if (sect_file_size > 0) + { + ModuleSP module_sp (section_sp->GetModule()); + if (module_sp) + { + ObjectFile *objfile = module_sp->GetObjectFile(); + if (objfile) + { + const uint64_t sect_file_offset = objfile->GetFileOffset() + section_sp->GetFileOffset(); + const uint64_t file_offset = sect_file_offset + offset; + uint64_t file_size = size; + if (file_size == UINT64_MAX) + { + file_size = section_sp->GetByteSize(); + if (file_size > offset) + file_size -= offset; + else + file_size = 0; + } + DataBufferSP data_buffer_sp (objfile->GetFileSpec().ReadFileContents (file_offset, file_size)); + if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) + { + DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp, + objfile->GetByteOrder(), + objfile->GetAddressByteSize())); + + sb_data.SetOpaque (data_extractor_sp); + } + } + } + } + } + return sb_data; +} + +SectionType +SBSection::GetSectionType () +{ + SectionSP section_sp (GetSP()); + if (section_sp.get()) + return section_sp->GetType(); + return eSectionTypeInvalid; +} + + +bool +SBSection::operator == (const SBSection &rhs) +{ + SectionSP lhs_section_sp (GetSP()); + SectionSP rhs_section_sp (rhs.GetSP()); + if (lhs_section_sp && rhs_section_sp) + return lhs_section_sp == rhs_section_sp; + return false; +} + +bool +SBSection::operator != (const SBSection &rhs) +{ + SectionSP lhs_section_sp (GetSP()); + SectionSP rhs_section_sp (rhs.GetSP()); + return lhs_section_sp != rhs_section_sp; +} + +bool +SBSection::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + SectionSP section_sp (GetSP()); + if (section_sp) + { + const addr_t file_addr = section_sp->GetFileAddress(); + strm.Printf ("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr, file_addr + section_sp->GetByteSize()); + section_sp->DumpName(&strm); + } + else + { + strm.PutCString ("No value"); + } + + return true; +} + diff --git a/source/API/SBSourceManager.cpp b/source/API/SBSourceManager.cpp new file mode 100644 index 000000000000..0b8cbfceda0f --- /dev/null +++ b/source/API/SBSourceManager.cpp @@ -0,0 +1,146 @@ +//===-- SBSourceManager.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/lldb-python.h" + +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBSourceManager.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBStream.h" + +#include "lldb/API/SBFileSpec.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/SourceManager.h" + +#include "lldb/Target/Target.h" + +namespace lldb_private +{ + class SourceManagerImpl + { + public: + SourceManagerImpl (const lldb::DebuggerSP &debugger_sp) : + m_debugger_wp (debugger_sp), + m_target_wp () + { + } + + SourceManagerImpl (const lldb::TargetSP &target_sp) : + m_debugger_wp (), + m_target_wp (target_sp) + { + } + + SourceManagerImpl (const SourceManagerImpl &rhs) + { + if (&rhs == this) + return; + m_debugger_wp = rhs.m_debugger_wp; + m_target_wp = rhs.m_target_wp; + } + + size_t + DisplaySourceLinesWithLineNumbers (const lldb_private::FileSpec &file, + uint32_t line, + uint32_t context_before, + uint32_t context_after, + const char *current_line_cstr, + lldb_private::Stream *s) + { + if (!file) + return 0; + + lldb::TargetSP target_sp (m_target_wp.lock()); + if (target_sp) + { + return target_sp->GetSourceManager().DisplaySourceLinesWithLineNumbers (file, + line, + context_before, + context_after, + current_line_cstr, + s); + } + else + { + lldb::DebuggerSP debugger_sp (m_debugger_wp.lock()); + if (debugger_sp) + { + return debugger_sp->GetSourceManager().DisplaySourceLinesWithLineNumbers (file, + line, + context_before, + context_after, + current_line_cstr, + s); + } + } + return 0; + } + + private: + lldb::DebuggerWP m_debugger_wp; + lldb::TargetWP m_target_wp; + + }; +} + +using namespace lldb; +using namespace lldb_private; + +SBSourceManager::SBSourceManager (const SBDebugger &debugger) +{ + m_opaque_ap.reset(new SourceManagerImpl (debugger.get_sp())); +} + +SBSourceManager::SBSourceManager (const SBTarget &target) +{ + m_opaque_ap.reset(new SourceManagerImpl (target.GetSP())); +} + +SBSourceManager::SBSourceManager (const SBSourceManager &rhs) +{ + if (&rhs == this) + return; + + m_opaque_ap.reset(new SourceManagerImpl (*(rhs.m_opaque_ap.get()))); +} + +const lldb::SBSourceManager & +SBSourceManager::operator = (const lldb::SBSourceManager &rhs) +{ + m_opaque_ap.reset (new SourceManagerImpl (*(rhs.m_opaque_ap.get()))); + return *this; +} + +SBSourceManager::~SBSourceManager() +{ +} + +size_t +SBSourceManager::DisplaySourceLinesWithLineNumbers +( + const SBFileSpec &file, + uint32_t line, + uint32_t context_before, + uint32_t context_after, + const char *current_line_cstr, + SBStream &s +) +{ + if (m_opaque_ap.get() == NULL) + return 0; + + return m_opaque_ap->DisplaySourceLinesWithLineNumbers (file.ref(), + line, + context_before, + context_after, + current_line_cstr, + s.get()); +} diff --git a/source/API/SBStream.cpp b/source/API/SBStream.cpp new file mode 100644 index 000000000000..dc8eb05ab0ba --- /dev/null +++ b/source/API/SBStream.cpp @@ -0,0 +1,187 @@ +//===-- SBStream.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/SBStream.h" + +#include "lldb/Core/Error.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/StreamString.h" + +using namespace lldb; +using namespace lldb_private; + +SBStream::SBStream () : + m_opaque_ap (new StreamString()), + m_is_file (false) +{ +} + +SBStream::~SBStream () +{ +} + +bool +SBStream::IsValid() const +{ + return (m_opaque_ap.get() != NULL); +} + +// If this stream is not redirected to a file, it will maintain a local +// cache for the stream data which can be accessed using this accessor. +const char * +SBStream::GetData () +{ + if (m_is_file || m_opaque_ap.get() == NULL) + return NULL; + + return static_cast<StreamString *>(m_opaque_ap.get())->GetData(); +} + +// If this stream is not redirected to a file, it will maintain a local +// cache for the stream output whose length can be accessed using this +// accessor. +size_t +SBStream::GetSize() +{ + if (m_is_file || m_opaque_ap.get() == NULL) + return 0; + + return static_cast<StreamString *>(m_opaque_ap.get())->GetSize(); +} + +void +SBStream::Printf (const char *format, ...) +{ + if (!format) + return; + va_list args; + va_start (args, format); + ref().PrintfVarArg (format, args); + va_end (args); +} + +void +SBStream::RedirectToFile (const char *path, bool append) +{ + std::string local_data; + if (m_opaque_ap.get()) + { + // See if we have any locally backed data. If so, copy it so we can then + // redirect it to the file so we don't lose the data + if (!m_is_file) + local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString()); + } + StreamFile *stream_file = new StreamFile; + uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; + if (append) + open_options |= File::eOpenOptionAppend; + stream_file->GetFile().Open (path, open_options, File::ePermissionsDefault); + + m_opaque_ap.reset (stream_file); + + if (m_opaque_ap.get()) + { + m_is_file = true; + + // If we had any data locally in our StreamString, then pass that along to + // the to new file we are redirecting to. + if (!local_data.empty()) + m_opaque_ap->Write (&local_data[0], local_data.size()); + } + else + m_is_file = false; +} + +void +SBStream::RedirectToFileHandle (FILE *fh, bool transfer_fh_ownership) +{ + std::string local_data; + if (m_opaque_ap.get()) + { + // See if we have any locally backed data. If so, copy it so we can then + // redirect it to the file so we don't lose the data + if (!m_is_file) + local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString()); + } + m_opaque_ap.reset (new StreamFile (fh, transfer_fh_ownership)); + + if (m_opaque_ap.get()) + { + m_is_file = true; + + // If we had any data locally in our StreamString, then pass that along to + // the to new file we are redirecting to. + if (!local_data.empty()) + m_opaque_ap->Write (&local_data[0], local_data.size()); + } + else + m_is_file = false; +} + +void +SBStream::RedirectToFileDescriptor (int fd, bool transfer_fh_ownership) +{ + std::string local_data; + if (m_opaque_ap.get()) + { + // See if we have any locally backed data. If so, copy it so we can then + // redirect it to the file so we don't lose the data + if (!m_is_file) + local_data.swap(static_cast<StreamString *>(m_opaque_ap.get())->GetString()); + } + + m_opaque_ap.reset (new StreamFile (::fdopen (fd, "w"), transfer_fh_ownership)); + if (m_opaque_ap.get()) + { + m_is_file = true; + + // If we had any data locally in our StreamString, then pass that along to + // the to new file we are redirecting to. + if (!local_data.empty()) + m_opaque_ap->Write (&local_data[0], local_data.size()); + } + else + m_is_file = false; + +} + +lldb_private::Stream * +SBStream::operator->() +{ + return m_opaque_ap.get(); +} + +lldb_private::Stream * +SBStream::get() +{ + return m_opaque_ap.get(); +} + +lldb_private::Stream & +SBStream::ref() +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new StreamString()); + return *m_opaque_ap.get(); +} + +void +SBStream::Clear () +{ + if (m_opaque_ap.get()) + { + // See if we have any locally backed data. If so, copy it so we can then + // redirect it to the file so we don't lose the data + if (m_is_file) + m_opaque_ap.reset(); + else + static_cast<StreamString *>(m_opaque_ap.get())->GetString().clear(); + } +} diff --git a/source/API/SBStringList.cpp b/source/API/SBStringList.cpp new file mode 100644 index 000000000000..129d2f4c11f0 --- /dev/null +++ b/source/API/SBStringList.cpp @@ -0,0 +1,136 @@ +//===-- SBStringList.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/SBStringList.h" + +#include "lldb/Core/StringList.h" + +using namespace lldb; +using namespace lldb_private; + +SBStringList::SBStringList () : + m_opaque_ap () +{ +} + +SBStringList::SBStringList (const lldb_private::StringList *lldb_strings_ptr) : + m_opaque_ap () +{ + if (lldb_strings_ptr) + m_opaque_ap.reset (new lldb_private::StringList (*lldb_strings_ptr)); +} + +SBStringList::SBStringList (const SBStringList &rhs) : + m_opaque_ap () +{ + if (rhs.IsValid()) + m_opaque_ap.reset (new lldb_private::StringList(*rhs)); +} + + +const SBStringList & +SBStringList::operator = (const SBStringList &rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_ap.reset(new lldb_private::StringList(*rhs)); + else + m_opaque_ap.reset(); + } + return *this; +} + +SBStringList::~SBStringList () +{ +} + +const lldb_private::StringList * +SBStringList::operator->() const +{ + return m_opaque_ap.get(); +} + +const lldb_private::StringList & +SBStringList::operator*() const +{ + return *m_opaque_ap; +} + +bool +SBStringList::IsValid() const +{ + return (m_opaque_ap.get() != NULL); +} + +void +SBStringList::AppendString (const char *str) +{ + if (str != NULL) + { + if (IsValid()) + m_opaque_ap->AppendString (str); + else + m_opaque_ap.reset (new lldb_private::StringList (str)); + } + +} + +void +SBStringList::AppendList (const char **strv, int strc) +{ + if ((strv != NULL) + && (strc > 0)) + { + if (IsValid()) + m_opaque_ap->AppendList (strv, strc); + else + m_opaque_ap.reset (new lldb_private::StringList (strv, strc)); + } +} + +void +SBStringList::AppendList (const SBStringList &strings) +{ + if (strings.IsValid()) + { + if (! IsValid()) + m_opaque_ap.reset (new lldb_private::StringList()); + m_opaque_ap->AppendList (*(strings.m_opaque_ap)); + } +} + +uint32_t +SBStringList::GetSize () const +{ + if (IsValid()) + { + return m_opaque_ap->GetSize(); + } + return 0; +} + +const char * +SBStringList::GetStringAtIndex (size_t idx) +{ + if (IsValid()) + { + return m_opaque_ap->GetStringAtIndex (idx); + } + return NULL; +} + +void +SBStringList::Clear () +{ + if (IsValid()) + { + m_opaque_ap->Clear(); + } +} diff --git a/source/API/SBSymbol.cpp b/source/API/SBSymbol.cpp new file mode 100644 index 000000000000..dd057e81a559 --- /dev/null +++ b/source/API/SBSymbol.cpp @@ -0,0 +1,223 @@ +//===-- SBSymbol.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/SBSymbol.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +SBSymbol::SBSymbol () : + m_opaque_ptr (NULL) +{ +} + +SBSymbol::SBSymbol (lldb_private::Symbol *lldb_object_ptr) : + m_opaque_ptr (lldb_object_ptr) +{ +} + +SBSymbol::SBSymbol (const lldb::SBSymbol &rhs) : + m_opaque_ptr (rhs.m_opaque_ptr) +{ +} + +const SBSymbol & +SBSymbol::operator = (const SBSymbol &rhs) +{ + m_opaque_ptr = rhs.m_opaque_ptr; + return *this; +} + +SBSymbol::~SBSymbol () +{ + m_opaque_ptr = NULL; +} + +void +SBSymbol::SetSymbol (lldb_private::Symbol *lldb_object_ptr) +{ + m_opaque_ptr = lldb_object_ptr; +} + +bool +SBSymbol::IsValid () const +{ + return m_opaque_ptr != NULL; +} + +const char * +SBSymbol::GetName() const +{ + const char *name = NULL; + if (m_opaque_ptr) + name = m_opaque_ptr->GetMangled().GetName().AsCString(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBSymbol(%p)::GetName () => \"%s\"", m_opaque_ptr, name ? name : ""); + return name; +} + +const char * +SBSymbol::GetMangledName () const +{ + const char *name = NULL; + if (m_opaque_ptr) + name = m_opaque_ptr->GetMangled().GetMangledName().AsCString(); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBSymbol(%p)::GetMangledName () => \"%s\"", m_opaque_ptr, name ? name : ""); + + return name; +} + + +bool +SBSymbol::operator == (const SBSymbol &rhs) const +{ + return m_opaque_ptr == rhs.m_opaque_ptr; +} + +bool +SBSymbol::operator != (const SBSymbol &rhs) const +{ + return m_opaque_ptr != rhs.m_opaque_ptr; +} + +bool +SBSymbol::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + if (m_opaque_ptr) + { + m_opaque_ptr->GetDescription (&strm, + lldb::eDescriptionLevelFull, NULL); + } + else + strm.PutCString ("No value"); + + return true; +} + +SBInstructionList +SBSymbol::GetInstructions (SBTarget target) +{ + return GetInstructions (target, NULL); +} + +SBInstructionList +SBSymbol::GetInstructions (SBTarget target, const char *flavor_string) +{ + SBInstructionList sb_instructions; + if (m_opaque_ptr) + { + 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); + } + if (m_opaque_ptr->ValueIsAddress()) + { + ModuleSP module_sp (m_opaque_ptr->GetAddress().GetModule()); + if (module_sp) + { + AddressRange symbol_range (m_opaque_ptr->GetAddress(), m_opaque_ptr->GetByteSize()); + sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture (), + NULL, + flavor_string, + exe_ctx, + symbol_range)); + } + } + } + return sb_instructions; +} + +lldb_private::Symbol * +SBSymbol::get () +{ + return m_opaque_ptr; +} + +void +SBSymbol::reset (lldb_private::Symbol *symbol) +{ + m_opaque_ptr = symbol; +} + +SBAddress +SBSymbol::GetStartAddress () +{ + SBAddress addr; + if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) + { + addr.SetAddress (&m_opaque_ptr->GetAddress()); + } + return addr; +} + +SBAddress +SBSymbol::GetEndAddress () +{ + SBAddress addr; + if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress()) + { + lldb::addr_t range_size = m_opaque_ptr->GetByteSize(); + if (range_size > 0) + { + addr.SetAddress (&m_opaque_ptr->GetAddress()); + addr->Slide (m_opaque_ptr->GetByteSize()); + } + } + return addr; +} + +uint32_t +SBSymbol::GetPrologueByteSize () +{ + if (m_opaque_ptr) + return m_opaque_ptr->GetPrologueByteSize(); + return 0; +} + +SymbolType +SBSymbol::GetType () +{ + if (m_opaque_ptr) + return m_opaque_ptr->GetType(); + return eSymbolTypeInvalid; +} + +bool +SBSymbol::IsExternal() +{ + if (m_opaque_ptr) + return m_opaque_ptr->IsExternal(); + return false; +} + +bool +SBSymbol::IsSynthetic() +{ + if (m_opaque_ptr) + return m_opaque_ptr->IsSynthetic(); + return false; +} + diff --git a/source/API/SBSymbolContext.cpp b/source/API/SBSymbolContext.cpp new file mode 100644 index 000000000000..479b0f75bfe9 --- /dev/null +++ b/source/API/SBSymbolContext.cpp @@ -0,0 +1,285 @@ +//===-- SBSymbolContext.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/SBSymbolContext.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" + +using namespace lldb; +using namespace lldb_private; + + + +SBSymbolContext::SBSymbolContext () : + m_opaque_ap () +{ +} + +SBSymbolContext::SBSymbolContext (const SymbolContext *sc_ptr) : + m_opaque_ap () +{ + if (sc_ptr) + m_opaque_ap.reset (new SymbolContext (*sc_ptr)); +} + +SBSymbolContext::SBSymbolContext (const SBSymbolContext& rhs) : + m_opaque_ap () +{ + if (rhs.IsValid()) + { + if (m_opaque_ap.get()) + *m_opaque_ap = *rhs.m_opaque_ap; + else + ref() = *rhs.m_opaque_ap; + } +} + +SBSymbolContext::~SBSymbolContext () +{ +} + +const SBSymbolContext & +SBSymbolContext::operator = (const SBSymbolContext &rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_ap.reset (new lldb_private::SymbolContext(*rhs.m_opaque_ap.get())); + } + return *this; +} + +void +SBSymbolContext::SetSymbolContext (const SymbolContext *sc_ptr) +{ + if (sc_ptr) + { + if (m_opaque_ap.get()) + *m_opaque_ap = *sc_ptr; + else + m_opaque_ap.reset (new SymbolContext (*sc_ptr)); + } + else + { + if (m_opaque_ap.get()) + m_opaque_ap->Clear(true); + } +} + +bool +SBSymbolContext::IsValid () const +{ + return m_opaque_ap.get() != NULL; +} + + + +SBModule +SBSymbolContext::GetModule () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBModule sb_module; + ModuleSP module_sp; + if (m_opaque_ap.get()) + { + module_sp = m_opaque_ap->module_sp; + sb_module.SetSP (module_sp); + } + + if (log) + { + SBStream sstr; + sb_module.GetDescription (sstr); + log->Printf ("SBSymbolContext(%p)::GetModule () => SBModule(%p): %s", + m_opaque_ap.get(), module_sp.get(), sstr.GetData()); + } + + return sb_module; +} + +SBCompileUnit +SBSymbolContext::GetCompileUnit () +{ + return SBCompileUnit (m_opaque_ap.get() ? m_opaque_ap->comp_unit : NULL); +} + +SBFunction +SBSymbolContext::GetFunction () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Function *function = NULL; + + if (m_opaque_ap.get()) + function = m_opaque_ap->function; + + SBFunction sb_function (function); + + if (log) + log->Printf ("SBSymbolContext(%p)::GetFunction () => SBFunction(%p)", + m_opaque_ap.get(), function); + + return sb_function; +} + +SBBlock +SBSymbolContext::GetBlock () +{ + return SBBlock (m_opaque_ap.get() ? m_opaque_ap->block : NULL); +} + +SBLineEntry +SBSymbolContext::GetLineEntry () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBLineEntry sb_line_entry; + if (m_opaque_ap.get()) + sb_line_entry.SetLineEntry (m_opaque_ap->line_entry); + + if (log) + { + log->Printf ("SBSymbolContext(%p)::GetLineEntry () => SBLineEntry(%p)", + m_opaque_ap.get(), sb_line_entry.get()); + } + + return sb_line_entry; +} + +SBSymbol +SBSymbolContext::GetSymbol () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Symbol *symbol = NULL; + + if (m_opaque_ap.get()) + symbol = m_opaque_ap->symbol; + + SBSymbol sb_symbol (symbol); + + if (log) + { + log->Printf ("SBSymbolContext(%p)::GetSymbol () => SBSymbol(%p)", + m_opaque_ap.get(), symbol); + } + + return sb_symbol; +} + +void +SBSymbolContext::SetModule (lldb::SBModule module) +{ + ref().module_sp = module.GetSP(); +} + +void +SBSymbolContext::SetCompileUnit (lldb::SBCompileUnit compile_unit) +{ + ref().comp_unit = compile_unit.get(); +} + +void +SBSymbolContext::SetFunction (lldb::SBFunction function) +{ + ref().function = function.get(); +} + +void +SBSymbolContext::SetBlock (lldb::SBBlock block) +{ + ref().block = block.GetPtr(); +} + +void +SBSymbolContext::SetLineEntry (lldb::SBLineEntry line_entry) +{ + if (line_entry.IsValid()) + ref().line_entry = line_entry.ref(); + else + ref().line_entry.Clear(); +} + +void +SBSymbolContext::SetSymbol (lldb::SBSymbol symbol) +{ + ref().symbol = symbol.get(); +} + + +lldb_private::SymbolContext* +SBSymbolContext::operator->() const +{ + return m_opaque_ap.get(); +} + + +const lldb_private::SymbolContext& +SBSymbolContext::operator*() const +{ + assert (m_opaque_ap.get()); + return *m_opaque_ap.get(); +} + + +lldb_private::SymbolContext& +SBSymbolContext::operator*() +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new SymbolContext); + return *m_opaque_ap.get(); +} + +lldb_private::SymbolContext& +SBSymbolContext::ref() +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new SymbolContext); + return *m_opaque_ap.get(); +} + +lldb_private::SymbolContext * +SBSymbolContext::get() const +{ + return m_opaque_ap.get(); +} + +bool +SBSymbolContext::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + if (m_opaque_ap.get()) + { + m_opaque_ap->GetDescription (&strm, lldb::eDescriptionLevelFull, NULL); + } + else + strm.PutCString ("No value"); + + return true; +} + +SBSymbolContext +SBSymbolContext::GetParentOfInlinedScope (const SBAddress &curr_frame_pc, + SBAddress &parent_frame_addr) const +{ + SBSymbolContext sb_sc; + if (m_opaque_ap.get() && curr_frame_pc.IsValid()) + { + if (m_opaque_ap->GetParentOfInlinedScope (curr_frame_pc.ref(), sb_sc.ref(), parent_frame_addr.ref())) + return sb_sc; + } + return SBSymbolContext(); +} + diff --git a/source/API/SBSymbolContextList.cpp b/source/API/SBSymbolContextList.cpp new file mode 100644 index 000000000000..0730096c5f3c --- /dev/null +++ b/source/API/SBSymbolContextList.cpp @@ -0,0 +1,117 @@ +//===-- SBSymbolContextList.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/SBSymbolContextList.h" +#include "lldb/API/SBStream.h" +#include "lldb/Symbol/SymbolContext.h" + +using namespace lldb; +using namespace lldb_private; + +SBSymbolContextList::SBSymbolContextList () : + m_opaque_ap (new SymbolContextList()) +{ +} + +SBSymbolContextList::SBSymbolContextList (const SBSymbolContextList& rhs) : + m_opaque_ap (new SymbolContextList(*rhs.m_opaque_ap)) +{ +} + +SBSymbolContextList::~SBSymbolContextList () +{ +} + +const SBSymbolContextList & +SBSymbolContextList::operator = (const SBSymbolContextList &rhs) +{ + if (this != &rhs) + { + *m_opaque_ap = *rhs.m_opaque_ap; + } + return *this; +} + +uint32_t +SBSymbolContextList::GetSize() const +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetSize(); + return 0; +} + +SBSymbolContext +SBSymbolContextList::GetContextAtIndex (uint32_t idx) +{ + SBSymbolContext sb_sc; + if (m_opaque_ap.get()) + { + SymbolContext sc; + if (m_opaque_ap->GetContextAtIndex (idx, sc)) + { + sb_sc.SetSymbolContext(&sc); + } + } + return sb_sc; +} + +void +SBSymbolContextList::Clear() +{ + if (m_opaque_ap.get()) + m_opaque_ap->Clear(); +} + +void +SBSymbolContextList::Append(SBSymbolContext &sc) +{ + if (sc.IsValid() && m_opaque_ap.get()) + m_opaque_ap->Append(*sc); +} + +void +SBSymbolContextList::Append(SBSymbolContextList &sc_list) +{ + if (sc_list.IsValid() && m_opaque_ap.get()) + m_opaque_ap->Append(*sc_list); +} + + +bool +SBSymbolContextList::IsValid () const +{ + return m_opaque_ap.get() != NULL; +} + + + +lldb_private::SymbolContextList* +SBSymbolContextList::operator->() const +{ + return m_opaque_ap.get(); +} + + +lldb_private::SymbolContextList& +SBSymbolContextList::operator*() const +{ + assert (m_opaque_ap.get()); + return *m_opaque_ap.get(); +} + +bool +SBSymbolContextList::GetDescription (lldb::SBStream &description) +{ + Stream &strm = description.ref(); + if (m_opaque_ap.get()) + m_opaque_ap->GetDescription (&strm, lldb::eDescriptionLevelFull, NULL); + return true; +} + + diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp new file mode 100644 index 000000000000..f37c8f8a614b --- /dev/null +++ b/source/API/SBTarget.cpp @@ -0,0 +1,2660 @@ +//===-- SBTarget.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/lldb-python.h" + +#include "lldb/API/SBTarget.h" + +#include "lldb/lldb-public.h" + +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBBreakpoint.h" +#include "lldb/API/SBExpressionOptions.h" +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBListener.h" +#include "lldb/API/SBModule.h" +#include "lldb/API/SBModuleSpec.h" +#include "lldb/API/SBSourceManager.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBSymbolContextList.h" +#include "lldb/Breakpoint/BreakpointID.h" +#include "lldb/Breakpoint/BreakpointIDList.h" +#include "lldb/Breakpoint/BreakpointList.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/AddressResolver.h" +#include "lldb/Core/AddressResolverName.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/RegularExpression.h" +#include "lldb/Core/SearchFilter.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/STLUtils.h" +#include "lldb/Core/ValueObjectList.h" +#include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/Host.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/LanguageRuntime.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/TargetList.h" + +#include "lldb/Interpreter/CommandReturnObject.h" +#include "../source/Commands/CommandObjectBreakpoint.h" + + +using namespace lldb; +using namespace lldb_private; + +#define DEFAULT_DISASM_BYTE_SIZE 32 + +SBLaunchInfo::SBLaunchInfo (const char **argv) : + m_opaque_sp(new ProcessLaunchInfo()) +{ + m_opaque_sp->GetFlags().Reset (eLaunchFlagDebug | eLaunchFlagDisableASLR); + if (argv && argv[0]) + m_opaque_sp->GetArguments().SetArguments(argv); +} + +SBLaunchInfo::~SBLaunchInfo() +{ +} + +lldb_private::ProcessLaunchInfo & +SBLaunchInfo::ref () +{ + return *m_opaque_sp; +} + + +uint32_t +SBLaunchInfo::GetUserID() +{ + return m_opaque_sp->GetUserID(); +} + +uint32_t +SBLaunchInfo::GetGroupID() +{ + return m_opaque_sp->GetGroupID(); +} + +bool +SBLaunchInfo::UserIDIsValid () +{ + return m_opaque_sp->UserIDIsValid(); +} + +bool +SBLaunchInfo::GroupIDIsValid () +{ + return m_opaque_sp->GroupIDIsValid(); +} + +void +SBLaunchInfo::SetUserID (uint32_t uid) +{ + m_opaque_sp->SetUserID (uid); +} + +void +SBLaunchInfo::SetGroupID (uint32_t gid) +{ + m_opaque_sp->SetGroupID (gid); +} + +uint32_t +SBLaunchInfo::GetNumArguments () +{ + return m_opaque_sp->GetArguments().GetArgumentCount(); +} + +const char * +SBLaunchInfo::GetArgumentAtIndex (uint32_t idx) +{ + return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx); +} + +void +SBLaunchInfo::SetArguments (const char **argv, bool append) +{ + if (append) + { + if (argv) + m_opaque_sp->GetArguments().AppendArguments(argv); + } + else + { + if (argv) + m_opaque_sp->GetArguments().SetArguments(argv); + else + m_opaque_sp->GetArguments().Clear(); + } +} + +uint32_t +SBLaunchInfo::GetNumEnvironmentEntries () +{ + return m_opaque_sp->GetEnvironmentEntries().GetArgumentCount(); +} + +const char * +SBLaunchInfo::GetEnvironmentEntryAtIndex (uint32_t idx) +{ + return m_opaque_sp->GetEnvironmentEntries().GetArgumentAtIndex(idx); +} + +void +SBLaunchInfo::SetEnvironmentEntries (const char **envp, bool append) +{ + if (append) + { + if (envp) + m_opaque_sp->GetEnvironmentEntries().AppendArguments(envp); + } + else + { + if (envp) + m_opaque_sp->GetEnvironmentEntries().SetArguments(envp); + else + m_opaque_sp->GetEnvironmentEntries().Clear(); + } +} + +void +SBLaunchInfo::Clear () +{ + m_opaque_sp->Clear(); +} + +const char * +SBLaunchInfo::GetWorkingDirectory () const +{ + return m_opaque_sp->GetWorkingDirectory(); +} + +void +SBLaunchInfo::SetWorkingDirectory (const char *working_dir) +{ + m_opaque_sp->SetWorkingDirectory(working_dir); +} + +uint32_t +SBLaunchInfo::GetLaunchFlags () +{ + return m_opaque_sp->GetFlags().Get(); +} + +void +SBLaunchInfo::SetLaunchFlags (uint32_t flags) +{ + m_opaque_sp->GetFlags().Reset(flags); +} + +const char * +SBLaunchInfo::GetProcessPluginName () +{ + return m_opaque_sp->GetProcessPluginName(); +} + +void +SBLaunchInfo::SetProcessPluginName (const char *plugin_name) +{ + return m_opaque_sp->SetProcessPluginName (plugin_name); +} + +const char * +SBLaunchInfo::GetShell () +{ + return m_opaque_sp->GetShell(); +} + +void +SBLaunchInfo::SetShell (const char * path) +{ + m_opaque_sp->SetShell (path); +} + +uint32_t +SBLaunchInfo::GetResumeCount () +{ + return m_opaque_sp->GetResumeCount(); +} + +void +SBLaunchInfo::SetResumeCount (uint32_t c) +{ + m_opaque_sp->SetResumeCount (c); +} + +bool +SBLaunchInfo::AddCloseFileAction (int fd) +{ + return m_opaque_sp->AppendCloseFileAction(fd); +} + +bool +SBLaunchInfo::AddDuplicateFileAction (int fd, int dup_fd) +{ + return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd); +} + +bool +SBLaunchInfo::AddOpenFileAction (int fd, const char *path, bool read, bool write) +{ + return m_opaque_sp->AppendOpenFileAction(fd, path, read, write); +} + +bool +SBLaunchInfo::AddSuppressFileAction (int fd, bool read, bool write) +{ + return m_opaque_sp->AppendSuppressFileAction(fd, read, write); +} + + +SBAttachInfo::SBAttachInfo () : + m_opaque_sp (new ProcessAttachInfo()) +{ +} + +SBAttachInfo::SBAttachInfo (lldb::pid_t pid) : + m_opaque_sp (new ProcessAttachInfo()) +{ + m_opaque_sp->SetProcessID (pid); +} + +SBAttachInfo::SBAttachInfo (const char *path, bool wait_for) : + m_opaque_sp (new ProcessAttachInfo()) +{ + if (path && path[0]) + m_opaque_sp->GetExecutableFile().SetFile(path, false); + m_opaque_sp->SetWaitForLaunch (wait_for); +} + +SBAttachInfo::SBAttachInfo (const SBAttachInfo &rhs) : + m_opaque_sp (new ProcessAttachInfo()) +{ + *m_opaque_sp = *rhs.m_opaque_sp; +} + +SBAttachInfo::~SBAttachInfo() +{ +} + +lldb_private::ProcessAttachInfo & +SBAttachInfo::ref () +{ + return *m_opaque_sp; +} + +SBAttachInfo & +SBAttachInfo::operator = (const SBAttachInfo &rhs) +{ + if (this != &rhs) + *m_opaque_sp = *rhs.m_opaque_sp; + return *this; +} + +lldb::pid_t +SBAttachInfo::GetProcessID () +{ + return m_opaque_sp->GetProcessID(); +} + +void +SBAttachInfo::SetProcessID (lldb::pid_t pid) +{ + m_opaque_sp->SetProcessID (pid); +} + + +uint32_t +SBAttachInfo::GetResumeCount () +{ + return m_opaque_sp->GetResumeCount(); +} + +void +SBAttachInfo::SetResumeCount (uint32_t c) +{ + m_opaque_sp->SetResumeCount (c); +} + +const char * +SBAttachInfo::GetProcessPluginName () +{ + return m_opaque_sp->GetProcessPluginName(); +} + +void +SBAttachInfo::SetProcessPluginName (const char *plugin_name) +{ + return m_opaque_sp->SetProcessPluginName (plugin_name); +} + +void +SBAttachInfo::SetExecutable (const char *path) +{ + if (path && path[0]) + m_opaque_sp->GetExecutableFile().SetFile(path, false); + else + m_opaque_sp->GetExecutableFile().Clear(); +} + +void +SBAttachInfo::SetExecutable (SBFileSpec exe_file) +{ + if (exe_file.IsValid()) + m_opaque_sp->GetExecutableFile() = exe_file.ref(); + else + m_opaque_sp->GetExecutableFile().Clear(); +} + +bool +SBAttachInfo::GetWaitForLaunch () +{ + return m_opaque_sp->GetWaitForLaunch(); +} + +void +SBAttachInfo::SetWaitForLaunch (bool b) +{ + m_opaque_sp->SetWaitForLaunch (b); +} + +bool +SBAttachInfo::GetIgnoreExisting () +{ + return m_opaque_sp->GetIgnoreExisting(); +} + +void +SBAttachInfo::SetIgnoreExisting (bool b) +{ + m_opaque_sp->SetIgnoreExisting (b); +} + +uint32_t +SBAttachInfo::GetUserID() +{ + return m_opaque_sp->GetUserID(); +} + +uint32_t +SBAttachInfo::GetGroupID() +{ + return m_opaque_sp->GetGroupID(); +} + +bool +SBAttachInfo::UserIDIsValid () +{ + return m_opaque_sp->UserIDIsValid(); +} + +bool +SBAttachInfo::GroupIDIsValid () +{ + return m_opaque_sp->GroupIDIsValid(); +} + +void +SBAttachInfo::SetUserID (uint32_t uid) +{ + m_opaque_sp->SetUserID (uid); +} + +void +SBAttachInfo::SetGroupID (uint32_t gid) +{ + m_opaque_sp->SetGroupID (gid); +} + +uint32_t +SBAttachInfo::GetEffectiveUserID() +{ + return m_opaque_sp->GetEffectiveUserID(); +} + +uint32_t +SBAttachInfo::GetEffectiveGroupID() +{ + return m_opaque_sp->GetEffectiveGroupID(); +} + +bool +SBAttachInfo::EffectiveUserIDIsValid () +{ + return m_opaque_sp->EffectiveUserIDIsValid(); +} + +bool +SBAttachInfo::EffectiveGroupIDIsValid () +{ + return m_opaque_sp->EffectiveGroupIDIsValid (); +} + +void +SBAttachInfo::SetEffectiveUserID (uint32_t uid) +{ + m_opaque_sp->SetEffectiveUserID(uid); +} + +void +SBAttachInfo::SetEffectiveGroupID (uint32_t gid) +{ + m_opaque_sp->SetEffectiveGroupID(gid); +} + +lldb::pid_t +SBAttachInfo::GetParentProcessID () +{ + return m_opaque_sp->GetParentProcessID(); +} + +void +SBAttachInfo::SetParentProcessID (lldb::pid_t pid) +{ + m_opaque_sp->SetParentProcessID (pid); +} + +bool +SBAttachInfo::ParentProcessIDIsValid() +{ + return m_opaque_sp->ParentProcessIDIsValid(); +} + + +//---------------------------------------------------------------------- +// SBTarget constructor +//---------------------------------------------------------------------- +SBTarget::SBTarget () : + m_opaque_sp () +{ +} + +SBTarget::SBTarget (const SBTarget& rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +SBTarget::SBTarget(const TargetSP& target_sp) : + m_opaque_sp (target_sp) +{ +} + +const SBTarget& +SBTarget::operator = (const SBTarget& rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBTarget::~SBTarget() +{ +} + +const char * +SBTarget::GetBroadcasterClassName () +{ + return Target::GetStaticBroadcasterClass().AsCString(); +} + +bool +SBTarget::IsValid () const +{ + return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid(); +} + +SBProcess +SBTarget::GetProcess () +{ + SBProcess sb_process; + ProcessSP process_sp; + TargetSP target_sp(GetSP()); + if (target_sp) + { + process_sp = target_sp->GetProcessSP(); + sb_process.SetSP (process_sp); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)", + target_sp.get(), process_sp.get()); + } + + return sb_process; +} + +SBDebugger +SBTarget::GetDebugger () const +{ + SBDebugger debugger; + TargetSP target_sp(GetSP()); + if (target_sp) + debugger.reset (target_sp->GetDebugger().shared_from_this()); + return debugger; +} + +SBProcess +SBTarget::LoadCore (const char *core_file) +{ + SBProcess sb_process; + TargetSP target_sp(GetSP()); + if (target_sp) + { + FileSpec filespec(core_file, true); + ProcessSP process_sp (target_sp->CreateProcess(target_sp->GetDebugger().GetListener(), + NULL, + &filespec)); + if (process_sp) + { + process_sp->LoadCore(); + sb_process.SetSP (process_sp); + } + } + return sb_process; +} + +SBProcess +SBTarget::LaunchSimple +( + char const **argv, + char const **envp, + const char *working_directory +) +{ + char *stdin_path = NULL; + char *stdout_path = NULL; + char *stderr_path = NULL; + uint32_t launch_flags = 0; + bool stop_at_entry = false; + SBError error; + SBListener listener = GetDebugger().GetListener(); + return Launch (listener, + argv, + envp, + stdin_path, + stdout_path, + stderr_path, + working_directory, + launch_flags, + stop_at_entry, + error); +} + +SBProcess +SBTarget::Launch +( + SBListener &listener, + char const **argv, + char const **envp, + const char *stdin_path, + const char *stdout_path, + const char *stderr_path, + const char *working_directory, + uint32_t launch_flags, // See LaunchFlags + bool stop_at_entry, + lldb::SBError& error +) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBProcess sb_process; + ProcessSP process_sp; + TargetSP target_sp(GetSP()); + + if (log) + { + log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...", + target_sp.get(), + argv, + envp, + stdin_path ? stdin_path : "NULL", + stdout_path ? stdout_path : "NULL", + stderr_path ? stderr_path : "NULL", + working_directory ? working_directory : "NULL", + launch_flags, + stop_at_entry, + error.get()); + } + + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + + if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR")) + launch_flags |= eLaunchFlagDisableASLR; + + StateType state = eStateInvalid; + process_sp = target_sp->GetProcessSP(); + if (process_sp) + { + state = process_sp->GetState(); + + if (process_sp->IsAlive() && state != eStateConnected) + { + if (state == eStateAttaching) + error.SetErrorString ("process attach is in progress"); + else + error.SetErrorString ("a process is already being debugged"); + return sb_process; + } + } + + if (state == eStateConnected) + { + // If we are already connected, then we have already specified the + // listener, so if a valid listener is supplied, we need to error out + // to let the client know. + if (listener.IsValid()) + { + error.SetErrorString ("process is connected and already has a listener, pass empty listener"); + return sb_process; + } + } + else + { + if (listener.IsValid()) + process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL); + else + process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); + } + + if (process_sp) + { + sb_process.SetSP (process_sp); + if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO")) + launch_flags |= eLaunchFlagDisableSTDIO; + + ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags); + + Module *exe_module = target_sp->GetExecutableModulePointer(); + if (exe_module) + launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); + if (argv) + launch_info.GetArguments().AppendArguments (argv); + if (envp) + launch_info.GetEnvironmentEntries ().SetArguments (envp); + + error.SetError (process_sp->Launch (launch_info)); + if (error.Success()) + { + // We we are stopping at the entry point, we can return now! + if (stop_at_entry) + return sb_process; + + // Make sure we are stopped at the entry + StateType state = process_sp->WaitForProcessToStop (NULL); + if (state == eStateStopped) + { + // resume the process to skip the entry point + error.SetError (process_sp->Resume()); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop yet again! + if (target_sp->GetDebugger().GetAsyncExecution () == false) + process_sp->WaitForProcessToStop (NULL); + } + } + } + } + else + { + error.SetErrorString ("unable to create lldb_private::Process"); + } + } + else + { + error.SetErrorString ("SBTarget is invalid"); + } + + log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); + if (log) + { + log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", + target_sp.get(), process_sp.get()); + } + + return sb_process; +} + +SBProcess +SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBProcess sb_process; + ProcessSP process_sp; + TargetSP target_sp(GetSP()); + + if (log) + { + log->Printf ("SBTarget(%p)::Launch (launch_info, error)...", target_sp.get()); + } + + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + StateType state = eStateInvalid; + process_sp = target_sp->GetProcessSP(); + if (process_sp) + { + state = process_sp->GetState(); + + if (process_sp->IsAlive() && state != eStateConnected) + { + if (state == eStateAttaching) + error.SetErrorString ("process attach is in progress"); + else + error.SetErrorString ("a process is already being debugged"); + return sb_process; + } + } + + if (state != eStateConnected) + process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); + + if (process_sp) + { + sb_process.SetSP (process_sp); + lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref(); + + Module *exe_module = target_sp->GetExecutableModulePointer(); + if (exe_module) + launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); + + const ArchSpec &arch_spec = target_sp->GetArchitecture(); + if (arch_spec.IsValid()) + launch_info.GetArchitecture () = arch_spec; + + error.SetError (process_sp->Launch (launch_info)); + const bool synchronous_execution = target_sp->GetDebugger().GetAsyncExecution () == false; + if (error.Success()) + { + if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) + { + // If we are doing synchronous mode, then wait for the initial + // stop to happen, else, return and let the caller watch for + // the stop + if (synchronous_execution) + process_sp->WaitForProcessToStop (NULL); + // We we are stopping at the entry point, we can return now! + return sb_process; + } + + // Make sure we are stopped at the entry + StateType state = process_sp->WaitForProcessToStop (NULL); + if (state == eStateStopped) + { + // resume the process to skip the entry point + error.SetError (process_sp->Resume()); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop yet again! + if (synchronous_execution) + process_sp->WaitForProcessToStop (NULL); + } + } + } + } + else + { + error.SetErrorString ("unable to create lldb_private::Process"); + } + } + else + { + error.SetErrorString ("SBTarget is invalid"); + } + + log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); + if (log) + { + log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", + target_sp.get(), process_sp.get()); + } + + return sb_process; +} + +lldb::SBProcess +SBTarget::Attach (SBAttachInfo &sb_attach_info, SBError& error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBProcess sb_process; + ProcessSP process_sp; + TargetSP target_sp(GetSP()); + + if (log) + { + log->Printf ("SBTarget(%p)::Attach (sb_attach_info, error)...", target_sp.get()); + } + + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + + StateType state = eStateInvalid; + process_sp = target_sp->GetProcessSP(); + if (process_sp) + { + state = process_sp->GetState(); + + if (process_sp->IsAlive() && state != eStateConnected) + { + if (state == eStateAttaching) + error.SetErrorString ("process attach is in progress"); + else + error.SetErrorString ("a process is already being debugged"); + if (log) + { + log->Printf ("SBTarget(%p)::Attach (...) => error %s", + target_sp.get(), error.GetCString()); + } + return sb_process; + } + } + + if (state != eStateConnected) + process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); + + if (process_sp) + { + ProcessAttachInfo &attach_info = sb_attach_info.ref(); + if (attach_info.ProcessIDIsValid() && !attach_info.UserIDIsValid()) + { + PlatformSP platform_sp = target_sp->GetPlatform(); + // See if we can pre-verify if a process exists or not + if (platform_sp && platform_sp->IsConnected()) + { + lldb::pid_t attach_pid = attach_info.GetProcessID(); + ProcessInstanceInfo instance_info; + if (platform_sp->GetProcessInfo(attach_pid, instance_info)) + { + attach_info.SetUserID(instance_info.GetEffectiveUserID()); + } + else + { + error.ref().SetErrorStringWithFormat("no process found with process ID %" PRIu64, attach_pid); + if (log) + { + log->Printf ("SBTarget(%p)::Attach (...) => error %s", + target_sp.get(), error.GetCString()); + } + return sb_process; + } + } + } + error.SetError (process_sp->Attach (attach_info)); + if (error.Success()) + { + sb_process.SetSP (process_sp); + // If we are doing synchronous mode, then wait for the + // process to stop! + if (target_sp->GetDebugger().GetAsyncExecution () == false) + process_sp->WaitForProcessToStop (NULL); + } + } + else + { + error.SetErrorString ("unable to create lldb_private::Process"); + } + } + else + { + error.SetErrorString ("SBTarget is invalid"); + } + + if (log) + { + log->Printf ("SBTarget(%p)::Attach (...) => SBProcess(%p)", + target_sp.get(), process_sp.get()); + } + + return sb_process; +} + + +#if defined(__APPLE__) + +lldb::SBProcess +SBTarget::AttachToProcessWithID (SBListener &listener, + ::pid_t pid, + lldb::SBError& error) +{ + return AttachToProcessWithID (listener, (lldb::pid_t)pid, error); +} + +#endif // #if defined(__APPLE__) + +lldb::SBProcess +SBTarget::AttachToProcessWithID +( + SBListener &listener, + lldb::pid_t pid,// The process ID to attach to + SBError& error // An error explaining what went wrong if attach fails +) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBProcess sb_process; + ProcessSP process_sp; + TargetSP target_sp(GetSP()); + + if (log) + { + log->Printf ("SBTarget(%p)::AttachToProcessWithID (listener, pid=%" PRId64 ", error)...", target_sp.get(), pid); + } + + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + + StateType state = eStateInvalid; + process_sp = target_sp->GetProcessSP(); + if (process_sp) + { + state = process_sp->GetState(); + + if (process_sp->IsAlive() && state != eStateConnected) + { + if (state == eStateAttaching) + error.SetErrorString ("process attach is in progress"); + else + error.SetErrorString ("a process is already being debugged"); + return sb_process; + } + } + + if (state == eStateConnected) + { + // If we are already connected, then we have already specified the + // listener, so if a valid listener is supplied, we need to error out + // to let the client know. + if (listener.IsValid()) + { + error.SetErrorString ("process is connected and already has a listener, pass empty listener"); + return sb_process; + } + } + else + { + if (listener.IsValid()) + process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL); + else + process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); + } + if (process_sp) + { + sb_process.SetSP (process_sp); + + ProcessAttachInfo attach_info; + attach_info.SetProcessID (pid); + + PlatformSP platform_sp = target_sp->GetPlatform(); + ProcessInstanceInfo instance_info; + if (platform_sp->GetProcessInfo(pid, instance_info)) + { + attach_info.SetUserID(instance_info.GetEffectiveUserID()); + } + error.SetError (process_sp->Attach (attach_info)); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop! + if (target_sp->GetDebugger().GetAsyncExecution () == false) + process_sp->WaitForProcessToStop (NULL); + } + } + else + { + error.SetErrorString ("unable to create lldb_private::Process"); + } + } + else + { + error.SetErrorString ("SBTarget is invalid"); + } + + if (log) + { + log->Printf ("SBTarget(%p)::AttachToProcessWithID (...) => SBProcess(%p)", + target_sp.get(), process_sp.get()); + } + return sb_process; +} + +lldb::SBProcess +SBTarget::AttachToProcessWithName +( + SBListener &listener, + const char *name, // basename of process to attach to + bool wait_for, // if true wait for a new instance of "name" to be launched + SBError& error // An error explaining what went wrong if attach fails +) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBProcess sb_process; + ProcessSP process_sp; + TargetSP target_sp(GetSP()); + + if (log) + { + log->Printf ("SBTarget(%p)::AttachToProcessWithName (listener, name=%s, wait_for=%s, error)...", target_sp.get(), name, wait_for ? "true" : "false"); + } + + if (name && target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + + StateType state = eStateInvalid; + process_sp = target_sp->GetProcessSP(); + if (process_sp) + { + state = process_sp->GetState(); + + if (process_sp->IsAlive() && state != eStateConnected) + { + if (state == eStateAttaching) + error.SetErrorString ("process attach is in progress"); + else + error.SetErrorString ("a process is already being debugged"); + return sb_process; + } + } + + if (state == eStateConnected) + { + // If we are already connected, then we have already specified the + // listener, so if a valid listener is supplied, we need to error out + // to let the client know. + if (listener.IsValid()) + { + error.SetErrorString ("process is connected and already has a listener, pass empty listener"); + return sb_process; + } + } + else + { + if (listener.IsValid()) + process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL); + else + process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); + } + + if (process_sp) + { + sb_process.SetSP (process_sp); + ProcessAttachInfo attach_info; + attach_info.GetExecutableFile().SetFile(name, false); + attach_info.SetWaitForLaunch(wait_for); + error.SetError (process_sp->Attach (attach_info)); + if (error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop! + if (target_sp->GetDebugger().GetAsyncExecution () == false) + process_sp->WaitForProcessToStop (NULL); + } + } + else + { + error.SetErrorString ("unable to create lldb_private::Process"); + } + } + else + { + error.SetErrorString ("SBTarget is invalid"); + } + + if (log) + { + log->Printf ("SBTarget(%p)::AttachToPorcessWithName (...) => SBProcess(%p)", + target_sp.get(), process_sp.get()); + } + return sb_process; +} + +lldb::SBProcess +SBTarget::ConnectRemote +( + SBListener &listener, + const char *url, + const char *plugin_name, + SBError& error +) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBProcess sb_process; + ProcessSP process_sp; + TargetSP target_sp(GetSP()); + + if (log) + { + log->Printf ("SBTarget(%p)::ConnectRemote (listener, url=%s, plugin_name=%s, error)...", target_sp.get(), url, plugin_name); + } + + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + if (listener.IsValid()) + process_sp = target_sp->CreateProcess (listener.ref(), plugin_name, NULL); + else + process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), plugin_name, NULL); + + + if (process_sp) + { + sb_process.SetSP (process_sp); + error.SetError (process_sp->ConnectRemote (NULL, url)); + } + else + { + error.SetErrorString ("unable to create lldb_private::Process"); + } + } + else + { + error.SetErrorString ("SBTarget is invalid"); + } + + if (log) + { + log->Printf ("SBTarget(%p)::ConnectRemote (...) => SBProcess(%p)", + target_sp.get(), process_sp.get()); + } + return sb_process; +} + +SBFileSpec +SBTarget::GetExecutable () +{ + + SBFileSpec exe_file_spec; + TargetSP target_sp(GetSP()); + if (target_sp) + { + Module *exe_module = target_sp->GetExecutableModulePointer(); + if (exe_module) + exe_file_spec.SetFileSpec (exe_module->GetFileSpec()); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)", + target_sp.get(), exe_file_spec.get()); + } + + return exe_file_spec; +} + +bool +SBTarget::operator == (const SBTarget &rhs) const +{ + return m_opaque_sp.get() == rhs.m_opaque_sp.get(); +} + +bool +SBTarget::operator != (const SBTarget &rhs) const +{ + return m_opaque_sp.get() != rhs.m_opaque_sp.get(); +} + +lldb::TargetSP +SBTarget::GetSP () const +{ + return m_opaque_sp; +} + +void +SBTarget::SetSP (const lldb::TargetSP& target_sp) +{ + m_opaque_sp = target_sp; +} + +lldb::SBAddress +SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr) +{ + lldb::SBAddress sb_addr; + Address &addr = sb_addr.ref(); + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + if (target_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, addr)) + return sb_addr; + } + + // We have a load address that isn't in a section, just return an address + // with the offset filled in (the address) and the section set to NULL + addr.SetRawAddress(vm_addr); + return sb_addr; +} + +SBSymbolContext +SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope) +{ + SBSymbolContext sc; + if (addr.IsValid()) + { + TargetSP target_sp(GetSP()); + if (target_sp) + target_sp->GetImages().ResolveSymbolContextForAddress (addr.ref(), resolve_scope, sc.ref()); + } + return sc; +} + + +SBBreakpoint +SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line) +{ + return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file, false), line)); +} + +SBBreakpoint +SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp && line != 0) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + + const LazyBool check_inlines = eLazyBoolCalculate; + const LazyBool skip_prologue = eLazyBoolCalculate; + const bool internal = false; + *sb_bp = target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, check_inlines, skip_prologue, internal); + } + + if (log) + { + SBStream sstr; + sb_bp.GetDescription (sstr); + char path[PATH_MAX]; + sb_file_spec->GetPath (path, sizeof(path)); + log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s", + target_sp.get(), + path, + line, + sb_bp.get(), + sstr.GetData()); + } + + return sb_bp; +} + +SBBreakpoint +SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp.get()) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + + const bool internal = false; + const LazyBool skip_prologue = eLazyBoolCalculate; + if (module_name && module_name[0]) + { + FileSpecList module_spec_list; + module_spec_list.Append (FileSpec (module_name, false)); + *sb_bp = target_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal); + } + else + { + *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal); + } + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)", + target_sp.get(), symbol_name, module_name, sb_bp.get()); + } + + return sb_bp; +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateByName (const char *symbol_name, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list) +{ + uint32_t name_type_mask = eFunctionNameTypeAuto; + return BreakpointCreateByName (symbol_name, name_type_mask, module_list, comp_unit_list); +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateByName (const char *symbol_name, + uint32_t name_type_mask, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp && symbol_name && symbol_name[0]) + { + const bool internal = false; + const LazyBool skip_prologue = eLazyBoolCalculate; + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + *sb_bp = target_sp->CreateBreakpoint (module_list.get(), + comp_unit_list.get(), + symbol_name, + name_type_mask, + skip_prologue, + internal); + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", name_type: %d) => SBBreakpoint(%p)", + target_sp.get(), symbol_name, name_type_mask, sb_bp.get()); + } + + return sb_bp; +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateByNames (const char *symbol_names[], + uint32_t num_names, + uint32_t name_type_mask, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp && num_names > 0) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + const bool internal = false; + const LazyBool skip_prologue = eLazyBoolCalculate; + *sb_bp = target_sp->CreateBreakpoint (module_list.get(), + comp_unit_list.get(), + symbol_names, + num_names, + name_type_mask, + skip_prologue, + internal); + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbols={", target_sp.get()); + for (uint32_t i = 0 ; i < num_names; i++) + { + char sep; + if (i < num_names - 1) + sep = ','; + else + sep = '}'; + if (symbol_names[i] != NULL) + log->Printf ("\"%s\"%c ", symbol_names[i], sep); + else + log->Printf ("\"<NULL>\"%c ", sep); + + } + log->Printf ("name_type: %d) => SBBreakpoint(%p)", name_type_mask, sb_bp.get()); + } + + return sb_bp; +} + +SBBreakpoint +SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp && symbol_name_regex && symbol_name_regex[0]) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + RegularExpression regexp(symbol_name_regex); + const bool internal = false; + const LazyBool skip_prologue = eLazyBoolCalculate; + + if (module_name && module_name[0]) + { + FileSpecList module_spec_list; + module_spec_list.Append (FileSpec (module_name, false)); + + *sb_bp = target_sp->CreateFuncRegexBreakpoint (&module_spec_list, NULL, regexp, skip_prologue, internal); + } + else + { + *sb_bp = target_sp->CreateFuncRegexBreakpoint (NULL, NULL, regexp, skip_prologue, internal); + } + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", + target_sp.get(), symbol_name_regex, module_name, sb_bp.get()); + } + + return sb_bp; +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp && symbol_name_regex && symbol_name_regex[0]) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + RegularExpression regexp(symbol_name_regex); + const bool internal = false; + const LazyBool skip_prologue = eLazyBoolCalculate; + + *sb_bp = target_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, skip_prologue, internal); + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\") => SBBreakpoint(%p)", + target_sp.get(), symbol_name_regex, sb_bp.get()); + } + + return sb_bp; +} + +SBBreakpoint +SBTarget::BreakpointCreateByAddress (addr_t address) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + *sb_bp = target_sp->CreateBreakpoint (address, false); + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%" PRIu64 ") => SBBreakpoint(%p)", target_sp.get(), (uint64_t) address, sb_bp.get()); + } + + return sb_bp; +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpec &source_file, const char *module_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp && source_regex && source_regex[0]) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + RegularExpression regexp(source_regex); + FileSpecList source_file_spec_list; + source_file_spec_list.Append (source_file.ref()); + + if (module_name && module_name[0]) + { + FileSpecList module_spec_list; + module_spec_list.Append (FileSpec (module_name, false)); + + *sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false); + } + else + { + *sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false); + } + } + + if (log) + { + char path[PATH_MAX]; + source_file->GetPath (path, sizeof(path)); + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", + target_sp.get(), source_regex, path, module_name, sb_bp.get()); + } + + return sb_bp; +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, + const SBFileSpecList &module_list, + const lldb::SBFileSpecList &source_file_list) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp && source_regex && source_regex[0]) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + RegularExpression regexp(source_regex); + *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false); + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\") => SBBreakpoint(%p)", + target_sp.get(), source_regex, sb_bp.get()); + } + + return sb_bp; +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateForException (lldb::LanguageType language, + bool catch_bp, + bool throw_bp) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + *sb_bp = target_sp->CreateExceptionBreakpoint (language, catch_bp, throw_bp); + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: %s throw: %s) => SBBreakpoint(%p)", + target_sp.get(), + LanguageRuntime::GetNameForLanguageType(language), + catch_bp ? "on" : "off", + throw_bp ? "on" : "off", + sb_bp.get()); + } + + return sb_bp; +} + +uint32_t +SBTarget::GetNumBreakpoints () const +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + // The breakpoint list is thread safe, no need to lock + return target_sp->GetBreakpointList().GetSize(); + } + return 0; +} + +SBBreakpoint +SBTarget::GetBreakpointAtIndex (uint32_t idx) const +{ + SBBreakpoint sb_breakpoint; + TargetSP target_sp(GetSP()); + if (target_sp) + { + // The breakpoint list is thread safe, no need to lock + *sb_breakpoint = target_sp->GetBreakpointList().GetBreakpointAtIndex(idx); + } + return sb_breakpoint; +} + +bool +SBTarget::BreakpointDelete (break_id_t bp_id) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool result = false; + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + result = target_sp->RemoveBreakpointByID (bp_id); + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i", target_sp.get(), (uint32_t) bp_id, result); + } + + return result; +} + +SBBreakpoint +SBTarget::FindBreakpointByID (break_id_t bp_id) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBBreakpoint sb_breakpoint; + TargetSP target_sp(GetSP()); + if (target_sp && bp_id != LLDB_INVALID_BREAK_ID) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + *sb_breakpoint = target_sp->GetBreakpointByID (bp_id); + } + + if (log) + { + log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)", + target_sp.get(), (uint32_t) bp_id, sb_breakpoint.get()); + } + + return sb_breakpoint; +} + +bool +SBTarget::EnableAllBreakpoints () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + target_sp->EnableAllBreakpoints (); + return true; + } + return false; +} + +bool +SBTarget::DisableAllBreakpoints () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + target_sp->DisableAllBreakpoints (); + return true; + } + return false; +} + +bool +SBTarget::DeleteAllBreakpoints () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + target_sp->RemoveAllBreakpoints (); + return true; + } + return false; +} + +uint32_t +SBTarget::GetNumWatchpoints () const +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + // The watchpoint list is thread safe, no need to lock + return target_sp->GetWatchpointList().GetSize(); + } + return 0; +} + +SBWatchpoint +SBTarget::GetWatchpointAtIndex (uint32_t idx) const +{ + SBWatchpoint sb_watchpoint; + TargetSP target_sp(GetSP()); + if (target_sp) + { + // The watchpoint list is thread safe, no need to lock + sb_watchpoint.SetSP (target_sp->GetWatchpointList().GetByIndex(idx)); + } + return sb_watchpoint; +} + +bool +SBTarget::DeleteWatchpoint (watch_id_t wp_id) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + bool result = false; + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + Mutex::Locker locker; + target_sp->GetWatchpointList().GetListMutex(locker); + result = target_sp->RemoveWatchpointByID (wp_id); + } + + if (log) + { + log->Printf ("SBTarget(%p)::WatchpointDelete (wp_id=%d) => %i", target_sp.get(), (uint32_t) wp_id, result); + } + + return result; +} + +SBWatchpoint +SBTarget::FindWatchpointByID (lldb::watch_id_t wp_id) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBWatchpoint sb_watchpoint; + lldb::WatchpointSP watchpoint_sp; + TargetSP target_sp(GetSP()); + if (target_sp && wp_id != LLDB_INVALID_WATCH_ID) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + Mutex::Locker locker; + target_sp->GetWatchpointList().GetListMutex(locker); + watchpoint_sp = target_sp->GetWatchpointList().FindByID(wp_id); + sb_watchpoint.SetSP (watchpoint_sp); + } + + if (log) + { + log->Printf ("SBTarget(%p)::FindWatchpointByID (bp_id=%d) => SBWatchpoint(%p)", + target_sp.get(), (uint32_t) wp_id, watchpoint_sp.get()); + } + + return sb_watchpoint; +} + +lldb::SBWatchpoint +SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError &error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBWatchpoint sb_watchpoint; + lldb::WatchpointSP watchpoint_sp; + TargetSP target_sp(GetSP()); + if (target_sp && (read || write) && addr != LLDB_INVALID_ADDRESS && size > 0) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + uint32_t watch_type = 0; + if (read) + watch_type |= LLDB_WATCH_TYPE_READ; + if (write) + watch_type |= LLDB_WATCH_TYPE_WRITE; + if (watch_type == 0) + { + error.SetErrorString("Can't create a watchpoint that is neither read nor write."); + return sb_watchpoint; + } + + // Target::CreateWatchpoint() is thread safe. + Error cw_error; + // This API doesn't take in a type, so we can't figure out what it is. + ClangASTType *type = NULL; + watchpoint_sp = target_sp->CreateWatchpoint(addr, size, type, watch_type, cw_error); + error.SetError(cw_error); + sb_watchpoint.SetSP (watchpoint_sp); + } + + if (log) + { + log->Printf ("SBTarget(%p)::WatchAddress (addr=0x%" PRIx64 ", 0x%u) => SBWatchpoint(%p)", + target_sp.get(), addr, (uint32_t) size, watchpoint_sp.get()); + } + + return sb_watchpoint; +} + +bool +SBTarget::EnableAllWatchpoints () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + Mutex::Locker locker; + target_sp->GetWatchpointList().GetListMutex(locker); + target_sp->EnableAllWatchpoints (); + return true; + } + return false; +} + +bool +SBTarget::DisableAllWatchpoints () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + Mutex::Locker locker; + target_sp->GetWatchpointList().GetListMutex(locker); + target_sp->DisableAllWatchpoints (); + return true; + } + return false; +} + +bool +SBTarget::DeleteAllWatchpoints () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + Mutex::Locker locker; + target_sp->GetWatchpointList().GetListMutex(locker); + target_sp->RemoveAllWatchpoints (); + return true; + } + return false; +} + + +lldb::SBModule +SBTarget::AddModule (const char *path, + const char *triple, + const char *uuid_cstr) +{ + return AddModule (path, triple, uuid_cstr, NULL); +} + +lldb::SBModule +SBTarget::AddModule (const char *path, + const char *triple, + const char *uuid_cstr, + const char *symfile) +{ + lldb::SBModule sb_module; + TargetSP target_sp(GetSP()); + if (target_sp) + { + ModuleSpec module_spec; + if (path) + module_spec.GetFileSpec().SetFile(path, false); + + if (uuid_cstr) + module_spec.GetUUID().SetFromCString(uuid_cstr); + + if (triple) + module_spec.GetArchitecture().SetTriple (triple, target_sp->GetPlatform ().get()); + + if (symfile) + module_spec.GetSymbolFileSpec ().SetFile(symfile, false); + + sb_module.SetSP(target_sp->GetSharedModule (module_spec)); + } + return sb_module; +} + +lldb::SBModule +SBTarget::AddModule (const SBModuleSpec &module_spec) +{ + lldb::SBModule sb_module; + TargetSP target_sp(GetSP()); + if (target_sp) + sb_module.SetSP(target_sp->GetSharedModule (*module_spec.m_opaque_ap)); + return sb_module; +} + +bool +SBTarget::AddModule (lldb::SBModule &module) +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + target_sp->GetImages().AppendIfNeeded (module.GetSP()); + return true; + } + return false; +} + +uint32_t +SBTarget::GetNumModules () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num = 0; + TargetSP target_sp(GetSP()); + if (target_sp) + { + // The module list is thread safe, no need to lock + num = target_sp->GetImages().GetSize(); + } + + if (log) + log->Printf ("SBTarget(%p)::GetNumModules () => %d", target_sp.get(), num); + + return num; +} + +void +SBTarget::Clear () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBTarget(%p)::Clear ()", m_opaque_sp.get()); + + m_opaque_sp.reset(); +} + + +SBModule +SBTarget::FindModule (const SBFileSpec &sb_file_spec) +{ + SBModule sb_module; + TargetSP target_sp(GetSP()); + if (target_sp && sb_file_spec.IsValid()) + { + ModuleSpec module_spec(*sb_file_spec); + // The module list is thread safe, no need to lock + sb_module.SetSP (target_sp->GetImages().FindFirstModule (module_spec)); + } + return sb_module; +} + +lldb::ByteOrder +SBTarget::GetByteOrder () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + |