diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/API')
47 files changed, 21554 insertions, 0 deletions
diff --git a/contrib/llvm/tools/lldb/source/API/SBAddress.cpp b/contrib/llvm/tools/lldb/source/API/SBAddress.cpp new file mode 100644 index 0000000..799c909 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBBlock.cpp b/contrib/llvm/tools/lldb/source/API/SBBlock.cpp new file mode 100644 index 0000000..c8a665f --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp b/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp new file mode 100644 index 0000000..11ad149 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBBreakpointLocation.cpp b/contrib/llvm/tools/lldb/source/API/SBBreakpointLocation.cpp new file mode 100644 index 0000000..6fdf59f --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBBroadcaster.cpp b/contrib/llvm/tools/lldb/source/API/SBBroadcaster.cpp new file mode 100644 index 0000000..7168305 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBCommandInterpreter.cpp b/contrib/llvm/tools/lldb/source/API/SBCommandInterpreter.cpp new file mode 100644 index 0000000..0c83900 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBCommandReturnObject.cpp b/contrib/llvm/tools/lldb/source/API/SBCommandReturnObject.cpp new file mode 100644 index 0000000..83d6563 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBCommunication.cpp b/contrib/llvm/tools/lldb/source/API/SBCommunication.cpp new file mode 100644 index 0000000..10feae5 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBCompileUnit.cpp b/contrib/llvm/tools/lldb/source/API/SBCompileUnit.cpp new file mode 100644 index 0000000..9f74877 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBData.cpp b/contrib/llvm/tools/lldb/source/API/SBData.cpp new file mode 100644 index 0000000..5b2f075 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp b/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp new file mode 100644 index 0000000..f5e71d5 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBDeclaration.cpp b/contrib/llvm/tools/lldb/source/API/SBDeclaration.cpp new file mode 100644 index 0000000..fc90156 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBError.cpp b/contrib/llvm/tools/lldb/source/API/SBError.cpp new file mode 100644 index 0000000..bd6b543 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBEvent.cpp b/contrib/llvm/tools/lldb/source/API/SBEvent.cpp new file mode 100644 index 0000000..d5d4a84 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBExpressionOptions.cpp b/contrib/llvm/tools/lldb/source/API/SBExpressionOptions.cpp new file mode 100644 index 0000000..127b0cf --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBFileSpec.cpp b/contrib/llvm/tools/lldb/source/API/SBFileSpec.cpp new file mode 100644 index 0000000..4413689 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBFileSpecList.cpp b/contrib/llvm/tools/lldb/source/API/SBFileSpecList.cpp new file mode 100644 index 0000000..3ebf3cc --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBFrame.cpp b/contrib/llvm/tools/lldb/source/API/SBFrame.cpp new file mode 100644 index 0000000..1a1a63b --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBFunction.cpp b/contrib/llvm/tools/lldb/source/API/SBFunction.cpp new file mode 100644 index 0000000..914d2d7 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBHostOS.cpp b/contrib/llvm/tools/lldb/source/API/SBHostOS.cpp new file mode 100644 index 0000000..a8f7db9 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBInputReader.cpp b/contrib/llvm/tools/lldb/source/API/SBInputReader.cpp new file mode 100644 index 0000000..82b75c8 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp b/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp new file mode 100644 index 0000000..2334cc0 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp @@ -0,0 +1,248 @@ +//===-- SBInstruction.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBInstruction.h" + +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBFrame.h" +#include "lldb/API/SBInstruction.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBTarget.h" + +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/EmulateInstruction.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +SBInstruction::SBInstruction () +{ +} + +SBInstruction::SBInstruction (const lldb::InstructionSP& inst_sp) : + m_opaque_sp (inst_sp) +{ +} + +SBInstruction::SBInstruction(const SBInstruction &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +const SBInstruction & +SBInstruction::operator = (const SBInstruction &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +SBInstruction::~SBInstruction () +{ +} + +bool +SBInstruction::IsValid() +{ + return (m_opaque_sp.get() != NULL); +} + +SBAddress +SBInstruction::GetAddress() +{ + SBAddress sb_addr; + if (m_opaque_sp && m_opaque_sp->GetAddress().IsValid()) + sb_addr.SetAddress(&m_opaque_sp->GetAddress()); + return sb_addr; +} + +const char * +SBInstruction::GetMnemonic(SBTarget target) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker; + ExecutionContext exe_ctx; + TargetSP target_sp (target.GetSP()); + if (target_sp) + { + api_locker.Lock (target_sp->GetAPIMutex()); + target_sp->CalculateExecutionContext (exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); + } + return m_opaque_sp->GetMnemonic(&exe_ctx); + } + return NULL; +} + +const char * +SBInstruction::GetOperands(SBTarget target) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker; + ExecutionContext exe_ctx; + TargetSP target_sp (target.GetSP()); + if (target_sp) + { + api_locker.Lock (target_sp->GetAPIMutex()); + target_sp->CalculateExecutionContext (exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); + } + return m_opaque_sp->GetOperands(&exe_ctx); + } + return NULL; +} + +const char * +SBInstruction::GetComment(SBTarget target) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker; + ExecutionContext exe_ctx; + TargetSP target_sp (target.GetSP()); + if (target_sp) + { + api_locker.Lock (target_sp->GetAPIMutex()); + target_sp->CalculateExecutionContext (exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); + } + return m_opaque_sp->GetComment(&exe_ctx); + } + return NULL; +} + +size_t +SBInstruction::GetByteSize () +{ + if (m_opaque_sp) + return m_opaque_sp->GetOpcode().GetByteSize(); + return 0; +} + +SBData +SBInstruction::GetData (SBTarget target) +{ + lldb::SBData sb_data; + if (m_opaque_sp) + { + DataExtractorSP data_extractor_sp (new DataExtractor()); + if (m_opaque_sp->GetData (*data_extractor_sp)) + { + sb_data.SetOpaque (data_extractor_sp); + } + } + return sb_data; +} + + + +bool +SBInstruction::DoesBranch () +{ + if (m_opaque_sp) + return m_opaque_sp->DoesBranch (); + return false; +} + +void +SBInstruction::SetOpaque (const lldb::InstructionSP &inst_sp) +{ + m_opaque_sp = inst_sp; +} + +bool +SBInstruction::GetDescription (lldb::SBStream &s) +{ + if (m_opaque_sp) + { + // Use the "ref()" instead of the "get()" accessor in case the SBStream + // didn't have a stream already created, one will get created... + m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL); + return true; + } + return false; +} + +void +SBInstruction::Print (FILE *out) +{ + if (out == NULL) + return; + + if (m_opaque_sp) + { + StreamFile out_stream (out, false); + m_opaque_sp->Dump (&out_stream, 0, true, false, NULL); + } +} + +bool +SBInstruction::EmulateWithFrame (lldb::SBFrame &frame, uint32_t evaluate_options) +{ + if (m_opaque_sp) + { + lldb::StackFrameSP frame_sp (frame.GetFrameSP()); + + if (frame_sp) + { + lldb_private::ExecutionContext exe_ctx; + frame_sp->CalculateExecutionContext (exe_ctx); + lldb_private::Target *target = exe_ctx.GetTargetPtr(); + lldb_private::ArchSpec arch = target->GetArchitecture(); + + return m_opaque_sp->Emulate (arch, + evaluate_options, + (void *) frame_sp.get(), + &lldb_private::EmulateInstruction::ReadMemoryFrame, + &lldb_private::EmulateInstruction::WriteMemoryFrame, + &lldb_private::EmulateInstruction::ReadRegisterFrame, + &lldb_private::EmulateInstruction::WriteRegisterFrame); + } + } + return false; +} + +bool +SBInstruction::DumpEmulation (const char *triple) +{ + if (m_opaque_sp && triple) + { + lldb_private::ArchSpec arch (triple, NULL); + + return m_opaque_sp->DumpEmulation (arch); + + } + return false; +} + +bool +SBInstruction::TestEmulation (lldb::SBStream &output_stream, const char *test_file) +{ + if (!m_opaque_sp.get()) + m_opaque_sp.reset (new PseudoInstruction()); + + return m_opaque_sp->TestEmulation (output_stream.get(), test_file); +} + +lldb::AddressClass +SBInstruction::GetAddressClass () +{ + if (m_opaque_sp.get()) + return m_opaque_sp->GetAddressClass(); + return eAddressClassInvalid; +} diff --git a/contrib/llvm/tools/lldb/source/API/SBInstructionList.cpp b/contrib/llvm/tools/lldb/source/API/SBInstructionList.cpp new file mode 100644 index 0000000..fe22d9c --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBLineEntry.cpp b/contrib/llvm/tools/lldb/source/API/SBLineEntry.cpp new file mode 100644 index 0000000..0864a2e --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBListener.cpp b/contrib/llvm/tools/lldb/source/API/SBListener.cpp new file mode 100644 index 0000000..2e67b4c --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBModule.cpp b/contrib/llvm/tools/lldb/source/API/SBModule.cpp new file mode 100644 index 0000000..5f5fc92 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBModuleSpec.cpp b/contrib/llvm/tools/lldb/source/API/SBModuleSpec.cpp new file mode 100644 index 0000000..654a8ca --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBProcess.cpp b/contrib/llvm/tools/lldb/source/API/SBProcess.cpp new file mode 100644 index 0000000..259eb5e --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBSection.cpp b/contrib/llvm/tools/lldb/source/API/SBSection.cpp new file mode 100644 index 0000000..3fb84e8 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBSourceManager.cpp b/contrib/llvm/tools/lldb/source/API/SBSourceManager.cpp new file mode 100644 index 0000000..0b8cbfc --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBStream.cpp b/contrib/llvm/tools/lldb/source/API/SBStream.cpp new file mode 100644 index 0000000..dc8eb05 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBStringList.cpp b/contrib/llvm/tools/lldb/source/API/SBStringList.cpp new file mode 100644 index 0000000..129d2f4 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBSymbol.cpp b/contrib/llvm/tools/lldb/source/API/SBSymbol.cpp new file mode 100644 index 0000000..dd057e8 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBSymbolContext.cpp b/contrib/llvm/tools/lldb/source/API/SBSymbolContext.cpp new file mode 100644 index 0000000..479b0f7 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBSymbolContextList.cpp b/contrib/llvm/tools/lldb/source/API/SBSymbolContextList.cpp new file mode 100644 index 0000000..0730096 --- /dev/null +++ b/contrib/llvm/tools/lldb/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/contrib/llvm/tools/lldb/source/API/SBTarget.cpp b/contrib/llvm/tools/lldb/source/API/SBTarget.cpp new file mode 100644 index 0000000..f37c8f8 --- /dev/null +++ b/contrib/llvm/tools/lldb/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) + return target_sp->GetArchitecture().GetByteOrder(); + return eByteOrderInvalid; +} + +const char * +SBTarget::GetTriple () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + std::string triple (target_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 +SBTarget::GetAddressByteSize() +{ + TargetSP target_sp(GetSP()); + if (target_sp) + return target_sp->GetArchitecture().GetAddressByteSize(); + return sizeof(void*); +} + + +SBModule +SBTarget::GetModuleAtIndex (uint32_t idx) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBModule sb_module; + ModuleSP module_sp; + TargetSP target_sp(GetSP()); + if (target_sp) + { + // The module list is thread safe, no need to lock + module_sp = target_sp->GetImages().GetModuleAtIndex(idx); + sb_module.SetSP (module_sp); + } + + if (log) + { + log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)", + target_sp.get(), idx, module_sp.get()); + } + + return sb_module; +} + +bool +SBTarget::RemoveModule (lldb::SBModule module) +{ + TargetSP target_sp(GetSP()); + if (target_sp) + return target_sp->GetImages().Remove(module.GetSP()); + return false; +} + + +SBBroadcaster +SBTarget::GetBroadcaster () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + TargetSP target_sp(GetSP()); + SBBroadcaster broadcaster(target_sp.get(), false); + + if (log) + log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)", + target_sp.get(), broadcaster.get()); + + return broadcaster; +} + +bool +SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) +{ + Stream &strm = description.ref(); + + TargetSP target_sp(GetSP()); + if (target_sp) + { + target_sp->Dump (&strm, description_level); + } + else + strm.PutCString ("No value"); + + return true; +} + +lldb::SBSymbolContextList +SBTarget::FindFunctions (const char *name, uint32_t name_type_mask) +{ + lldb::SBSymbolContextList sb_sc_list; + if (name && name[0]) + { + TargetSP target_sp(GetSP()); + if (target_sp) + { + const bool symbols_ok = true; + const bool inlines_ok = true; + const bool append = true; + target_sp->GetImages().FindFunctions (ConstString(name), + name_type_mask, + symbols_ok, + inlines_ok, + append, + *sb_sc_list); + } + } + return sb_sc_list; +} + +lldb::SBType +SBTarget::FindFirstType (const char* typename_cstr) +{ + TargetSP target_sp(GetSP()); + if (typename_cstr && typename_cstr[0] && target_sp) + { + ConstString const_typename(typename_cstr); + SymbolContext sc; + const bool exact_match = false; + + const ModuleList &module_list = target_sp->GetImages(); + size_t count = module_list.GetSize(); + for (size_t idx = 0; idx < count; idx++) + { + ModuleSP module_sp (module_list.GetModuleAtIndex(idx)); + if (module_sp) + { + TypeSP type_sp (module_sp->FindFirstType(sc, const_typename, exact_match)); + if (type_sp) + return SBType(type_sp); + } + } + + // Didn't find the type in the symbols; try the Objective-C runtime + // if one is installed + + ProcessSP process_sp(target_sp->GetProcessSP()); + + if (process_sp) + { + ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime(); + + if (objc_language_runtime) + { + TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor(); + + if (objc_type_vendor) + { + std::vector <ClangASTType> types; + + if (objc_type_vendor->FindTypes(const_typename, true, 1, types) > 0) + return SBType(types[0]); + } + } + } + + // No matches, search for basic typename matches + ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); + if (clang_ast) + return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename)); + } + return SBType(); +} + +SBType +SBTarget::GetBasicType(lldb::BasicType type) +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); + if (clang_ast) + return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), type)); + } + return SBType(); +} + + +lldb::SBTypeList +SBTarget::FindTypes (const char* typename_cstr) +{ + SBTypeList sb_type_list; + TargetSP target_sp(GetSP()); + if (typename_cstr && typename_cstr[0] && target_sp) + { + ModuleList& images = target_sp->GetImages(); + ConstString const_typename(typename_cstr); + bool exact_match = false; + SymbolContext sc; + TypeList type_list; + + uint32_t num_matches = images.FindTypes (sc, + const_typename, + 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) + sb_type_list.Append(SBType(type_sp)); + } + } + + // Try the Objective-C runtime if one is installed + + ProcessSP process_sp(target_sp->GetProcessSP()); + + if (process_sp) + { + ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime(); + + if (objc_language_runtime) + { + TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor(); + + if (objc_type_vendor) + { + std::vector <ClangASTType> types; + + if (objc_type_vendor->FindTypes(const_typename, true, UINT32_MAX, types)) + { + for (ClangASTType &type : types) + { + sb_type_list.Append(SBType(type)); + } + } + } + } + } + + if (sb_type_list.GetSize() == 0) + { + // No matches, search for basic typename matches + ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); + if (clang_ast) + sb_type_list.Append (SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename))); + } + } + return sb_type_list; +} + +SBValueList +SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches) +{ + SBValueList sb_value_list; + + TargetSP target_sp(GetSP()); + if (name && target_sp) + { + VariableList variable_list; + const bool append = true; + const uint32_t match_count = target_sp->GetImages().FindGlobalVariables (ConstString (name), + append, + max_matches, + variable_list); + + if (match_count > 0) + { + ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get(); + if (exe_scope == NULL) + exe_scope = target_sp.get(); + for (uint32_t i=0; i<match_count; ++i) + { + lldb::ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_scope, variable_list.GetVariableAtIndex(i))); + if (valobj_sp) + sb_value_list.Append(SBValue(valobj_sp)); + } + } + } + + return sb_value_list; +} + +lldb::SBValue +SBTarget::FindFirstGlobalVariable (const char* name) +{ + SBValueList sb_value_list(FindGlobalVariables(name, 1)); + if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0) + return sb_value_list.GetValueAtIndex(0); + return SBValue(); +} + +SBSourceManager +SBTarget::GetSourceManager() +{ + SBSourceManager source_manager (*this); + return source_manager; +} + +lldb::SBInstructionList +SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count) +{ + return ReadInstructions (base_addr, count, NULL); +} + +lldb::SBInstructionList +SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string) +{ + SBInstructionList sb_instructions; + + TargetSP target_sp(GetSP()); + if (target_sp) + { + Address *addr_ptr = base_addr.get(); + + if (addr_ptr) + { + DataBufferHeap data (target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0); + bool prefer_file_cache = false; + lldb_private::Error error; + lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; + const size_t bytes_read = target_sp->ReadMemory(*addr_ptr, + prefer_file_cache, + data.GetBytes(), + data.GetByteSize(), + error, + &load_addr); + const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; + sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(), + NULL, + flavor_string, + *addr_ptr, + data.GetBytes(), + bytes_read, + count, + data_from_file)); + } + } + + return sb_instructions; + +} + +lldb::SBInstructionList +SBTarget::GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size) +{ + return GetInstructionsWithFlavor (base_addr, NULL, buf, size); +} + +lldb::SBInstructionList +SBTarget::GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size) +{ + SBInstructionList sb_instructions; + + TargetSP target_sp(GetSP()); + if (target_sp) + { + Address addr; + + if (base_addr.get()) + addr = *base_addr.get(); + + const bool data_from_file = true; + + sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(), + NULL, + flavor_string, + addr, + buf, + size, + UINT32_MAX, + data_from_file)); + } + + return sb_instructions; +} + +lldb::SBInstructionList +SBTarget::GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size) +{ + return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), NULL, buf, size); +} + +lldb::SBInstructionList +SBTarget::GetInstructionsWithFlavor (lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size) +{ + return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), flavor_string, buf, size); +} + +SBError +SBTarget::SetSectionLoadAddress (lldb::SBSection section, + lldb::addr_t section_base_addr) +{ + SBError sb_error; + TargetSP target_sp(GetSP()); + if (target_sp) + { + if (!section.IsValid()) + { + sb_error.SetErrorStringWithFormat ("invalid section"); + } + else + { + SectionSP section_sp (section.GetSP()); + if (section_sp) + { + if (section_sp->IsThreadSpecific()) + { + sb_error.SetErrorString ("thread specific sections are not yet supported"); + } + else + { + if (target_sp->GetSectionLoadList().SetSectionLoadAddress (section_sp, section_base_addr)) + { + // Flush info in the process (stack frames, etc) + ProcessSP process_sp (target_sp->GetProcessSP()); + if (process_sp) + process_sp->Flush(); + } + } + } + } + } + else + { + sb_error.SetErrorString ("invalid target"); + } + return sb_error; +} + +SBError +SBTarget::ClearSectionLoadAddress (lldb::SBSection section) +{ + SBError sb_error; + + TargetSP target_sp(GetSP()); + if (target_sp) + { + if (!section.IsValid()) + { + sb_error.SetErrorStringWithFormat ("invalid section"); + } + else + { + if (target_sp->GetSectionLoadList().SetSectionUnloaded (section.GetSP())) + { + // Flush info in the process (stack frames, etc) + ProcessSP process_sp (target_sp->GetProcessSP()); + if (process_sp) + process_sp->Flush(); + } + } + } + else + { + sb_error.SetErrorStringWithFormat ("invalid target"); + } + return sb_error; +} + +SBError +SBTarget::SetModuleLoadAddress (lldb::SBModule module, int64_t slide_offset) +{ + SBError sb_error; + + TargetSP target_sp(GetSP()); + if (target_sp) + { + ModuleSP module_sp (module.GetSP()); + if (module_sp) + { + bool changed = false; + if (module_sp->SetLoadAddress (*target_sp, slide_offset, changed)) + { + // The load was successful, make sure that at least some sections + // changed before we notify that our module was loaded. + if (changed) + { + ModuleList module_list; + module_list.Append(module_sp); + target_sp->ModulesDidLoad (module_list); + // Flush info in the process (stack frames, etc) + ProcessSP process_sp (target_sp->GetProcessSP()); + if (process_sp) + process_sp->Flush(); + } + } + } + else + { + sb_error.SetErrorStringWithFormat ("invalid module"); + } + + } + else + { + sb_error.SetErrorStringWithFormat ("invalid target"); + } + return sb_error; +} + +SBError +SBTarget::ClearModuleLoadAddress (lldb::SBModule module) +{ + SBError sb_error; + + char path[PATH_MAX]; + TargetSP target_sp(GetSP()); + if (target_sp) + { + ModuleSP module_sp (module.GetSP()); + if (module_sp) + { + ObjectFile *objfile = module_sp->GetObjectFile(); + if (objfile) + { + SectionList *section_list = objfile->GetSectionList(); + if (section_list) + { + bool changed = false; + const size_t num_sections = section_list->GetSize(); + for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) + { + SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx)); + if (section_sp) + changed |= target_sp->GetSectionLoadList().SetSectionUnloaded (section_sp) > 0; + } + if (changed) + { + // Flush info in the process (stack frames, etc) + ProcessSP process_sp (target_sp->GetProcessSP()); + if (process_sp) + process_sp->Flush(); + } + } + else + { + module_sp->GetFileSpec().GetPath (path, sizeof(path)); + sb_error.SetErrorStringWithFormat ("no sections in object file '%s'", path); + } + } + else + { + module_sp->GetFileSpec().GetPath (path, sizeof(path)); + sb_error.SetErrorStringWithFormat ("no object file for module '%s'", path); + } + } + else + { + sb_error.SetErrorStringWithFormat ("invalid module"); + } + } + else + { + sb_error.SetErrorStringWithFormat ("invalid target"); + } + return sb_error; +} + + +lldb::SBSymbolContextList +SBTarget::FindSymbols (const char *name, lldb::SymbolType symbol_type) +{ + SBSymbolContextList sb_sc_list; + if (name && name[0]) + { + TargetSP target_sp(GetSP()); + if (target_sp) + { + bool append = true; + target_sp->GetImages().FindSymbolsWithNameAndType (ConstString(name), + symbol_type, + *sb_sc_list, + append); + } + } + return sb_sc_list; + +} + + +lldb::SBValue +SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &options) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + Log * expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + SBValue expr_result; + ExecutionResults exe_results = eExecutionSetupError; + ValueObjectSP expr_value_sp; + TargetSP target_sp(GetSP()); + StackFrame *frame = NULL; + if (target_sp) + { + if (expr == NULL || expr[0] == '\0') + { + if (log) + log->Printf ("SBTarget::EvaluateExpression called with an empty expression"); + return expr_result; + } + + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + ExecutionContext exe_ctx (m_opaque_sp.get()); + + if (log) + log->Printf ("SBTarget()::EvaluateExpression (expr=\"%s\")...", expr); + + frame = exe_ctx.GetFramePtr(); + Target *target = exe_ctx.GetTargetPtr(); + + if (target) + { +#ifdef LLDB_CONFIGURATION_DEBUG + StreamString frame_description; + if (frame) + frame->DumpUsingSettingsFormat (&frame_description); + Host::SetCrashDescriptionWithFormat ("SBTarget::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 ("SBTarget::EvaluateExpression () => error: could not reconstruct frame object for this SBTarget."); + } + } +#ifndef LLDB_DISABLE_PYTHON + if (expr_log) + expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is %s, summary %s **", + expr_result.GetValue(), + expr_result.GetSummary()); + + if (log) + log->Printf ("SBTarget(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", + frame, + expr, + expr_value_sp.get(), + exe_results); +#endif + + return expr_result; +} + + +lldb::addr_t +SBTarget::GetStackRedZoneSize() +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + ABISP abi_sp; + ProcessSP process_sp (target_sp->GetProcessSP()); + if (process_sp) + abi_sp = process_sp->GetABI(); + else + abi_sp = ABI::FindPlugin(target_sp->GetArchitecture()); + if (abi_sp) + return abi_sp->GetRedZoneSize(); + } + return 0; +} + diff --git a/contrib/llvm/tools/lldb/source/API/SBThread.cpp b/contrib/llvm/tools/lldb/source/API/SBThread.cpp new file mode 100644 index 0000000..2752620 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBThread.cpp @@ -0,0 +1,1229 @@ +//===-- SBThread.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/SBThread.h" + +#include "lldb/API/SBSymbolContext.h" +#include "lldb/API/SBFileSpec.h" +#include "lldb/API/SBStream.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/State.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/Process.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Target/StopInfo.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/ThreadPlanStepInstruction.h" +#include "lldb/Target/ThreadPlanStepOut.h" +#include "lldb/Target/ThreadPlanStepRange.h" +#include "lldb/Target/ThreadPlanStepInRange.h" + + +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBFrame.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBValue.h" + +using namespace lldb; +using namespace lldb_private; + +const char * +SBThread::GetBroadcasterClassName () +{ + return Thread::GetStaticBroadcasterClass().AsCString(); +} + +//---------------------------------------------------------------------- +// Constructors +//---------------------------------------------------------------------- +SBThread::SBThread () : + m_opaque_sp (new ExecutionContextRef()) +{ +} + +SBThread::SBThread (const ThreadSP& lldb_object_sp) : + m_opaque_sp (new ExecutionContextRef(lldb_object_sp)) +{ +} + +SBThread::SBThread (const SBThread &rhs) : + m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp)) +{ + +} + +//---------------------------------------------------------------------- +// Assignment operator +//---------------------------------------------------------------------- + +const lldb::SBThread & +SBThread::operator = (const SBThread &rhs) +{ + if (this != &rhs) + *m_opaque_sp = *rhs.m_opaque_sp; + return *this; +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBThread::~SBThread() +{ +} + +bool +SBThread::IsValid() const +{ + return m_opaque_sp->GetThreadSP().get() != NULL; +} + +void +SBThread::Clear () +{ + m_opaque_sp->Clear(); +} + + +StopReason +SBThread::GetStopReason() +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + StopReason reason = eStopReasonInvalid; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + return exe_ctx.GetThreadPtr()->GetStopReason(); + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(), + Thread::StopReasonAsCString (reason)); + + return reason; +} + +size_t +SBThread::GetStopReasonDataCount () +{ + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); + if (stop_info_sp) + { + StopReason reason = stop_info_sp->GetStopReason(); + switch (reason) + { + case eStopReasonInvalid: + case eStopReasonNone: + case eStopReasonTrace: + case eStopReasonExec: + case eStopReasonPlanComplete: + case eStopReasonThreadExiting: + // There is no data for these stop reasons. + return 0; + + case eStopReasonBreakpoint: + { + break_id_t site_id = stop_info_sp->GetValue(); + lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); + if (bp_site_sp) + return bp_site_sp->GetNumberOfOwners () * 2; + else + return 0; // Breakpoint must have cleared itself... + } + break; + + case eStopReasonWatchpoint: + return 1; + + case eStopReasonSignal: + return 1; + + case eStopReasonException: + return 1; + } + } + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + return 0; +} + +uint64_t +SBThread::GetStopReasonDataAtIndex (uint32_t idx) +{ + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Thread *thread = exe_ctx.GetThreadPtr(); + StopInfoSP stop_info_sp = thread->GetStopInfo (); + if (stop_info_sp) + { + StopReason reason = stop_info_sp->GetStopReason(); + switch (reason) + { + case eStopReasonInvalid: + case eStopReasonNone: + case eStopReasonTrace: + case eStopReasonExec: + case eStopReasonPlanComplete: + case eStopReasonThreadExiting: + // There is no data for these stop reasons. + return 0; + + case eStopReasonBreakpoint: + { + break_id_t site_id = stop_info_sp->GetValue(); + lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); + if (bp_site_sp) + { + uint32_t bp_index = idx / 2; + BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); + if (bp_loc_sp) + { + if (bp_index & 1) + { + // Odd idx, return the breakpoint location ID + return bp_loc_sp->GetID(); + } + else + { + // Even idx, return the breakpoint ID + return bp_loc_sp->GetBreakpoint().GetID(); + } + } + } + return LLDB_INVALID_BREAK_ID; + } + break; + + case eStopReasonWatchpoint: + return stop_info_sp->GetValue(); + + case eStopReasonSignal: + return stop_info_sp->GetValue(); + + case eStopReasonException: + return stop_info_sp->GetValue(); + } + } + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + return 0; +} + +size_t +SBThread::GetStopDescription (char *dst, size_t dst_len) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + + StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); + if (stop_info_sp) + { + const char *stop_desc = stop_info_sp->GetDescription(); + if (stop_desc) + { + if (log) + log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", + exe_ctx.GetThreadPtr(), stop_desc); + if (dst) + return ::snprintf (dst, dst_len, "%s", stop_desc); + else + { + // NULL dst passed in, return the length needed to contain the description + return ::strlen (stop_desc) + 1; // Include the NULL byte for size + } + } + else + { + size_t stop_desc_len = 0; + switch (stop_info_sp->GetStopReason()) + { + case eStopReasonTrace: + case eStopReasonPlanComplete: + { + static char trace_desc[] = "step"; + stop_desc = trace_desc; + stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size + } + break; + + case eStopReasonBreakpoint: + { + static char bp_desc[] = "breakpoint hit"; + stop_desc = bp_desc; + stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size + } + break; + + case eStopReasonWatchpoint: + { + static char wp_desc[] = "watchpoint hit"; + stop_desc = wp_desc; + stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size + } + break; + + case eStopReasonSignal: + { + stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); + if (stop_desc == NULL || stop_desc[0] == '\0') + { + static char signal_desc[] = "signal"; + stop_desc = signal_desc; + stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size + } + } + break; + + case eStopReasonException: + { + char exc_desc[] = "exception"; + stop_desc = exc_desc; + stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size + } + break; + + case eStopReasonExec: + { + char exc_desc[] = "exec"; + stop_desc = exc_desc; + stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size + } + break; + + case eStopReasonThreadExiting: + { + char limbo_desc[] = "thread exiting"; + stop_desc = limbo_desc; + stop_desc_len = sizeof(limbo_desc); + } + break; + default: + break; + } + + if (stop_desc && stop_desc[0]) + { + if (log) + log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", + exe_ctx.GetThreadPtr(), stop_desc); + + if (dst) + return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte + + if (stop_desc_len == 0) + stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte + + return stop_desc_len; + } + } + } + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + if (dst) + *dst = 0; + return 0; +} + +SBValue +SBThread::GetStopReturnValue () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ValueObjectSP return_valobj_sp; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); + if (stop_info_sp) + { + return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); + } + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(), + return_valobj_sp.get() + ? return_valobj_sp->GetValueAsCString() + : "<no return value>"); + + return SBValue (return_valobj_sp); +} + +void +SBThread::SetThread (const ThreadSP& lldb_object_sp) +{ + m_opaque_sp->SetThreadSP (lldb_object_sp); +} + + +lldb::tid_t +SBThread::GetThreadID () const +{ + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); + if (thread_sp) + return thread_sp->GetID(); + return LLDB_INVALID_THREAD_ID; +} + +uint32_t +SBThread::GetIndexID () const +{ + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); + if (thread_sp) + return thread_sp->GetIndexID(); + return LLDB_INVALID_INDEX32; +} + +const char * +SBThread::GetName () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *name = NULL; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + name = exe_ctx.GetThreadPtr()->GetName(); + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); + + return name; +} + +const char * +SBThread::GetQueueName () const +{ + const char *name = NULL; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + name = exe_ctx.GetThreadPtr()->GetQueueName(); + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); + + return name; +} + +SBError +SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan) +{ + SBError sb_error; + + Process *process = exe_ctx.GetProcessPtr(); + if (!process) + { + sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); + return sb_error; + } + + Thread *thread = exe_ctx.GetThreadPtr(); + if (!thread) + { + sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); + return sb_error; + } + + // User level plans should be Master Plans so they can be interrupted, other plans executed, and + // then a "continue" will resume the plan. + if (new_plan != NULL) + { + new_plan->SetIsMasterPlan(true); + new_plan->SetOkayToDiscard(false); + } + + // Why do we need to set the current thread by ID here??? + process->GetThreadList().SetSelectedThreadByID (thread->GetID()); + sb_error.ref() = process->Resume(); + + if (sb_error.Success()) + { + // If we are doing synchronous mode, then wait for the + // process to stop yet again! + if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) + process->WaitForProcessToStop (NULL); + } + + return sb_error; +} + +void +SBThread::StepOver (lldb::RunMode stop_other_threads) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + + if (log) + log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), + Thread::RunModeAsCString (stop_other_threads)); + + if (exe_ctx.HasThreadScope()) + { + Thread *thread = exe_ctx.GetThreadPtr(); + bool abort_other_plans = false; + StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); + + ThreadPlanSP new_plan_sp; + if (frame_sp) + { + if (frame_sp->HasDebugInformation ()) + { + SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); + new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, + sc.line_entry.range, + sc, + stop_other_threads); + } + else + { + new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, + abort_other_plans, + stop_other_threads); + } + } + + // This returns an error, we should use it! + ResumeNewPlan (exe_ctx, new_plan_sp.get()); + } +} + +void +SBThread::StepInto (lldb::RunMode stop_other_threads) +{ + StepInto (NULL, stop_other_threads); +} + +void +SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (log) + log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", + exe_ctx.GetThreadPtr(), + target_name? target_name: "<NULL>", + Thread::RunModeAsCString (stop_other_threads)); + + if (exe_ctx.HasThreadScope()) + { + bool abort_other_plans = false; + + Thread *thread = exe_ctx.GetThreadPtr(); + StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); + ThreadPlanSP new_plan_sp; + + if (frame_sp && frame_sp->HasDebugInformation ()) + { + bool avoid_code_without_debug_info = true; + SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); + new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, + sc.line_entry.range, + sc, + target_name, + stop_other_threads, + avoid_code_without_debug_info); + } + else + { + new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, + abort_other_plans, + stop_other_threads); + } + + // This returns an error, we should use it! + ResumeNewPlan (exe_ctx, new_plan_sp.get()); + } +} + +void +SBThread::StepOut () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + + if (log) + log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr()); + + if (exe_ctx.HasThreadScope()) + { + bool abort_other_plans = false; + bool stop_other_threads = false; + + Thread *thread = exe_ctx.GetThreadPtr(); + + ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, + NULL, + false, + stop_other_threads, + eVoteYes, + eVoteNoOpinion, + 0)); + + // This returns an error, we should use it! + ResumeNewPlan (exe_ctx, new_plan_sp.get()); + } +} + +void +SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrameSP frame_sp (sb_frame.GetFrameSP()); + if (log) + { + SBStream frame_desc_strm; + sb_frame.GetDescription (frame_desc_strm); + log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); + } + + if (exe_ctx.HasThreadScope()) + { + bool abort_other_plans = false; + bool stop_other_threads = false; + Thread *thread = exe_ctx.GetThreadPtr(); + + ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, + NULL, + false, + stop_other_threads, + eVoteYes, + eVoteNoOpinion, + frame_sp->GetFrameIndex())); + + // This returns an error, we should use it! + ResumeNewPlan (exe_ctx, new_plan_sp.get()); + } +} + +void +SBThread::StepInstruction (bool step_over) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + + + if (log) + log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over); + + if (exe_ctx.HasThreadScope()) + { + Thread *thread = exe_ctx.GetThreadPtr(); + ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true)); + + // This returns an error, we should use it! + ResumeNewPlan (exe_ctx, new_plan_sp.get()); + } +} + +void +SBThread::RunToAddress (lldb::addr_t addr) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + + if (log) + log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr); + + if (exe_ctx.HasThreadScope()) + { + bool abort_other_plans = false; + bool stop_other_threads = true; + + Address target_addr (addr); + + Thread *thread = exe_ctx.GetThreadPtr(); + + ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads)); + + // This returns an error, we should use it! + ResumeNewPlan (exe_ctx, new_plan_sp.get()); + } +} + +SBError +SBThread::StepOverUntil (lldb::SBFrame &sb_frame, + lldb::SBFileSpec &sb_file_spec, + uint32_t line) +{ + SBError sb_error; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + char path[PATH_MAX]; + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + StackFrameSP frame_sp (sb_frame.GetFrameSP()); + + if (log) + { + SBStream frame_desc_strm; + sb_frame.GetDescription (frame_desc_strm); + sb_file_spec->GetPath (path, sizeof(path)); + log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", + exe_ctx.GetThreadPtr(), + frame_sp.get(), + frame_desc_strm.GetData(), + path, line); + } + + if (exe_ctx.HasThreadScope()) + { + Target *target = exe_ctx.GetTargetPtr(); + Thread *thread = exe_ctx.GetThreadPtr(); + + if (line == 0) + { + sb_error.SetErrorString("invalid line argument"); + return sb_error; + } + + if (!frame_sp) + { + frame_sp = thread->GetSelectedFrame (); + if (!frame_sp) + frame_sp = thread->GetStackFrameAtIndex (0); + } + + SymbolContext frame_sc; + if (!frame_sp) + { + sb_error.SetErrorString("no valid frames in thread to step"); + return sb_error; + } + + // If we have a frame, get its line + frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | + eSymbolContextFunction | + eSymbolContextLineEntry | + eSymbolContextSymbol ); + + if (frame_sc.comp_unit == NULL) + { + sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); + return sb_error; + } + + FileSpec step_file_spec; + if (sb_file_spec.IsValid()) + { + // The file spec passed in was valid, so use it + step_file_spec = sb_file_spec.ref(); + } + else + { + if (frame_sc.line_entry.IsValid()) + step_file_spec = frame_sc.line_entry.file; + else + { + sb_error.SetErrorString("invalid file argument or no file for frame"); + return sb_error; + } + } + + // Grab the current function, then we will make sure the "until" address is + // within the function. We discard addresses that are out of the current + // function, and then if there are no addresses remaining, give an appropriate + // error message. + + bool all_in_function = true; + AddressRange fun_range = frame_sc.function->GetAddressRange(); + + std::vector<addr_t> step_over_until_addrs; + const bool abort_other_plans = false; + const bool stop_other_threads = false; + const bool check_inlines = true; + const bool exact = false; + + SymbolContextList sc_list; + const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, + line, + check_inlines, + exact, + eSymbolContextLineEntry, + sc_list); + if (num_matches > 0) + { + SymbolContext sc; + for (uint32_t i=0; i<num_matches; ++i) + { + if (sc_list.GetContextAtIndex(i, sc)) + { + addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); + if (step_addr != LLDB_INVALID_ADDRESS) + { + if (fun_range.ContainsLoadAddress(step_addr, target)) + step_over_until_addrs.push_back(step_addr); + else + all_in_function = false; + } + } + } + } + + if (step_over_until_addrs.empty()) + { + if (all_in_function) + { + step_file_spec.GetPath (path, sizeof(path)); + sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); + } + else + sb_error.SetErrorString ("step until target not in current function"); + } + else + { + ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans, + &step_over_until_addrs[0], + step_over_until_addrs.size(), + stop_other_threads, + frame_sp->GetFrameIndex())); + + sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); + } + } + else + { + sb_error.SetErrorString("this SBThread object is invalid"); + } + return sb_error; +} + +SBError +SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) +{ + SBError sb_error; + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + + if (log) + log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID()); + + if (exe_ctx.HasThreadScope()) + { + Thread *thread = exe_ctx.GetThreadPtr(); + sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); + } + + return sb_error; +} + + +bool +SBThread::Suspend() +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ExecutionContext exe_ctx (m_opaque_sp.get()); + bool result = false; + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); + result = true; + } + else + { + if (log) + log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + if (log) + log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result); + return result; +} + +bool +SBThread::Resume () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ExecutionContext exe_ctx (m_opaque_sp.get()); + bool result = false; + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning); + result = true; + } + else + { + if (log) + log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + if (log) + log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result); + return result; +} + +bool +SBThread::IsSuspended() +{ + ExecutionContext exe_ctx (m_opaque_sp.get()); + if (exe_ctx.HasThreadScope()) + return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; + return false; +} + +bool +SBThread::IsStopped() +{ + ExecutionContext exe_ctx (m_opaque_sp.get()); + if (exe_ctx.HasThreadScope()) + return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); + return false; +} + +SBProcess +SBThread::GetProcess () +{ + SBProcess sb_process; + ExecutionContext exe_ctx (m_opaque_sp.get()); + if (exe_ctx.HasThreadScope()) + { + // Have to go up to the target so we can get a shared pointer to our process... + sb_process.SetSP (exe_ctx.GetProcessSP()); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + SBStream frame_desc_strm; + sb_process.GetDescription (frame_desc_strm); + log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(), + sb_process.GetSP().get(), frame_desc_strm.GetData()); + } + + return sb_process; +} + +uint32_t +SBThread::GetNumFrames () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num_frames = 0; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames); + + return num_frames; +} + +SBFrame +SBThread::GetFrameAtIndex (uint32_t idx) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBFrame sb_frame; + StackFrameSP frame_sp; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); + sb_frame.SetFrameSP (frame_sp); + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + + if (log) + { + SBStream frame_desc_strm; + sb_frame.GetDescription (frame_desc_strm); + log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", + exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); + } + + return sb_frame; +} + +lldb::SBFrame +SBThread::GetSelectedFrame () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBFrame sb_frame; + StackFrameSP frame_sp; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); + sb_frame.SetFrameSP (frame_sp); + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + + if (log) + { + SBStream frame_desc_strm; + sb_frame.GetDescription (frame_desc_strm); + log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", + exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); + } + + return sb_frame; +} + +lldb::SBFrame +SBThread::SetSelectedFrame (uint32_t idx) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBFrame sb_frame; + StackFrameSP frame_sp; + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + Thread *thread = exe_ctx.GetThreadPtr(); + frame_sp = thread->GetStackFrameAtIndex (idx); + if (frame_sp) + { + thread->SetSelectedFrame (frame_sp.get()); + sb_frame.SetFrameSP (frame_sp); + } + } + else + { + if (log) + log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); + } + } + + if (log) + { + SBStream frame_desc_strm; + sb_frame.GetDescription (frame_desc_strm); + log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", + exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); + } + return sb_frame; +} + +bool +SBThread::EventIsThreadEvent (const SBEvent &event) +{ + return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; +} + +SBFrame +SBThread::GetStackFrameFromEvent (const SBEvent &event) +{ + return Thread::ThreadEventData::GetStackFrameFromEvent (event.get()); + +} + +SBThread +SBThread::GetThreadFromEvent (const SBEvent &event) +{ + return Thread::ThreadEventData::GetThreadFromEvent (event.get()); +} + +bool +SBThread::operator == (const SBThread &rhs) const +{ + return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); +} + +bool +SBThread::operator != (const SBThread &rhs) const +{ + return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); +} + +bool +SBThread::GetStatus (SBStream &status) const +{ + Stream &strm = status.ref(); + + ExecutionContext exe_ctx (m_opaque_sp.get()); + if (exe_ctx.HasThreadScope()) + { + exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); + } + else + strm.PutCString ("No status"); + + return true; +} + +bool +SBThread::GetDescription (SBStream &description) const +{ + Stream &strm = description.ref(); + + ExecutionContext exe_ctx (m_opaque_sp.get()); + if (exe_ctx.HasThreadScope()) + { + strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID()); + } + else + strm.PutCString ("No value"); + + return true; +} diff --git a/contrib/llvm/tools/lldb/source/API/SBType.cpp b/contrib/llvm/tools/lldb/source/API/SBType.cpp new file mode 100644 index 0000000..372d073 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBType.cpp @@ -0,0 +1,648 @@ +//===-- SBType.cpp ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <string.h> + +#include "clang/AST/ASTContext.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/Type.h" + +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBType.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/Type.h" + +using namespace lldb; +using namespace lldb_private; +using namespace clang; + +SBType::SBType() : + m_opaque_sp() +{ +} + +SBType::SBType (const ClangASTType &type) : + m_opaque_sp(new TypeImpl(ClangASTType(type.GetASTContext(), + type.GetOpaqueQualType()))) +{ +} + +SBType::SBType (const lldb::TypeSP &type_sp) : + m_opaque_sp(new TypeImpl(type_sp)) +{ +} + +SBType::SBType (const lldb::TypeImplSP &type_impl_sp) : + m_opaque_sp(type_impl_sp) +{ +} + + +SBType::SBType (const SBType &rhs) : + m_opaque_sp() +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } +} + + +//SBType::SBType (TypeImpl* impl) : +// m_opaque_ap(impl) +//{} +// +bool +SBType::operator == (SBType &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + + return (rhs.m_opaque_sp->GetASTContext() == m_opaque_sp->GetASTContext()) && + (rhs.m_opaque_sp->GetOpaqueQualType() == m_opaque_sp->GetOpaqueQualType()); +} + +bool +SBType::operator != (SBType &rhs) +{ + if (IsValid() == false) + return rhs.IsValid(); + + return (rhs.m_opaque_sp->GetASTContext() != m_opaque_sp->GetASTContext()) || + (rhs.m_opaque_sp->GetOpaqueQualType() != m_opaque_sp->GetOpaqueQualType()); +} + +lldb::TypeImplSP +SBType::GetSP () +{ + return m_opaque_sp; +} + + +void +SBType::SetSP (const lldb::TypeImplSP &type_impl_sp) +{ + m_opaque_sp = type_impl_sp; +} + +SBType & +SBType::operator = (const SBType &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } + return *this; +} + +SBType::~SBType () +{} + +TypeImpl & +SBType::ref () +{ + if (m_opaque_sp.get() == NULL) + m_opaque_sp.reset (new TypeImpl()); + return *m_opaque_sp; +} + +const TypeImpl & +SBType::ref () const +{ + // "const SBAddress &addr" should already have checked "addr.IsValid()" + // prior to calling this function. In case you didn't we will assert + // and die to let you know. + assert (m_opaque_sp.get()); + return *m_opaque_sp; +} + +bool +SBType::IsValid() const +{ + if (m_opaque_sp.get() == NULL) + return false; + + return m_opaque_sp->IsValid(); +} + +uint64_t +SBType::GetByteSize() +{ + if (!IsValid()) + return 0; + + return m_opaque_sp->GetClangASTType().GetByteSize(); + +} + +bool +SBType::IsPointerType() +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType().IsPointerType(); +} + +bool +SBType::IsReferenceType() +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType().IsReferenceType(); +} + +SBType +SBType::GetPointerType() +{ + if (!IsValid()) + return SBType(); + + return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointerType())); +} + +SBType +SBType::GetPointeeType() +{ + if (!IsValid()) + return SBType(); + return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetPointeeType())); +} + +SBType +SBType::GetReferenceType() +{ + if (!IsValid()) + return SBType(); + return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetLValueReferenceType())); +} + +SBType +SBType::GetDereferencedType() +{ + if (!IsValid()) + return SBType(); + return SBType(ClangASTType(m_opaque_sp->GetClangASTType().GetNonReferenceType())); +} + +bool +SBType::IsFunctionType () +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType().IsFunctionType(); +} + +bool +SBType::IsPolymorphicClass () +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType().IsPolymorphicClass(); +} + + + +lldb::SBType +SBType::GetFunctionReturnType () +{ + if (IsValid()) + { + ClangASTType return_clang_type (m_opaque_sp->GetClangASTType().GetFunctionReturnType()); + if (return_clang_type.IsValid()) + return SBType(return_clang_type); + } + return lldb::SBType(); +} + +lldb::SBTypeList +SBType::GetFunctionArgumentTypes () +{ + SBTypeList sb_type_list; + if (IsValid()) + { + QualType qual_type(QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType())); + const FunctionProtoType* func = dyn_cast<FunctionProtoType>(qual_type.getTypePtr()); + if (func) + { + const uint32_t num_args = func->getNumArgs(); + for (uint32_t i=0; i<num_args; ++i) + sb_type_list.Append (SBType(ClangASTType(m_opaque_sp->GetASTContext(), func->getArgType(i).getAsOpaquePtr()))); + } + } + return sb_type_list; +} + +lldb::SBType +SBType::GetUnqualifiedType() +{ + if (!IsValid()) + return SBType(); + return SBType(m_opaque_sp->GetClangASTType().GetFullyUnqualifiedType()); +} + +lldb::SBType +SBType::GetCanonicalType() +{ + if (IsValid()) + return SBType(m_opaque_sp->GetClangASTType().GetCanonicalType()); + return SBType(); +} + + +lldb::BasicType +SBType::GetBasicType() +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType().GetBasicTypeEnumeration (); + return eBasicTypeInvalid; +} + +SBType +SBType::GetBasicType(lldb::BasicType basic_type) +{ + if (IsValid()) + return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetASTContext(), basic_type)); + return SBType(); +} + +uint32_t +SBType::GetNumberOfDirectBaseClasses () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType().GetNumDirectBaseClasses(); + return 0; +} + +uint32_t +SBType::GetNumberOfVirtualBaseClasses () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType().GetNumVirtualBaseClasses(); + return 0; +} + +uint32_t +SBType::GetNumberOfFields () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType().GetNumFields(); + return 0; +} + +bool +SBType::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) +{ + Stream &strm = description.ref(); + + if (m_opaque_sp) + { + m_opaque_sp->GetDescription (strm, description_level); + } + else + strm.PutCString ("No value"); + + return true; +} + + + +SBTypeMember +SBType::GetDirectBaseClassAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + ClangASTType this_type (m_opaque_sp->GetClangASTType ()); + if (this_type.IsValid()) + { + uint32_t bit_offset = 0; + ClangASTType base_class_type (this_type.GetDirectBaseClassAtIndex(idx, &bit_offset)); + if (base_class_type.IsValid()) + { + sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); + } + } + } + return sb_type_member; + +} + +SBTypeMember +SBType::GetVirtualBaseClassAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + ClangASTType this_type (m_opaque_sp->GetClangASTType ()); + if (this_type.IsValid()) + { + uint32_t bit_offset = 0; + ClangASTType base_class_type (this_type.GetVirtualBaseClassAtIndex(idx, &bit_offset)); + if (base_class_type.IsValid()) + { + sb_type_member.reset (new TypeMemberImpl (TypeImplSP(new TypeImpl(base_class_type)), bit_offset)); + } + } + } + return sb_type_member; +} + +SBTypeMember +SBType::GetFieldAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + ClangASTType this_type (m_opaque_sp->GetClangASTType ()); + if (this_type.IsValid()) + { + uint64_t bit_offset = 0; + uint32_t bitfield_bit_size = 0; + bool is_bitfield = false; + std::string name_sstr; + ClangASTType field_type (this_type.GetFieldAtIndex (idx, + name_sstr, + &bit_offset, + &bitfield_bit_size, + &is_bitfield)); + if (field_type.IsValid()) + { + ConstString name; + if (!name_sstr.empty()) + name.SetCString(name_sstr.c_str()); + sb_type_member.reset (new TypeMemberImpl (TypeImplSP (new TypeImpl(field_type)), + bit_offset, + name, + bitfield_bit_size, + is_bitfield)); + } + } + } + return sb_type_member; +} + +bool +SBType::IsTypeComplete() +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType().IsCompleteType(); +} + +const char* +SBType::GetName() +{ + if (!IsValid()) + return ""; + return m_opaque_sp->GetClangASTType().GetConstTypeName().GetCString(); +} + +lldb::TypeClass +SBType::GetTypeClass () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType().GetTypeClass(); + return lldb::eTypeClassInvalid; +} + +uint32_t +SBType::GetNumberOfTemplateArguments () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType().GetNumTemplateArguments(); + return 0; +} + +lldb::SBType +SBType::GetTemplateArgumentType (uint32_t idx) +{ + if (IsValid()) + { + TemplateArgumentKind kind = eTemplateArgumentKindNull; + ClangASTType template_arg_type = m_opaque_sp->GetClangASTType().GetTemplateArgument (idx, kind); + if (template_arg_type.IsValid()) + return SBType(template_arg_type); + } + return SBType(); +} + + +lldb::TemplateArgumentKind +SBType::GetTemplateArgumentKind (uint32_t idx) +{ + TemplateArgumentKind kind = eTemplateArgumentKindNull; + if (IsValid()) + m_opaque_sp->GetClangASTType().GetTemplateArgument (idx, kind); + return kind; +} + + +SBTypeList::SBTypeList() : + m_opaque_ap(new TypeListImpl()) +{ +} + +SBTypeList::SBTypeList(const SBTypeList& rhs) : + m_opaque_ap(new TypeListImpl()) +{ + for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); +} + +bool +SBTypeList::IsValid () +{ + return (m_opaque_ap.get() != NULL); +} + +SBTypeList& +SBTypeList::operator = (const SBTypeList& rhs) +{ + if (this != &rhs) + { + m_opaque_ap.reset (new TypeListImpl()); + for (uint32_t i = 0, rhs_size = const_cast<SBTypeList&>(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast<SBTypeList&>(rhs).GetTypeAtIndex(i)); + } + return *this; +} + +void +SBTypeList::Append (SBType type) +{ + if (type.IsValid()) + m_opaque_ap->Append (type.m_opaque_sp); +} + +SBType +SBTypeList::GetTypeAtIndex(uint32_t index) +{ + if (m_opaque_ap.get()) + return SBType(m_opaque_ap->GetTypeAtIndex(index)); + return SBType(); +} + +uint32_t +SBTypeList::GetSize() +{ + return m_opaque_ap->GetSize(); +} + +SBTypeList::~SBTypeList() +{ +} + +SBTypeMember::SBTypeMember() : + m_opaque_ap() +{ +} + +SBTypeMember::~SBTypeMember() +{ +} + +SBTypeMember::SBTypeMember (const SBTypeMember& rhs) : + m_opaque_ap() +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); + } +} + +lldb::SBTypeMember& +SBTypeMember::operator = (const lldb::SBTypeMember& rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_ap.reset(new TypeMemberImpl(rhs.ref())); + } + return *this; +} + +bool +SBTypeMember::IsValid() const +{ + return m_opaque_ap.get(); +} + +const char * +SBTypeMember::GetName () +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetName().GetCString(); + return NULL; +} + +SBType +SBTypeMember::GetType () +{ + SBType sb_type; + if (m_opaque_ap.get()) + { + sb_type.SetSP (m_opaque_ap->GetTypeImpl()); + } + return sb_type; + +} + +uint64_t +SBTypeMember::GetOffsetInBytes() +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetBitOffset() / 8u; + return 0; +} + +uint64_t +SBTypeMember::GetOffsetInBits() +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetBitOffset(); + return 0; +} + +bool +SBTypeMember::IsBitfield() +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetIsBitfield(); + return false; +} + +uint32_t +SBTypeMember::GetBitfieldSizeInBits() +{ + if (m_opaque_ap.get()) + return m_opaque_ap->GetBitfieldBitSize(); + return 0; +} + + +bool +SBTypeMember::GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level) +{ + Stream &strm = description.ref(); + + if (m_opaque_ap.get()) + { + const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); + const uint32_t byte_offset = bit_offset / 8u; + const uint32_t byte_bit_offset = bit_offset % 8u; + const char *name = m_opaque_ap->GetName().GetCString(); + if (byte_bit_offset) + strm.Printf ("+%u + %u bits: (", byte_offset, byte_bit_offset); + else + strm.Printf ("+%u: (", byte_offset); + + TypeImplSP type_impl_sp (m_opaque_ap->GetTypeImpl()); + if (type_impl_sp) + type_impl_sp->GetDescription(strm, description_level); + + strm.Printf (") %s", name); + if (m_opaque_ap->GetIsBitfield()) + { + const uint32_t bitfield_bit_size = m_opaque_ap->GetBitfieldBitSize(); + strm.Printf (" : %u", bitfield_bit_size); + } + } + else + { + strm.PutCString ("No value"); + } + return true; +} + + +void +SBTypeMember::reset(TypeMemberImpl *type_member_impl) +{ + m_opaque_ap.reset(type_member_impl); +} + +TypeMemberImpl & +SBTypeMember::ref () +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new TypeMemberImpl()); + return *m_opaque_ap.get(); +} + +const TypeMemberImpl & +SBTypeMember::ref () const +{ + return *m_opaque_ap.get(); +} diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeCategory.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeCategory.cpp new file mode 100644 index 0000000..e397869 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeCategory.cpp @@ -0,0 +1,576 @@ +//===-- SBTypeCategory.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/SBTypeCategory.h" + +#include "lldb/API/SBTypeFilter.h" +#include "lldb/API/SBTypeFormat.h" +#include "lldb/API/SBTypeSummary.h" +#include "lldb/API/SBTypeSynthetic.h" +#include "lldb/API/SBTypeNameSpecifier.h" +#include "lldb/API/SBStream.h" + +#include "lldb/Core/Debugger.h" +#include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/ScriptInterpreter.h" + +using namespace lldb; +using namespace lldb_private; + +typedef std::pair<lldb::TypeCategoryImplSP,user_id_t> ImplType; + +SBTypeCategory::SBTypeCategory() : +m_opaque_sp() +{ +} + +SBTypeCategory::SBTypeCategory (const char* name) : +m_opaque_sp() +{ + DataVisualization::Categories::GetCategory(ConstString(name), m_opaque_sp); +} + +SBTypeCategory::SBTypeCategory (const lldb::SBTypeCategory &rhs) : +m_opaque_sp(rhs.m_opaque_sp) +{ +} + +SBTypeCategory::~SBTypeCategory () +{ +} + +bool +SBTypeCategory::IsValid() const +{ + return (m_opaque_sp.get() != NULL); +} + +bool +SBTypeCategory::GetEnabled () +{ + if (!IsValid()) + return false; + return m_opaque_sp->IsEnabled(); +} + +void +SBTypeCategory::SetEnabled (bool enabled) +{ + if (!IsValid()) + return; + if (enabled) + DataVisualization::Categories::Enable(m_opaque_sp); + else + DataVisualization::Categories::Disable(m_opaque_sp); +} + +const char* +SBTypeCategory::GetName() +{ + if (!IsValid()) + return NULL; + return m_opaque_sp->GetName(); +} + +uint32_t +SBTypeCategory::GetNumFormats () +{ + if (!IsDefaultCategory()) + return 0; + + return DataVisualization::ValueFormats::GetCount(); +} + +uint32_t +SBTypeCategory::GetNumSummaries () +{ + if (!IsValid()) + return 0; + return m_opaque_sp->GetSummaryNavigator()->GetCount() + m_opaque_sp->GetRegexSummaryNavigator()->GetCount(); +} + +uint32_t +SBTypeCategory::GetNumFilters () +{ + if (!IsValid()) + return 0; + return m_opaque_sp->GetFilterNavigator()->GetCount() + m_opaque_sp->GetRegexFilterNavigator()->GetCount(); +} + +#ifndef LLDB_DISABLE_PYTHON +uint32_t +SBTypeCategory::GetNumSynthetics () +{ + if (!IsValid()) + return 0; + return m_opaque_sp->GetSyntheticNavigator()->GetCount() + m_opaque_sp->GetRegexSyntheticNavigator()->GetCount(); +} +#endif + +lldb::SBTypeNameSpecifier +SBTypeCategory::GetTypeNameSpecifierForFilterAtIndex (uint32_t index) +{ + if (!IsValid()) + return SBTypeNameSpecifier(); + return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForFilterAtIndex(index)); +} + +lldb::SBTypeNameSpecifier +SBTypeCategory::GetTypeNameSpecifierForFormatAtIndex (uint32_t index) +{ + if (!IsDefaultCategory()) + return SBTypeNameSpecifier(); + return SBTypeNameSpecifier(DataVisualization::ValueFormats::GetTypeNameSpecifierForFormatAtIndex(index)); +} + +lldb::SBTypeNameSpecifier +SBTypeCategory::GetTypeNameSpecifierForSummaryAtIndex (uint32_t index) +{ + if (!IsValid()) + return SBTypeNameSpecifier(); + return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForSummaryAtIndex(index)); +} + +#ifndef LLDB_DISABLE_PYTHON +lldb::SBTypeNameSpecifier +SBTypeCategory::GetTypeNameSpecifierForSyntheticAtIndex (uint32_t index) +{ + if (!IsValid()) + return SBTypeNameSpecifier(); + return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForSyntheticAtIndex(index)); +} +#endif + +SBTypeFilter +SBTypeCategory::GetFilterForType (SBTypeNameSpecifier spec) +{ + if (!IsValid()) + return SBTypeFilter(); + + if (!spec.IsValid()) + return SBTypeFilter(); + + lldb::SyntheticChildrenSP children_sp; + + if (spec.IsRegex()) + m_opaque_sp->GetRegexFilterNavigator()->GetExact(ConstString(spec.GetName()), children_sp); + else + m_opaque_sp->GetFilterNavigator()->GetExact(ConstString(spec.GetName()), children_sp); + + if (!children_sp) + return lldb::SBTypeFilter(); + + TypeFilterImplSP filter_sp = std::static_pointer_cast<TypeFilterImpl>(children_sp); + + return lldb::SBTypeFilter(filter_sp); + +} +SBTypeFormat +SBTypeCategory::GetFormatForType (SBTypeNameSpecifier spec) +{ + if (!IsDefaultCategory()) + return SBTypeFormat(); + + if (!spec.IsValid()) + return SBTypeFormat(); + + if (spec.IsRegex()) + return SBTypeFormat(); + + return SBTypeFormat(DataVisualization::ValueFormats::GetFormat(ConstString(spec.GetName()))); +} + +#ifndef LLDB_DISABLE_PYTHON +SBTypeSummary +SBTypeCategory::GetSummaryForType (SBTypeNameSpecifier spec) +{ + if (!IsValid()) + return SBTypeSummary(); + + if (!spec.IsValid()) + return SBTypeSummary(); + + lldb::TypeSummaryImplSP summary_sp; + + if (spec.IsRegex()) + m_opaque_sp->GetRegexSummaryNavigator()->GetExact(ConstString(spec.GetName()), summary_sp); + else + m_opaque_sp->GetSummaryNavigator()->GetExact(ConstString(spec.GetName()), summary_sp); + + if (!summary_sp) + return lldb::SBTypeSummary(); + + return lldb::SBTypeSummary(summary_sp); +} +#endif // LLDB_DISABLE_PYTHON + +#ifndef LLDB_DISABLE_PYTHON +SBTypeSynthetic +SBTypeCategory::GetSyntheticForType (SBTypeNameSpecifier spec) +{ + if (!IsValid()) + return SBTypeSynthetic(); + + if (!spec.IsValid()) + return SBTypeSynthetic(); + + lldb::SyntheticChildrenSP children_sp; + + if (spec.IsRegex()) + m_opaque_sp->GetRegexSyntheticNavigator()->GetExact(ConstString(spec.GetName()), children_sp); + else + m_opaque_sp->GetSyntheticNavigator()->GetExact(ConstString(spec.GetName()), children_sp); + + if (!children_sp) + return lldb::SBTypeSynthetic(); + + ScriptedSyntheticChildrenSP synth_sp = std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); + + return lldb::SBTypeSynthetic(synth_sp); +} +#endif + +#ifndef LLDB_DISABLE_PYTHON +SBTypeFilter +SBTypeCategory::GetFilterAtIndex (uint32_t index) +{ + if (!IsValid()) + return SBTypeFilter(); + lldb::SyntheticChildrenSP children_sp = m_opaque_sp->GetSyntheticAtIndex((index)); + + if (!children_sp.get()) + return lldb::SBTypeFilter(); + + TypeFilterImplSP filter_sp = std::static_pointer_cast<TypeFilterImpl>(children_sp); + + return lldb::SBTypeFilter(filter_sp); +} +#endif + +SBTypeFormat +SBTypeCategory::GetFormatAtIndex (uint32_t index) +{ + if (!IsDefaultCategory()) + return SBTypeFormat(); + return SBTypeFormat(DataVisualization::ValueFormats::GetFormatAtIndex((index))); +} + +#ifndef LLDB_DISABLE_PYTHON +SBTypeSummary +SBTypeCategory::GetSummaryAtIndex (uint32_t index) +{ + if (!IsValid()) + return SBTypeSummary(); + return SBTypeSummary(m_opaque_sp->GetSummaryAtIndex((index))); +} +#endif + +#ifndef LLDB_DISABLE_PYTHON +SBTypeSynthetic +SBTypeCategory::GetSyntheticAtIndex (uint32_t index) +{ + if (!IsValid()) + return SBTypeSynthetic(); + lldb::SyntheticChildrenSP children_sp = m_opaque_sp->GetSyntheticAtIndex((index)); + + if (!children_sp.get()) + return lldb::SBTypeSynthetic(); + + ScriptedSyntheticChildrenSP synth_sp = std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); + + return lldb::SBTypeSynthetic(synth_sp); +} +#endif + +bool +SBTypeCategory::AddTypeFormat (SBTypeNameSpecifier type_name, + SBTypeFormat format) +{ + if (!IsDefaultCategory()) + return false; + + if (!type_name.IsValid()) + return false; + + if (!format.IsValid()) + return false; + + if (type_name.IsRegex()) + return false; + + DataVisualization::ValueFormats::Add(ConstString(type_name.GetName()), format.GetSP()); + + return true; +} + +bool +SBTypeCategory::DeleteTypeFormat (SBTypeNameSpecifier type_name) +{ + if (!IsDefaultCategory()) + return false; + + if (!type_name.IsValid()) + return false; + + if (type_name.IsRegex()) + return false; + + return DataVisualization::ValueFormats::Delete(ConstString(type_name.GetName())); +} + +#ifndef LLDB_DISABLE_PYTHON +bool +SBTypeCategory::AddTypeSummary (SBTypeNameSpecifier type_name, + SBTypeSummary summary) +{ + if (!IsValid()) + return false; + + if (!type_name.IsValid()) + return false; + + if (!summary.IsValid()) + return false; + + // FIXME: we need to iterate over all the Debugger objects and have each of them contain a copy of the function + // since we currently have formatters live in a global space, while Python code lives in a specific Debugger-related environment + // this should eventually be fixed by deciding a final location in the LLDB object space for formatters + if (summary.IsFunctionCode()) + { + void *name_token = (void*)ConstString(type_name.GetName()).GetCString(); + const char* script = summary.GetData(); + StringList input; input.SplitIntoLines(script, strlen(script)); + uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers(); + bool need_set = true; + for (uint32_t j = 0; + j < num_debuggers; + j++) + { + DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j); + if (debugger_sp) + { + ScriptInterpreter* interpreter_ptr = debugger_sp->GetCommandInterpreter().GetScriptInterpreter(); + if (interpreter_ptr) + { + std::string output; + if (interpreter_ptr->GenerateTypeScriptFunction(input, output, name_token) && !output.empty()) + { + if (need_set) + { + need_set = false; + summary.SetFunctionName(output.c_str()); + } + } + } + } + } + } + + if (type_name.IsRegex()) + m_opaque_sp->GetRegexSummaryNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), summary.GetSP()); + else + m_opaque_sp->GetSummaryNavigator()->Add(ConstString(type_name.GetName()), summary.GetSP()); + + return true; +} +#endif + +bool +SBTypeCategory::DeleteTypeSummary (SBTypeNameSpecifier type_name) +{ + if (!IsValid()) + return false; + + if (!type_name.IsValid()) + return false; + + if (type_name.IsRegex()) + return m_opaque_sp->GetRegexSummaryNavigator()->Delete(ConstString(type_name.GetName())); + else + return m_opaque_sp->GetSummaryNavigator()->Delete(ConstString(type_name.GetName())); +} + +bool +SBTypeCategory::AddTypeFilter (SBTypeNameSpecifier type_name, + SBTypeFilter filter) +{ + if (!IsValid()) + return false; + + if (!type_name.IsValid()) + return false; + + if (!filter.IsValid()) + return false; + + if (type_name.IsRegex()) + m_opaque_sp->GetRegexFilterNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), filter.GetSP()); + else + m_opaque_sp->GetFilterNavigator()->Add(ConstString(type_name.GetName()), filter.GetSP()); + + return true; +} + +bool +SBTypeCategory::DeleteTypeFilter (SBTypeNameSpecifier type_name) +{ + if (!IsValid()) + return false; + + if (!type_name.IsValid()) + return false; + + if (type_name.IsRegex()) + return m_opaque_sp->GetRegexFilterNavigator()->Delete(ConstString(type_name.GetName())); + else + return m_opaque_sp->GetFilterNavigator()->Delete(ConstString(type_name.GetName())); +} + +#ifndef LLDB_DISABLE_PYTHON +bool +SBTypeCategory::AddTypeSynthetic (SBTypeNameSpecifier type_name, + SBTypeSynthetic synth) +{ + if (!IsValid()) + return false; + + if (!type_name.IsValid()) + return false; + + if (!synth.IsValid()) + return false; + + // FIXME: we need to iterate over all the Debugger objects and have each of them contain a copy of the function + // since we currently have formatters live in a global space, while Python code lives in a specific Debugger-related environment + // this should eventually be fixed by deciding a final location in the LLDB object space for formatters + if (synth.IsClassCode()) + { + void *name_token = (void*)ConstString(type_name.GetName()).GetCString(); + const char* script = synth.GetData(); + StringList input; input.SplitIntoLines(script, strlen(script)); + uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers(); + bool need_set = true; + for (uint32_t j = 0; + j < num_debuggers; + j++) + { + DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j); + if (debugger_sp) + { + ScriptInterpreter* interpreter_ptr = debugger_sp->GetCommandInterpreter().GetScriptInterpreter(); + if (interpreter_ptr) + { + std::string output; + if (interpreter_ptr->GenerateTypeSynthClass(input, output, name_token) && !output.empty()) + { + if (need_set) + { + need_set = false; + synth.SetClassName(output.c_str()); + } + } + } + } + } + } + + if (type_name.IsRegex()) + m_opaque_sp->GetRegexSyntheticNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), synth.GetSP()); + else + m_opaque_sp->GetSyntheticNavigator()->Add(ConstString(type_name.GetName()), synth.GetSP()); + + return true; +} + +bool +SBTypeCategory::DeleteTypeSynthetic (SBTypeNameSpecifier type_name) +{ + if (!IsValid()) + return false; + + if (!type_name.IsValid()) + return false; + + if (type_name.IsRegex()) + return m_opaque_sp->GetRegexSyntheticNavigator()->Delete(ConstString(type_name.GetName())); + else + return m_opaque_sp->GetSyntheticNavigator()->Delete(ConstString(type_name.GetName())); +} +#endif // LLDB_DISABLE_PYTHON + +bool +SBTypeCategory::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + if (!IsValid()) + return false; + description.Printf("Category name: %s\n",GetName()); + return true; +} + +lldb::SBTypeCategory & +SBTypeCategory::operator = (const lldb::SBTypeCategory &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } + return *this; +} + +bool +SBTypeCategory::operator == (lldb::SBTypeCategory &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + + return m_opaque_sp.get() == rhs.m_opaque_sp.get(); + +} + +bool +SBTypeCategory::operator != (lldb::SBTypeCategory &rhs) +{ + if (IsValid() == false) + return rhs.IsValid(); + + return m_opaque_sp.get() != rhs.m_opaque_sp.get(); +} + +lldb::TypeCategoryImplSP +SBTypeCategory::GetSP () +{ + if (!IsValid()) + return lldb::TypeCategoryImplSP(); + return m_opaque_sp; +} + +void +SBTypeCategory::SetSP (const lldb::TypeCategoryImplSP &typecategory_impl_sp) +{ + m_opaque_sp = typecategory_impl_sp; +} + +SBTypeCategory::SBTypeCategory (const lldb::TypeCategoryImplSP &typecategory_impl_sp) : +m_opaque_sp(typecategory_impl_sp) +{ +} + +bool +SBTypeCategory::IsDefaultCategory() +{ + if (!IsValid()) + return false; + + return (strcmp(m_opaque_sp->GetName(),"default") == 0); +} + diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeFilter.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeFilter.cpp new file mode 100644 index 0000000..605e92d --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeFilter.cpp @@ -0,0 +1,199 @@ +//===-- SBTypeFilter.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/SBTypeFilter.h" + +#include "lldb/API/SBStream.h" + +#include "lldb/DataFormatters/DataVisualization.h" + +using namespace lldb; +using namespace lldb_private; + +SBTypeFilter::SBTypeFilter() : +m_opaque_sp() +{ +} + +SBTypeFilter::SBTypeFilter (uint32_t options) +: m_opaque_sp(TypeFilterImplSP(new TypeFilterImpl(options))) +{ +} + +SBTypeFilter::SBTypeFilter (const lldb::SBTypeFilter &rhs) : +m_opaque_sp(rhs.m_opaque_sp) +{ +} + +SBTypeFilter::~SBTypeFilter () +{ +} + +bool +SBTypeFilter::IsValid() const +{ + return m_opaque_sp.get() != NULL; +} + +uint32_t +SBTypeFilter::GetOptions() +{ + if (IsValid()) + return m_opaque_sp->GetOptions(); + return 0; +} + +void +SBTypeFilter::SetOptions (uint32_t value) +{ + if (CopyOnWrite_Impl()) + m_opaque_sp->SetOptions(value); +} + +bool +SBTypeFilter::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + if (!IsValid()) + return false; + else { + description.Printf("%s\n", + m_opaque_sp->GetDescription().c_str()); + return true; + } +} + +void +SBTypeFilter::Clear() +{ + if (CopyOnWrite_Impl()) + m_opaque_sp->Clear(); +} + +uint32_t +SBTypeFilter::GetNumberOfExpressionPaths() +{ + if (IsValid()) + return m_opaque_sp->GetCount(); + return 0; +} + +const char* +SBTypeFilter::GetExpressionPathAtIndex (uint32_t i) +{ + if (IsValid()) + { + const char* item = m_opaque_sp->GetExpressionPathAtIndex(i); + if (item && *item == '.') + item++; + return item; + } + return NULL; +} + +bool +SBTypeFilter::ReplaceExpressionPathAtIndex (uint32_t i, const char* item) +{ + if (CopyOnWrite_Impl()) + return m_opaque_sp->SetExpressionPathAtIndex(i, item); + else + return false; +} + +void +SBTypeFilter::AppendExpressionPath (const char* item) +{ + if (CopyOnWrite_Impl()) + m_opaque_sp->AddExpressionPath(item); +} + +lldb::SBTypeFilter & +SBTypeFilter::operator = (const lldb::SBTypeFilter &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } + return *this; +} + +bool +SBTypeFilter::operator == (lldb::SBTypeFilter &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + + return m_opaque_sp == rhs.m_opaque_sp; +} + +bool +SBTypeFilter::IsEqualTo (lldb::SBTypeFilter &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + + if (GetNumberOfExpressionPaths() != rhs.GetNumberOfExpressionPaths()) + return false; + + for (uint32_t j = 0; + j < GetNumberOfExpressionPaths(); + j++) + if ( strcmp(GetExpressionPathAtIndex(j),rhs.GetExpressionPathAtIndex(j)) != 0) + return false; + + return GetOptions() == rhs.GetOptions(); +} + +bool +SBTypeFilter::operator != (lldb::SBTypeFilter &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + + return m_opaque_sp != rhs.m_opaque_sp; +} + +lldb::TypeFilterImplSP +SBTypeFilter::GetSP () +{ + return m_opaque_sp; +} + +void +SBTypeFilter::SetSP (const lldb::TypeFilterImplSP &typefilter_impl_sp) +{ + m_opaque_sp = typefilter_impl_sp; +} + +SBTypeFilter::SBTypeFilter (const lldb::TypeFilterImplSP &typefilter_impl_sp) : +m_opaque_sp(typefilter_impl_sp) +{ +} + +bool +SBTypeFilter::CopyOnWrite_Impl() +{ + if (!IsValid()) + return false; + if (m_opaque_sp.unique()) + return true; + + TypeFilterImplSP new_sp(new TypeFilterImpl(GetOptions())); + + for (uint32_t j = 0; + j < GetNumberOfExpressionPaths(); + j++) + new_sp->AddExpressionPath(GetExpressionPathAtIndex(j)); + + SetSP(new_sp); + + return true; +} diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeFormat.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeFormat.cpp new file mode 100644 index 0000000..34ab404 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeFormat.cpp @@ -0,0 +1,155 @@ +//===-- SBTypeFormat.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/SBTypeFormat.h" + +#include "lldb/API/SBStream.h" + +#include "lldb/DataFormatters/DataVisualization.h" + +using namespace lldb; +using namespace lldb_private; + +SBTypeFormat::SBTypeFormat() : +m_opaque_sp() +{ +} + +SBTypeFormat::SBTypeFormat (lldb::Format format, + uint32_t options) +: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl(format,options))) +{ +} + +SBTypeFormat::SBTypeFormat (const lldb::SBTypeFormat &rhs) : +m_opaque_sp(rhs.m_opaque_sp) +{ +} + +SBTypeFormat::~SBTypeFormat () +{ +} + +bool +SBTypeFormat::IsValid() const +{ + return m_opaque_sp.get() != NULL; +} + +lldb::Format +SBTypeFormat::GetFormat () +{ + if (IsValid()) + return m_opaque_sp->GetFormat(); + return lldb::eFormatInvalid; +} + +uint32_t +SBTypeFormat::GetOptions() +{ + if (IsValid()) + return m_opaque_sp->GetOptions(); + return 0; +} + +void +SBTypeFormat::SetFormat (lldb::Format fmt) +{ + if (CopyOnWrite_Impl()) + m_opaque_sp->SetFormat(fmt); +} + +void +SBTypeFormat::SetOptions (uint32_t value) +{ + if (CopyOnWrite_Impl()) + m_opaque_sp->SetOptions(value); +} + +bool +SBTypeFormat::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + if (!IsValid()) + return false; + else { + description.Printf("%s\n", + m_opaque_sp->GetDescription().c_str()); + return true; + } +} + +lldb::SBTypeFormat & +SBTypeFormat::operator = (const lldb::SBTypeFormat &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } + return *this; +} + +bool +SBTypeFormat::operator == (lldb::SBTypeFormat &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + return m_opaque_sp == rhs.m_opaque_sp; +} + +bool +SBTypeFormat::IsEqualTo (lldb::SBTypeFormat &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + + if (GetFormat() == rhs.GetFormat()) + return GetOptions() == rhs.GetOptions(); + else + return false; +} + +bool +SBTypeFormat::operator != (lldb::SBTypeFormat &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + return m_opaque_sp != rhs.m_opaque_sp; +} + +lldb::TypeFormatImplSP +SBTypeFormat::GetSP () +{ + return m_opaque_sp; +} + +void +SBTypeFormat::SetSP (const lldb::TypeFormatImplSP &typeformat_impl_sp) +{ + m_opaque_sp = typeformat_impl_sp; +} + +SBTypeFormat::SBTypeFormat (const lldb::TypeFormatImplSP &typeformat_impl_sp) : + m_opaque_sp(typeformat_impl_sp) +{ +} + +bool +SBTypeFormat::CopyOnWrite_Impl() +{ + if (!IsValid()) + return false; + if (m_opaque_sp.unique()) + return true; + + SetSP(TypeFormatImplSP(new TypeFormatImpl(GetFormat(),GetOptions()))); + return true; +} diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeNameSpecifier.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeNameSpecifier.cpp new file mode 100644 index 0000000..d417499 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeNameSpecifier.cpp @@ -0,0 +1,150 @@ +//===-- SBTypeNameSpecifier.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/SBTypeNameSpecifier.h" + +#include "lldb/API/SBStream.h" +#include "lldb/API/SBType.h" + +#include "lldb/DataFormatters/DataVisualization.h" + +using namespace lldb; +using namespace lldb_private; + +SBTypeNameSpecifier::SBTypeNameSpecifier() : +m_opaque_sp() +{ +} + +SBTypeNameSpecifier::SBTypeNameSpecifier (const char* name, + bool is_regex) : +m_opaque_sp(new TypeNameSpecifierImpl(name, is_regex)) +{ + if (name == NULL || (*name) == 0) + m_opaque_sp.reset(); +} + +SBTypeNameSpecifier::SBTypeNameSpecifier (SBType type) : +m_opaque_sp() +{ + if (type.IsValid()) + m_opaque_sp = TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(type.m_opaque_sp->GetClangASTType())); +} + +SBTypeNameSpecifier::SBTypeNameSpecifier (const lldb::SBTypeNameSpecifier &rhs) : +m_opaque_sp(rhs.m_opaque_sp) +{} + +SBTypeNameSpecifier::~SBTypeNameSpecifier () +{ +} + +bool +SBTypeNameSpecifier::IsValid() const +{ + return m_opaque_sp.get() != NULL; +} + +const char* +SBTypeNameSpecifier::GetName () +{ + if (!IsValid()) + return NULL; + + return m_opaque_sp->GetName(); +} + +SBType +SBTypeNameSpecifier::GetType () +{ + if (!IsValid()) + return SBType(); + lldb_private::ClangASTType c_type = m_opaque_sp->GetClangASTType(); + if (c_type.IsValid()) + return SBType(c_type); + return SBType(); +} + +bool +SBTypeNameSpecifier::IsRegex () +{ + if (!IsValid()) + return false; + + return m_opaque_sp->IsRegex(); +} + +bool +SBTypeNameSpecifier::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + if (!IsValid()) + return false; + description.Printf("SBTypeNameSpecifier(%s,%s)", GetName(), IsRegex() ? "regex" : "plain"); + return true; +} + +lldb::SBTypeNameSpecifier & +SBTypeNameSpecifier::operator = (const lldb::SBTypeNameSpecifier &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } + return *this; +} + +bool +SBTypeNameSpecifier::operator == (lldb::SBTypeNameSpecifier &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + return m_opaque_sp == rhs.m_opaque_sp; +} + +bool +SBTypeNameSpecifier::IsEqualTo (lldb::SBTypeNameSpecifier &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + + if (IsRegex() != rhs.IsRegex()) + return false; + if (GetName() == NULL || rhs.GetName() == NULL) + return false; + + return (strcmp(GetName(), rhs.GetName()) == 0); +} + +bool +SBTypeNameSpecifier::operator != (lldb::SBTypeNameSpecifier &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + return m_opaque_sp != rhs.m_opaque_sp; +} + +lldb::TypeNameSpecifierImplSP +SBTypeNameSpecifier::GetSP () +{ + return m_opaque_sp; +} + +void +SBTypeNameSpecifier::SetSP (const lldb::TypeNameSpecifierImplSP &type_namespec_sp) +{ + m_opaque_sp = type_namespec_sp; +} + +SBTypeNameSpecifier::SBTypeNameSpecifier (const lldb::TypeNameSpecifierImplSP &type_namespec_sp) : +m_opaque_sp(type_namespec_sp) +{ +} diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeSummary.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeSummary.cpp new file mode 100644 index 0000000..aaa09c2 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeSummary.cpp @@ -0,0 +1,335 @@ +//===-- SBTypeSummary.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/SBTypeSummary.h" + +#include "lldb/API/SBStream.h" + +#include "lldb/DataFormatters/DataVisualization.h" + +using namespace lldb; +using namespace lldb_private; + +#ifndef LLDB_DISABLE_PYTHON + +SBTypeSummary::SBTypeSummary() : +m_opaque_sp() +{ +} + +SBTypeSummary +SBTypeSummary::CreateWithSummaryString (const char* data, uint32_t options) +{ + if (!data || data[0] == 0) + return SBTypeSummary(); + + return SBTypeSummary(TypeSummaryImplSP(new StringSummaryFormat(options, data))); +} + +SBTypeSummary +SBTypeSummary::CreateWithFunctionName (const char* data, uint32_t options) +{ + if (!data || data[0] == 0) + return SBTypeSummary(); + + return SBTypeSummary(TypeSummaryImplSP(new ScriptSummaryFormat(options, data))); +} + +SBTypeSummary +SBTypeSummary::CreateWithScriptCode (const char* data, uint32_t options) +{ + if (!data || data[0] == 0) + return SBTypeSummary(); + + return SBTypeSummary(TypeSummaryImplSP(new ScriptSummaryFormat(options, "", data))); +} + +SBTypeSummary::SBTypeSummary (const lldb::SBTypeSummary &rhs) : +m_opaque_sp(rhs.m_opaque_sp) +{ +} + +SBTypeSummary::~SBTypeSummary () +{ +} + +bool +SBTypeSummary::IsValid() const +{ + return m_opaque_sp.get() != NULL; +} + +bool +SBTypeSummary::IsFunctionCode() +{ + if (!IsValid()) + return false; + if (m_opaque_sp->IsScripted()) + { + ScriptSummaryFormat* script_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get(); + const char* ftext = script_summary_ptr->GetPythonScript(); + return (ftext && *ftext != 0); + } + return false; +} + +bool +SBTypeSummary::IsFunctionName() +{ + if (!IsValid()) + return false; + if (m_opaque_sp->IsScripted()) + { + ScriptSummaryFormat* script_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get(); + const char* ftext = script_summary_ptr->GetPythonScript(); + return (!ftext || *ftext == 0); + } + return false; +} + +bool +SBTypeSummary::IsSummaryString() +{ + if (!IsValid()) + return false; + + if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback) + return false; + + return !m_opaque_sp->IsScripted(); +} + +const char* +SBTypeSummary::GetData () +{ + if (!IsValid()) + return NULL; + if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback) + return NULL; + if (m_opaque_sp->IsScripted()) + { + ScriptSummaryFormat* script_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get(); + const char* fname = script_summary_ptr->GetFunctionName(); + const char* ftext = script_summary_ptr->GetPythonScript(); + if (ftext && *ftext) + return ftext; + return fname; + } + else + { + StringSummaryFormat* string_summary_ptr = (StringSummaryFormat*)m_opaque_sp.get(); + return string_summary_ptr->GetSummaryString(); + } +} + +uint32_t +SBTypeSummary::GetOptions () +{ + if (!IsValid()) + return lldb::eTypeOptionNone; + return m_opaque_sp->GetOptions(); +} + +void +SBTypeSummary::SetOptions (uint32_t value) +{ + if (!CopyOnWrite_Impl()) + return; + m_opaque_sp->SetOptions(value); +} + +void +SBTypeSummary::SetSummaryString (const char* data) +{ + if (!IsValid()) + return; + if (m_opaque_sp->IsScripted() || (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback)) + ChangeSummaryType(false); + ((StringSummaryFormat*)m_opaque_sp.get())->SetSummaryString(data); +} + +void +SBTypeSummary::SetFunctionName (const char* data) +{ + if (!IsValid()) + return; + if (!m_opaque_sp->IsScripted()) + ChangeSummaryType(true); + ((ScriptSummaryFormat*)m_opaque_sp.get())->SetFunctionName(data); +} + +void +SBTypeSummary::SetFunctionCode (const char* data) +{ + if (!IsValid()) + return; + if (!m_opaque_sp->IsScripted()) + ChangeSummaryType(true); + ((ScriptSummaryFormat*)m_opaque_sp.get())->SetPythonScript(data); +} + +bool +SBTypeSummary::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + if (!CopyOnWrite_Impl()) + return false; + else { + description.Printf("%s\n", + m_opaque_sp->GetDescription().c_str()); + return true; + } +} + +lldb::SBTypeSummary & +SBTypeSummary::operator = (const lldb::SBTypeSummary &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } + return *this; +} + +bool +SBTypeSummary::operator == (lldb::SBTypeSummary &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + return m_opaque_sp == rhs.m_opaque_sp; +} + +bool +SBTypeSummary::IsEqualTo (lldb::SBTypeSummary &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + + if (m_opaque_sp->GetType() != rhs.m_opaque_sp->GetType()) + return false; + + if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback) + { + lldb_private::CXXFunctionSummaryFormat *self_cxx = (lldb_private::CXXFunctionSummaryFormat*)m_opaque_sp.get(); + lldb_private::CXXFunctionSummaryFormat *other_cxx = (lldb_private::CXXFunctionSummaryFormat*)rhs.m_opaque_sp.get(); + return (self_cxx->m_impl == other_cxx->m_impl); + } + + if (m_opaque_sp->IsScripted() != rhs.m_opaque_sp->IsScripted()) + return false; + + if (IsFunctionCode() != rhs.IsFunctionCode()) + return false; + + if (IsSummaryString() != rhs.IsSummaryString()) + return false; + + if (IsFunctionName() != rhs.IsFunctionName()) + return false; + + if ( GetData() == NULL || rhs.GetData() == NULL || strcmp(GetData(), rhs.GetData()) ) + return false; + + return GetOptions() == rhs.GetOptions(); + +} + +bool +SBTypeSummary::operator != (lldb::SBTypeSummary &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + return m_opaque_sp != rhs.m_opaque_sp; +} + +lldb::TypeSummaryImplSP +SBTypeSummary::GetSP () +{ + return m_opaque_sp; +} + +void +SBTypeSummary::SetSP (const lldb::TypeSummaryImplSP &typesummary_impl_sp) +{ + m_opaque_sp = typesummary_impl_sp; +} + +SBTypeSummary::SBTypeSummary (const lldb::TypeSummaryImplSP &typesummary_impl_sp) : +m_opaque_sp(typesummary_impl_sp) +{ +} + +bool +SBTypeSummary::CopyOnWrite_Impl() +{ + if (!IsValid()) + return false; + + if (m_opaque_sp.unique()) + return true; + + TypeSummaryImplSP new_sp; + + if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback) + { + CXXFunctionSummaryFormat* current_summary_ptr = (CXXFunctionSummaryFormat*)m_opaque_sp.get(); + new_sp = TypeSummaryImplSP(new CXXFunctionSummaryFormat(GetOptions(), + current_summary_ptr->m_impl, + current_summary_ptr->m_description.c_str())); + } + else if (m_opaque_sp->IsScripted()) + { + ScriptSummaryFormat* current_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get(); + new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), + current_summary_ptr->GetFunctionName(), + current_summary_ptr->GetPythonScript())); + } + else { + StringSummaryFormat* current_summary_ptr = (StringSummaryFormat*)m_opaque_sp.get(); + new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), + current_summary_ptr->GetSummaryString())); + } + + SetSP(new_sp); + + return true; +} + +bool +SBTypeSummary::ChangeSummaryType (bool want_script) +{ + if (!IsValid()) + return false; + + TypeSummaryImplSP new_sp; + + if (want_script == m_opaque_sp->IsScripted()) + { + if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback && !want_script) + new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), "")); + else + return CopyOnWrite_Impl(); + } + + if (!new_sp) + { + if (want_script) + new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), "", "")); + else + new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), "")); + } + + SetSP(new_sp); + + return true; +} + +#endif // LLDB_DISABLE_PYTHON diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeSynthetic.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeSynthetic.cpp new file mode 100644 index 0000000..681ed6c --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeSynthetic.cpp @@ -0,0 +1,209 @@ +//===-- SBTypeSynthetic.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/SBTypeSynthetic.h" + +#include "lldb/API/SBStream.h" + +#include "lldb/DataFormatters/DataVisualization.h" + +using namespace lldb; +using namespace lldb_private; + +#ifndef LLDB_DISABLE_PYTHON + +SBTypeSynthetic::SBTypeSynthetic() : +m_opaque_sp() +{ +} + +SBTypeSynthetic +SBTypeSynthetic::CreateWithClassName (const char* data, uint32_t options) +{ + if (!data || data[0] == 0) + return SBTypeSynthetic(); + return SBTypeSynthetic(ScriptedSyntheticChildrenSP(new ScriptedSyntheticChildren(options, data, ""))); +} + +SBTypeSynthetic +SBTypeSynthetic::CreateWithScriptCode (const char* data, uint32_t options) +{ + if (!data || data[0] == 0) + return SBTypeSynthetic(); + return SBTypeSynthetic(ScriptedSyntheticChildrenSP(new ScriptedSyntheticChildren(options, "", data))); +} + +SBTypeSynthetic::SBTypeSynthetic (const lldb::SBTypeSynthetic &rhs) : +m_opaque_sp(rhs.m_opaque_sp) +{ +} + +SBTypeSynthetic::~SBTypeSynthetic () +{ +} + +bool +SBTypeSynthetic::IsValid() const +{ + return m_opaque_sp.get() != NULL; +} + +bool +SBTypeSynthetic::IsClassCode() +{ + if (!IsValid()) + return false; + const char* code = m_opaque_sp->GetPythonCode(); + return (code && *code); +} + +bool +SBTypeSynthetic::IsClassName() +{ + if (!IsValid()) + return false; + return !IsClassCode(); +} + +const char* +SBTypeSynthetic::GetData () +{ + if (!IsValid()) + return NULL; + if (IsClassCode()) + return m_opaque_sp->GetPythonCode(); + else + return m_opaque_sp->GetPythonClassName(); +} + +void +SBTypeSynthetic::SetClassName (const char* data) +{ + if (IsValid() && data && *data) + m_opaque_sp->SetPythonClassName(data); +} + +void +SBTypeSynthetic::SetClassCode (const char* data) +{ + if (IsValid() && data && *data) + m_opaque_sp->SetPythonCode(data); +} + +uint32_t +SBTypeSynthetic::GetOptions () +{ + if (!IsValid()) + return lldb::eTypeOptionNone; + return m_opaque_sp->GetOptions(); +} + +void +SBTypeSynthetic::SetOptions (uint32_t value) +{ + if (!CopyOnWrite_Impl()) + return; + m_opaque_sp->SetOptions(value); +} + +bool +SBTypeSynthetic::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + if (m_opaque_sp) + { + description.Printf("%s\n", + m_opaque_sp->GetDescription().c_str()); + return true; + } + return false; +} + +lldb::SBTypeSynthetic & +SBTypeSynthetic::operator = (const lldb::SBTypeSynthetic &rhs) +{ + if (this != &rhs) + { + m_opaque_sp = rhs.m_opaque_sp; + } + return *this; +} + +bool +SBTypeSynthetic::operator == (lldb::SBTypeSynthetic &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + return m_opaque_sp == rhs.m_opaque_sp; +} + +bool +SBTypeSynthetic::IsEqualTo (lldb::SBTypeSynthetic &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + + if (m_opaque_sp->IsScripted() != rhs.m_opaque_sp->IsScripted()) + return false; + + if (IsClassCode() != rhs.IsClassCode()) + return false; + + if ( strcmp(GetData(), rhs.GetData()) ) + return false; + + return GetOptions() == rhs.GetOptions(); + +} + +bool +SBTypeSynthetic::operator != (lldb::SBTypeSynthetic &rhs) +{ + if (IsValid() == false) + return !rhs.IsValid(); + return m_opaque_sp != rhs.m_opaque_sp; +} + +lldb::ScriptedSyntheticChildrenSP +SBTypeSynthetic::GetSP () +{ + return m_opaque_sp; +} + +void +SBTypeSynthetic::SetSP (const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp) +{ + m_opaque_sp = TypeSynthetic_impl_sp; +} + +SBTypeSynthetic::SBTypeSynthetic (const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp) : +m_opaque_sp(TypeSynthetic_impl_sp) +{ +} + +bool +SBTypeSynthetic::CopyOnWrite_Impl() +{ + if (!IsValid()) + return false; + if (m_opaque_sp.unique()) + return true; + + ScriptedSyntheticChildrenSP new_sp(new ScriptedSyntheticChildren(m_opaque_sp->GetOptions(), + m_opaque_sp->GetPythonClassName(), + m_opaque_sp->GetPythonCode())); + + SetSP(new_sp); + + return true; +} + +#endif // LLDB_DISABLE_PYTHON diff --git a/contrib/llvm/tools/lldb/source/API/SBValue.cpp b/contrib/llvm/tools/lldb/source/API/SBValue.cpp new file mode 100644 index 0000000..aa9b23a --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBValue.cpp @@ -0,0 +1,1719 @@ +//===-- SBValue.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/SBValue.h" + +#include "lldb/API/SBDeclaration.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBTypeFilter.h" +#include "lldb/API/SBTypeFormat.h" +#include "lldb/API/SBTypeSummary.h" +#include "lldb/API/SBTypeSynthetic.h" + +#include "lldb/Breakpoint/Watchpoint.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Declaration.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" + +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBExpressionOptions.h" +#include "lldb/API/SBFrame.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBThread.h" + +using namespace lldb; +using namespace lldb_private; + +class ValueImpl +{ +public: + ValueImpl () + { + } + + ValueImpl (lldb::ValueObjectSP in_valobj_sp, + lldb::DynamicValueType use_dynamic, + bool use_synthetic, + const char *name = NULL) : + m_valobj_sp(in_valobj_sp), + m_use_dynamic(use_dynamic), + m_use_synthetic(use_synthetic), + m_name (name) + { + if (!m_name.IsEmpty() && m_valobj_sp) + m_valobj_sp->SetName(m_name); + } + + ValueImpl (const ValueImpl& rhs) : + m_valobj_sp(rhs.m_valobj_sp), + m_use_dynamic(rhs.m_use_dynamic), + m_use_synthetic(rhs.m_use_synthetic), + m_name (rhs.m_name) + { + } + + ValueImpl & + operator = (const ValueImpl &rhs) + { + if (this != &rhs) + { + m_valobj_sp = rhs.m_valobj_sp; + m_use_dynamic = rhs.m_use_dynamic; + m_use_synthetic = rhs.m_use_synthetic; + m_name = rhs.m_name; + } + return *this; + } + + bool + IsValid () + { + return m_valobj_sp.get() != NULL; + } + + lldb::ValueObjectSP + GetRootSP () + { + return m_valobj_sp; + } + + lldb::ValueObjectSP + GetSP (Process::StopLocker &stop_locker, Mutex::Locker &api_locker, Error &error) + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (!m_valobj_sp) + { + error.SetErrorString("invalid value object"); + return m_valobj_sp; + } + + lldb::ValueObjectSP value_sp = m_valobj_sp; + + Target *target = value_sp->GetTargetSP().get(); + if (target) + api_locker.Lock(target->GetAPIMutex()); + + ProcessSP process_sp(value_sp->GetProcessSP()); + if (process_sp && !stop_locker.TryLock (&process_sp->GetRunLock())) + { + // We don't allow people to play around with ValueObject if the process is running. + // If you want to look at values, pause the process, then look. + if (log) + log->Printf ("SBValue(%p)::GetSP() => error: process is running", value_sp.get()); + error.SetErrorString ("process must be stopped."); + return ValueObjectSP(); + } + + if (value_sp->GetDynamicValue(m_use_dynamic)) + value_sp = value_sp->GetDynamicValue(m_use_dynamic); + if (value_sp->GetSyntheticValue(m_use_synthetic)) + value_sp = value_sp->GetSyntheticValue(m_use_synthetic); + if (!value_sp) + error.SetErrorString("invalid value object"); + if (!m_name.IsEmpty()) + value_sp->SetName(m_name); + + return value_sp; + } + + void + SetUseDynamic (lldb::DynamicValueType use_dynamic) + { + m_use_dynamic = use_dynamic; + } + + void + SetUseSynthetic (bool use_synthetic) + { + m_use_synthetic = use_synthetic; + } + + lldb::DynamicValueType + GetUseDynamic () + { + return m_use_dynamic; + } + + bool + GetUseSynthetic () + { + return m_use_synthetic; + } + + // All the derived values that we would make from the m_valobj_sp will share + // the ExecutionContext with m_valobj_sp, so we don't need to do the calculations + // in GetSP to return the Target, Process, Thread or Frame. It is convenient to + // provide simple accessors for these, which I do here. + TargetSP + GetTargetSP () + { + if (m_valobj_sp) + return m_valobj_sp->GetTargetSP(); + else + return TargetSP(); + } + + ProcessSP + GetProcessSP () + { + if (m_valobj_sp) + return m_valobj_sp->GetProcessSP(); + else + return ProcessSP(); + } + + ThreadSP + GetThreadSP () + { + if (m_valobj_sp) + return m_valobj_sp->GetThreadSP(); + else + return ThreadSP(); + } + + StackFrameSP + GetFrameSP () + { + if (m_valobj_sp) + return m_valobj_sp->GetFrameSP(); + else + return StackFrameSP(); + } + +private: + lldb::ValueObjectSP m_valobj_sp; + lldb::DynamicValueType m_use_dynamic; + bool m_use_synthetic; + ConstString m_name; +}; + +class ValueLocker +{ +public: + ValueLocker () + { + } + + ValueObjectSP + GetLockedSP(ValueImpl &in_value) + { + return in_value.GetSP(m_stop_locker, m_api_locker, m_lock_error); + } + + Error & + GetError() + { + return m_lock_error; + } + +private: + Process::StopLocker m_stop_locker; + Mutex::Locker m_api_locker; + Error m_lock_error; + +}; + +SBValue::SBValue () : + m_opaque_sp () +{ +} + +SBValue::SBValue (const lldb::ValueObjectSP &value_sp) +{ + SetSP(value_sp); +} + +SBValue::SBValue(const SBValue &rhs) +{ + SetSP(rhs.m_opaque_sp); +} + +SBValue & +SBValue::operator = (const SBValue &rhs) +{ + if (this != &rhs) + { + SetSP(rhs.m_opaque_sp); + } + return *this; +} + +SBValue::~SBValue() +{ +} + +bool +SBValue::IsValid () +{ + // If this function ever changes to anything that does more than just + // check if the opaque shared pointer is non NULL, then we need to update + // all "if (m_opaque_sp)" code in this file. + return m_opaque_sp.get() != NULL && m_opaque_sp->GetRootSP().get() != NULL; +} + +void +SBValue::Clear() +{ + m_opaque_sp.reset(); +} + +SBError +SBValue::GetError() +{ + SBError sb_error; + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + sb_error.SetError(value_sp->GetError()); + else + sb_error.SetErrorStringWithFormat ("error: %s", locker.GetError().AsCString()); + + return sb_error; +} + +user_id_t +SBValue::GetID() +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->GetID(); + return LLDB_INVALID_UID; +} + +const char * +SBValue::GetName() +{ + const char *name = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + name = value_sp->GetName().GetCString(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (name) + log->Printf ("SBValue(%p)::GetName () => \"%s\"", value_sp.get(), name); + else + log->Printf ("SBValue(%p)::GetName () => NULL", value_sp.get()); + } + + return name; +} + +const char * +SBValue::GetTypeName () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *name = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + name = value_sp->GetQualifiedTypeName().GetCString(); + } + + if (log) + { + if (name) + log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", value_sp.get(), name); + else + log->Printf ("SBValue(%p)::GetTypeName () => NULL", value_sp.get()); + } + + return name; +} + +size_t +SBValue::GetByteSize () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + size_t result = 0; + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + result = value_sp->GetByteSize(); + } + + if (log) + log->Printf ("SBValue(%p)::GetByteSize () => %" PRIu64, value_sp.get(), (uint64_t)result); + + return result; +} + +bool +SBValue::IsInScope () +{ + bool result = false; + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + result = value_sp->IsInScope (); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::IsInScope () => %i", value_sp.get(), result); + + return result; +} + +const char * +SBValue::GetValue () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + const char *cstr = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + cstr = value_sp->GetValueAsCString (); + } + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetValue() => \"%s\"", value_sp.get(), cstr); + else + log->Printf ("SBValue(%p)::GetValue() => NULL", value_sp.get()); + } + + return cstr; +} + +ValueType +SBValue::GetValueType () +{ + ValueType result = eValueTypeInvalid; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + result = value_sp->GetValueType(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + switch (result) + { + case eValueTypeInvalid: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeInvalid", value_sp.get()); break; + case eValueTypeVariableGlobal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", value_sp.get()); break; + case eValueTypeVariableStatic: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", value_sp.get()); break; + case eValueTypeVariableArgument:log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", value_sp.get()); break; + case eValueTypeVariableLocal: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", value_sp.get()); break; + case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", value_sp.get()); break; + case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", value_sp.get()); break; + case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", value_sp.get()); break; + } + } + return result; +} + +const char * +SBValue::GetObjectDescription () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *cstr = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + cstr = value_sp->GetObjectDescription (); + } + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetObjectDescription() => \"%s\"", value_sp.get(), cstr); + else + log->Printf ("SBValue(%p)::GetObjectDescription() => NULL", value_sp.get()); + } + return cstr; +} + +SBType +SBValue::GetType() +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBType sb_type; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + TypeImplSP type_sp; + if (value_sp) + { + type_sp.reset (new TypeImpl(value_sp->GetClangType())); + sb_type.SetSP(type_sp); + } + if (log) + { + if (type_sp) + log->Printf ("SBValue(%p)::GetType => SBType(%p)", value_sp.get(), type_sp.get()); + else + log->Printf ("SBValue(%p)::GetType => NULL", value_sp.get()); + } + return sb_type; +} + +bool +SBValue::GetValueDidChange () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool result = false; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + result = value_sp->GetValueDidChange (); + } + if (log) + log->Printf ("SBValue(%p)::GetValueDidChange() => %i", value_sp.get(), result); + + return result; +} + +#ifndef LLDB_DISABLE_PYTHON +const char * +SBValue::GetSummary () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *cstr = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + cstr = value_sp->GetSummaryAsCString(); + } + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetSummary() => \"%s\"", value_sp.get(), cstr); + else + log->Printf ("SBValue(%p)::GetSummary() => NULL", value_sp.get()); + } + return cstr; +} +#endif // LLDB_DISABLE_PYTHON + +const char * +SBValue::GetLocation () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *cstr = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + cstr = value_sp->GetLocationAsCString(); + } + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetLocation() => \"%s\"", value_sp.get(), cstr); + else + log->Printf ("SBValue(%p)::GetLocation() => NULL", value_sp.get()); + } + return cstr; +} + +// Deprecated - use the one that takes an lldb::SBError +bool +SBValue::SetValueFromCString (const char *value_str) +{ + lldb::SBError dummy; + return SetValueFromCString(value_str,dummy); +} + +bool +SBValue::SetValueFromCString (const char *value_str, lldb::SBError& error) +{ + bool success = false; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (value_sp) + { + success = value_sp->SetValueFromCString (value_str,error.ref()); + } + else + error.SetErrorStringWithFormat ("Could not get value: %s", locker.GetError().AsCString()); + + if (log) + log->Printf ("SBValue(%p)::SetValueFromCString(\"%s\") => %i", value_sp.get(), value_str, success); + + return success; +} + +lldb::SBTypeFormat +SBValue::GetTypeFormat () +{ + lldb::SBTypeFormat format; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + if (value_sp->UpdateValueIfNeeded(true)) + { + lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat(); + if (format_sp) + format.SetSP(format_sp); + } + } + return format; +} + +#ifndef LLDB_DISABLE_PYTHON +lldb::SBTypeSummary +SBValue::GetTypeSummary () +{ + lldb::SBTypeSummary summary; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + if (value_sp->UpdateValueIfNeeded(true)) + { + lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat(); + if (summary_sp) + summary.SetSP(summary_sp); + } + } + return summary; +} +#endif // LLDB_DISABLE_PYTHON + +lldb::SBTypeFilter +SBValue::GetTypeFilter () +{ + lldb::SBTypeFilter filter; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + if (value_sp->UpdateValueIfNeeded(true)) + { + lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren(); + + if (synthetic_sp && !synthetic_sp->IsScripted()) + { + TypeFilterImplSP filter_sp = std::static_pointer_cast<TypeFilterImpl>(synthetic_sp); + filter.SetSP(filter_sp); + } + } + } + return filter; +} + +#ifndef LLDB_DISABLE_PYTHON +lldb::SBTypeSynthetic +SBValue::GetTypeSynthetic () +{ + lldb::SBTypeSynthetic synthetic; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + if (value_sp->UpdateValueIfNeeded(true)) + { + lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren(); + + if (children_sp && children_sp->IsScripted()) + { + ScriptedSyntheticChildrenSP synth_sp = std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp); + synthetic.SetSP(synth_sp); + } + } + } + return synthetic; +} +#endif + +lldb::SBValue +SBValue::CreateChildAtOffset (const char *name, uint32_t offset, SBType type) +{ + lldb::SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + lldb::ValueObjectSP new_value_sp; + if (value_sp) + { + TypeImplSP type_sp (type.GetSP()); + if (type.IsValid()) + { + sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(offset, type_sp->GetClangASTType(), true),GetPreferDynamicValue(),GetPreferSyntheticValue(), name); + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBValue(%p)::CreateChildAtOffset => \"%s\"", + value_sp.get(), + new_value_sp->GetName().AsCString()); + else + log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL", + value_sp.get()); + } + return sb_value; +} + +lldb::SBValue +SBValue::Cast (SBType type) +{ + lldb::SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + TypeImplSP type_sp (type.GetSP()); + if (value_sp && type_sp) + sb_value.SetSP(value_sp->Cast(type_sp->GetClangASTType()),GetPreferDynamicValue(),GetPreferSyntheticValue()); + return sb_value; +} + +lldb::SBValue +SBValue::CreateValueFromExpression (const char *name, const char* expression) +{ + SBExpressionOptions options; + options.ref().SetKeepInMemory(true); + return CreateValueFromExpression (name, expression, options); +} + +lldb::SBValue +SBValue::CreateValueFromExpression (const char *name, const char *expression, SBExpressionOptions &options) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + lldb::ValueObjectSP new_value_sp; + if (value_sp) + { + ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); + Target* target = exe_ctx.GetTargetPtr(); + if (target) + { + options.ref().SetKeepInMemory(true); + target->EvaluateExpression (expression, + exe_ctx.GetFramePtr(), + new_value_sp, + options.ref()); + if (new_value_sp) + { + new_value_sp->SetName(ConstString(name)); + sb_value.SetSP(new_value_sp); + } + } + } + if (log) + { + if (new_value_sp) + log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => SBValue (%p)", + value_sp.get(), + name, + expression, + new_value_sp.get()); + else + log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => NULL", + value_sp.get(), + name, + expression); + } + return sb_value; +} + +lldb::SBValue +SBValue::CreateValueFromAddress(const char* name, lldb::addr_t address, SBType sb_type) +{ + lldb::SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + lldb::ValueObjectSP new_value_sp; + lldb::TypeImplSP type_impl_sp (sb_type.GetSP()); + if (value_sp && type_impl_sp) + { + ClangASTType pointee_ast_type(type_impl_sp->GetClangASTType().GetPointerType ()); + if (pointee_ast_type) + { + lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); + + ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); + ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), + pointee_ast_type, + ConstString(name), + buffer, + lldb::endian::InlHostByteOrder(), + exe_ctx.GetAddressByteSize())); + + if (ptr_result_valobj_sp) + { + ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress); + Error err; + new_value_sp = ptr_result_valobj_sp->Dereference(err); + if (new_value_sp) + new_value_sp->SetName(ConstString(name)); + } + sb_value.SetSP(new_value_sp); + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBValue(%p)::CreateValueFromAddress => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString()); + else + log->Printf ("SBValue(%p)::CreateValueFromAddress => NULL", value_sp.get()); + } + return sb_value; +} + +lldb::SBValue +SBValue::CreateValueFromData (const char* name, SBData data, SBType type) +{ + lldb::SBValue sb_value; + lldb::ValueObjectSP new_value_sp; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); + + new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), + type.m_opaque_sp->GetClangASTType(), + ConstString(name), + *data.m_opaque_sp, + LLDB_INVALID_ADDRESS); + new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad); + sb_value.SetSP(new_value_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBValue(%p)::CreateValueFromData => \"%s\"", value_sp.get(), new_value_sp->GetName().AsCString()); + else + log->Printf ("SBValue(%p)::CreateValueFromData => NULL", value_sp.get()); + } + return sb_value; +} + +SBValue +SBValue::GetChildAtIndex (uint32_t idx) +{ + const bool can_create_synthetic = false; + lldb::DynamicValueType use_dynamic = eNoDynamicValues; + TargetSP target_sp; + if (m_opaque_sp) + target_sp = m_opaque_sp->GetTargetSP(); + + if (target_sp) + use_dynamic = target_sp->GetPreferDynamicValue(); + + return GetChildAtIndex (idx, use_dynamic, can_create_synthetic); +} + +SBValue +SBValue::GetChildAtIndex (uint32_t idx, lldb::DynamicValueType use_dynamic, bool can_create_synthetic) +{ + lldb::ValueObjectSP child_sp; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + const bool can_create = true; + child_sp = value_sp->GetChildAtIndex (idx, can_create); + if (can_create_synthetic && !child_sp) + { + if (value_sp->IsPointerType()) + { + child_sp = value_sp->GetSyntheticArrayMemberFromPointer(idx, can_create); + } + else if (value_sp->IsArrayType()) + { + child_sp = value_sp->GetSyntheticArrayMemberFromArray(idx, can_create); + } + } + } + + SBValue sb_value; + sb_value.SetSP (child_sp, use_dynamic, GetPreferSyntheticValue()); + if (log) + log->Printf ("SBValue(%p)::GetChildAtIndex (%u) => SBValue(%p)", value_sp.get(), idx, value_sp.get()); + + return sb_value; +} + +uint32_t +SBValue::GetIndexOfChildWithName (const char *name) +{ + uint32_t idx = UINT32_MAX; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + idx = value_sp->GetIndexOfChildWithName (ConstString(name)); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (idx == UINT32_MAX) + log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => NOT FOUND", value_sp.get(), name); + else + log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", value_sp.get(), name, idx); + } + return idx; +} + +SBValue +SBValue::GetChildMemberWithName (const char *name) +{ + lldb::DynamicValueType use_dynamic_value = eNoDynamicValues; + TargetSP target_sp; + if (m_opaque_sp) + target_sp = m_opaque_sp->GetTargetSP(); + + if (target_sp) + use_dynamic_value = target_sp->GetPreferDynamicValue(); + return GetChildMemberWithName (name, use_dynamic_value); +} + +SBValue +SBValue::GetChildMemberWithName (const char *name, lldb::DynamicValueType use_dynamic_value) +{ + lldb::ValueObjectSP child_sp; + const ConstString str_name (name); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + child_sp = value_sp->GetChildMemberWithName (str_name, true); + } + + SBValue sb_value; + sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue()); + + if (log) + log->Printf ("SBValue(%p)::GetChildMemberWithName (name=\"%s\") => SBValue(%p)", value_sp.get(), name, value_sp.get()); + + return sb_value; +} + +lldb::SBValue +SBValue::GetDynamicValue (lldb::DynamicValueType use_dynamic) +{ + SBValue value_sb; + if (IsValid()) + { + ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),use_dynamic,m_opaque_sp->GetUseSynthetic())); + value_sb.SetSP(proxy_sp); + } + return value_sb; +} + +lldb::SBValue +SBValue::GetStaticValue () +{ + SBValue value_sb; + if (IsValid()) + { + ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),eNoDynamicValues,m_opaque_sp->GetUseSynthetic())); + value_sb.SetSP(proxy_sp); + } + return value_sb; +} + +lldb::SBValue +SBValue::GetNonSyntheticValue () +{ + SBValue value_sb; + if (IsValid()) + { + ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),m_opaque_sp->GetUseDynamic(),false)); + value_sb.SetSP(proxy_sp); + } + return value_sb; +} + +lldb::DynamicValueType +SBValue::GetPreferDynamicValue () +{ + if (!IsValid()) + return eNoDynamicValues; + return m_opaque_sp->GetUseDynamic(); +} + +void +SBValue::SetPreferDynamicValue (lldb::DynamicValueType use_dynamic) +{ + if (IsValid()) + return m_opaque_sp->SetUseDynamic (use_dynamic); +} + +bool +SBValue::GetPreferSyntheticValue () +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetUseSynthetic(); +} + +void +SBValue::SetPreferSyntheticValue (bool use_synthetic) +{ + if (IsValid()) + return m_opaque_sp->SetUseSynthetic (use_synthetic); +} + +bool +SBValue::IsDynamic() +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->IsDynamic(); + return false; +} + +bool +SBValue::IsSynthetic () +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->IsSynthetic(); + return false; +} + +lldb::SBValue +SBValue::GetValueForExpressionPath(const char* expr_path) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::ValueObjectSP child_sp; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + // using default values for all the fancy options, just do it if you can + child_sp = value_sp->GetValueForExpressionPath(expr_path); + } + + SBValue sb_value; + sb_value.SetSP(child_sp,GetPreferDynamicValue(),GetPreferSyntheticValue()); + + if (log) + log->Printf ("SBValue(%p)::GetValueForExpressionPath (expr_path=\"%s\") => SBValue(%p)", value_sp.get(), expr_path, value_sp.get()); + + return sb_value; +} + +int64_t +SBValue::GetValueAsSigned(SBError& error, int64_t fail_value) +{ + error.Clear(); + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Scalar scalar; + if (value_sp->ResolveValue (scalar)) + return scalar.SLongLong (fail_value); + else + error.SetErrorString ("could not resolve value"); + } + else + error.SetErrorStringWithFormat ("could not get SBValue: %s", locker.GetError().AsCString()); + + return fail_value; +} + +uint64_t +SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value) +{ + error.Clear(); + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Scalar scalar; + if (value_sp->ResolveValue (scalar)) + return scalar.ULongLong(fail_value); + else + error.SetErrorString("could not resolve value"); + } + else + error.SetErrorStringWithFormat ("could not get SBValue: %s", locker.GetError().AsCString()); + + return fail_value; +} + +int64_t +SBValue::GetValueAsSigned(int64_t fail_value) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Scalar scalar; + if (value_sp->ResolveValue (scalar)) + return scalar.SLongLong(fail_value); + } + return fail_value; +} + +uint64_t +SBValue::GetValueAsUnsigned(uint64_t fail_value) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Scalar scalar; + if (value_sp->ResolveValue (scalar)) + return scalar.ULongLong(fail_value); + } + return fail_value; +} + +bool +SBValue::MightHaveChildren () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool has_children = false; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + has_children = value_sp->MightHaveChildren(); + + if (log) + log->Printf ("SBValue(%p)::MightHaveChildren() => %i", value_sp.get(), has_children); + return has_children; +} + +uint32_t +SBValue::GetNumChildren () +{ + uint32_t num_children = 0; + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + num_children = value_sp->GetNumChildren(); + + if (log) + log->Printf ("SBValue(%p)::GetNumChildren () => %u", value_sp.get(), num_children); + + return num_children; +} + + +SBValue +SBValue::Dereference () +{ + SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Error error; + sb_value = value_sp->Dereference (error); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::Dereference () => SBValue(%p)", value_sp.get(), value_sp.get()); + + return sb_value; +} + +bool +SBValue::TypeIsPointerType () +{ + bool is_ptr_type = false; + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + is_ptr_type = value_sp->IsPointerType(); + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::TypeIsPointerType () => %i", value_sp.get(), is_ptr_type); + + + return is_ptr_type; +} + +void * +SBValue::GetOpaqueType() +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->GetClangType().GetOpaqueQualType(); + return NULL; +} + +lldb::SBTarget +SBValue::GetTarget() +{ + SBTarget sb_target; + TargetSP target_sp; + if (m_opaque_sp) + { + target_sp = m_opaque_sp->GetTargetSP(); + sb_target.SetSP (target_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (target_sp.get() == NULL) + log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get()); + else + log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), target_sp.get()); + } + return sb_target; +} + +lldb::SBProcess +SBValue::GetProcess() +{ + SBProcess sb_process; + ProcessSP process_sp; + if (m_opaque_sp) + { + process_sp = m_opaque_sp->GetProcessSP(); + sb_process.SetSP (process_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (process_sp.get() == NULL) + log->Printf ("SBValue(%p)::GetProcess () => NULL", m_opaque_sp.get()); + else + log->Printf ("SBValue(%p)::GetProcess () => %p", m_opaque_sp.get(), process_sp.get()); + } + return sb_process; +} + +lldb::SBThread +SBValue::GetThread() +{ + SBThread sb_thread; + ThreadSP thread_sp; + if (m_opaque_sp) + { + thread_sp = m_opaque_sp->GetThreadSP(); + sb_thread.SetThread(thread_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (thread_sp.get() == NULL) + log->Printf ("SBValue(%p)::GetThread () => NULL", m_opaque_sp.get()); + else + log->Printf ("SBValue(%p)::GetThread () => %p", m_opaque_sp.get(), thread_sp.get()); + } + return sb_thread; +} + +lldb::SBFrame +SBValue::GetFrame() +{ + SBFrame sb_frame; + StackFrameSP frame_sp; + if (m_opaque_sp) + { + frame_sp = m_opaque_sp->GetFrameSP(); + sb_frame.SetFrameSP (frame_sp); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (frame_sp.get() == NULL) + log->Printf ("SBValue(%p)::GetFrame () => NULL", m_opaque_sp.get()); + else + log->Printf ("SBValue(%p)::GetFrame () => %p", m_opaque_sp.get(), frame_sp.get()); + } + return sb_frame; +} + + +lldb::ValueObjectSP +SBValue::GetSP (ValueLocker &locker) const +{ + if (!m_opaque_sp || !m_opaque_sp->IsValid()) + return ValueObjectSP(); + return locker.GetLockedSP(*m_opaque_sp.get()); +} + +lldb::ValueObjectSP +SBValue::GetSP () const +{ + ValueLocker locker; + return GetSP(locker); +} + +void +SBValue::SetSP (ValueImplSP impl_sp) +{ + m_opaque_sp = impl_sp; +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp) +{ + if (sp) + { + lldb::TargetSP target_sp(sp->GetTargetSP()); + if (target_sp) + { + lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); + bool use_synthetic = target_sp->TargetProperties::GetEnableSyntheticValue(); + m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic)); + } + else + m_opaque_sp = ValueImplSP(new ValueImpl(sp,eNoDynamicValues,true)); + } + else + m_opaque_sp = ValueImplSP(new ValueImpl(sp,eNoDynamicValues,false)); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic) +{ + if (sp) + { + lldb::TargetSP target_sp(sp->GetTargetSP()); + if (target_sp) + { + bool use_synthetic = target_sp->TargetProperties::GetEnableSyntheticValue(); + SetSP (sp, use_dynamic, use_synthetic); + } + else + SetSP (sp, use_dynamic, true); + } + else + SetSP (sp, use_dynamic, false); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, bool use_synthetic) +{ + if (sp) + { + lldb::TargetSP target_sp(sp->GetTargetSP()); + if (target_sp) + { + lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue(); + SetSP (sp, use_dynamic, use_synthetic); + } + else + SetSP (sp, eNoDynamicValues, use_synthetic); + } + else + SetSP (sp, eNoDynamicValues, use_synthetic); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic) +{ + m_opaque_sp = ValueImplSP(new ValueImpl(sp,use_dynamic,use_synthetic)); +} + +void +SBValue::SetSP (const lldb::ValueObjectSP &sp, lldb::DynamicValueType use_dynamic, bool use_synthetic, const char *name) +{ + m_opaque_sp = ValueImplSP(new ValueImpl(sp,use_dynamic,use_synthetic, name)); +} + +bool +SBValue::GetExpressionPath (SBStream &description) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + value_sp->GetExpressionPath (description.ref(), false); + return true; + } + return false; +} + +bool +SBValue::GetExpressionPath (SBStream &description, bool qualify_cxx_base_classes) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + value_sp->GetExpressionPath (description.ref(), qualify_cxx_base_classes); + return true; + } + return false; +} + +bool +SBValue::GetDescription (SBStream &description) +{ + Stream &strm = description.ref(); + + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + ValueObject::DumpValueObject (strm, value_sp.get()); + } + else + strm.PutCString ("No value"); + + return true; +} + +lldb::Format +SBValue::GetFormat () +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + return value_sp->GetFormat(); + return eFormatDefault; +} + +void +SBValue::SetFormat (lldb::Format format) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + value_sp->SetFormat(format); +} + +lldb::SBValue +SBValue::AddressOf() +{ + SBValue sb_value; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + Error error; + sb_value.SetSP(value_sp->AddressOf (error),GetPreferDynamicValue(), GetPreferSyntheticValue()); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::AddressOf () => SBValue(%p)", value_sp.get(), value_sp.get()); + + return sb_value; +} + +lldb::addr_t +SBValue::GetLoadAddress() +{ + lldb::addr_t value = LLDB_INVALID_ADDRESS; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + TargetSP target_sp (value_sp->GetTargetSP()); + if (target_sp) + { + const bool scalar_is_load_address = true; + AddressType addr_type; + value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); + if (addr_type == eAddressTypeFile) + { + ModuleSP module_sp (value_sp->GetModule()); + if (!module_sp) + value = LLDB_INVALID_ADDRESS; + else + { + Address addr; + module_sp->ResolveFileAddress(value, addr); + value = addr.GetLoadAddress(target_sp.get()); + } + } + else if (addr_type == eAddressTypeHost || addr_type == eAddressTypeInvalid) + value = LLDB_INVALID_ADDRESS; + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::GetLoadAddress () => (%" PRIu64 ")", value_sp.get(), value); + + return value; +} + +lldb::SBAddress +SBValue::GetAddress() +{ + Address addr; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + TargetSP target_sp (value_sp->GetTargetSP()); + if (target_sp) + { + lldb::addr_t value = LLDB_INVALID_ADDRESS; + const bool scalar_is_load_address = true; + AddressType addr_type; + value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); + if (addr_type == eAddressTypeFile) + { + ModuleSP module_sp (value_sp->GetModule()); + if (module_sp) + module_sp->ResolveFileAddress(value, addr); + } + else if (addr_type == eAddressTypeLoad) + { + // no need to check the return value on this.. if it can actually do the resolve + // addr will be in the form (section,offset), otherwise it will simply be returned + // as (NULL, value) + addr.SetLoadAddress(value, target_sp.get()); + } + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::GetAddress () => (%s,%" PRIu64 ")", value_sp.get(), + (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), + addr.GetOffset()); + return SBAddress(new Address(addr)); +} + +lldb::SBData +SBValue::GetPointeeData (uint32_t item_idx, + uint32_t item_count) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::SBData sb_data; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + TargetSP target_sp (value_sp->GetTargetSP()); + if (target_sp) + { + DataExtractorSP data_sp(new DataExtractor()); + value_sp->GetPointeeData(*data_sp, item_idx, item_count); + if (data_sp->GetByteSize() > 0) + *sb_data = data_sp; + } + } + if (log) + log->Printf ("SBValue(%p)::GetPointeeData (%d, %d) => SBData(%p)", + value_sp.get(), + item_idx, + item_count, + sb_data.get()); + + return sb_data; +} + +lldb::SBData +SBValue::GetData () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + lldb::SBData sb_data; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + DataExtractorSP data_sp(new DataExtractor()); + value_sp->GetData(*data_sp); + if (data_sp->GetByteSize() > 0) + *sb_data = data_sp; + } + if (log) + log->Printf ("SBValue(%p)::GetData () => SBData(%p)", + value_sp.get(), + sb_data.get()); + + return sb_data; +} + +bool +SBValue::SetData (lldb::SBData &data, SBError &error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + bool ret = true; + + if (value_sp) + { + DataExtractor *data_extractor = data.get(); + + if (!data_extractor) + { + if (log) + log->Printf ("SBValue(%p)::SetData() => error: no data to set", value_sp.get()); + + error.SetErrorString("No data to set"); + ret = false; + } + else + { + Error set_error; + + value_sp->SetData(*data_extractor, set_error); + + if (!set_error.Success()) + { + error.SetErrorStringWithFormat("Couldn't set data: %s", set_error.AsCString()); + ret = false; + } + } + } + else + { + error.SetErrorStringWithFormat ("Couldn't set data: could not get SBValue: %s", locker.GetError().AsCString()); + ret = false; + } + + if (log) + log->Printf ("SBValue(%p)::SetData (%p) => %s", + value_sp.get(), + data.get(), + ret ? "true" : "false"); + return ret; +} + +lldb::SBDeclaration +SBValue::GetDeclaration () +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + SBDeclaration decl_sb; + if (value_sp) + { + Declaration decl; + if (value_sp->GetDeclaration(decl)) + decl_sb.SetDeclaration(decl); + } + return decl_sb; +} + +lldb::SBWatchpoint +SBValue::Watch (bool resolve_location, bool read, bool write, SBError &error) +{ + SBWatchpoint sb_watchpoint; + + // If the SBValue is not valid, there's no point in even trying to watch it. + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + TargetSP target_sp (GetTarget().GetSP()); + if (value_sp && target_sp) + { + // Read and Write cannot both be false. + if (!read && !write) + return sb_watchpoint; + + // If the value is not in scope, don't try and watch and invalid value + if (!IsInScope()) + return sb_watchpoint; + + addr_t addr = GetLoadAddress(); + if (addr == LLDB_INVALID_ADDRESS) + return sb_watchpoint; + size_t byte_size = GetByteSize(); + if (byte_size == 0) + return sb_watchpoint; + + uint32_t watch_type = 0; + if (read) + watch_type |= LLDB_WATCH_TYPE_READ; + if (write) + watch_type |= LLDB_WATCH_TYPE_WRITE; + + Error rc; + ClangASTType type (value_sp->GetClangType()); + WatchpointSP watchpoint_sp = target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc); + error.SetError(rc); + + if (watchpoint_sp) + { + sb_watchpoint.SetSP (watchpoint_sp); + Declaration decl; + if (value_sp->GetDeclaration (decl)) + { + if (decl.GetFile()) + { + StreamString ss; + // True to show fullpath for declaration file. + decl.DumpStopContext(&ss, true); + watchpoint_sp->SetDeclInfo(ss.GetString()); + } + } + } + } + else if (target_sp) + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::Watch() => error getting SBValue: %s", value_sp.get(), locker.GetError().AsCString()); + + error.SetErrorStringWithFormat("could not get SBValue: %s", locker.GetError().AsCString()); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBValue(%p)::Watch() => error getting SBValue: no target", value_sp.get()); + error.SetErrorString("could not set watchpoint, a target is required"); + } + + return sb_watchpoint; +} + +// FIXME: Remove this method impl (as well as the decl in .h) once it is no longer needed. +// Backward compatibility fix in the interim. +lldb::SBWatchpoint +SBValue::Watch (bool resolve_location, bool read, bool write) +{ + SBError error; + return Watch(resolve_location, read, write, error); +} + +lldb::SBWatchpoint +SBValue::WatchPointee (bool resolve_location, bool read, bool write, SBError &error) +{ + SBWatchpoint sb_watchpoint; + if (IsInScope() && GetType().IsPointerType()) + sb_watchpoint = Dereference().Watch (resolve_location, read, write, error); + return sb_watchpoint; +} diff --git a/contrib/llvm/tools/lldb/source/API/SBValueList.cpp b/contrib/llvm/tools/lldb/source/API/SBValueList.cpp new file mode 100644 index 0000000..46866eb --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBValueList.cpp @@ -0,0 +1,275 @@ +//===-- SBValueList.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/SBValueList.h" +#include "lldb/API/SBValue.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/ValueObjectList.h" + +#include <vector> + +using namespace lldb; +using namespace lldb_private; + +class ValueListImpl +{ +public: + ValueListImpl () : + m_values() + { + } + + ValueListImpl (const ValueListImpl& rhs) : + m_values(rhs.m_values) + { + } + + ValueListImpl& + operator = (const ValueListImpl& rhs) + { + if (this == &rhs) + return *this; + m_values = rhs.m_values; + return *this; + }; + + uint32_t + GetSize () + { + return m_values.size(); + } + + void + Append (const lldb::SBValue& sb_value) + { + m_values.push_back(sb_value); + } + + void + Append (const ValueListImpl& list) + { + for (auto val : list.m_values) + Append (val); + } + + lldb::SBValue + GetValueAtIndex (uint32_t index) + { + if (index >= GetSize()) + return lldb::SBValue(); + return m_values[index]; + } + + lldb::SBValue + FindValueByUID (lldb::user_id_t uid) + { + for (auto val : m_values) + { + if (val.IsValid() && val.GetID() == uid) + return val; + } + return lldb::SBValue(); + } + +private: + std::vector<lldb::SBValue> m_values; +}; + +SBValueList::SBValueList () : + m_opaque_ap () +{ +} + +SBValueList::SBValueList (const SBValueList &rhs) : + m_opaque_ap () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (rhs.IsValid()) + m_opaque_ap.reset (new ValueListImpl (*rhs)); + + if (log) + { + log->Printf ("SBValueList::SBValueList (rhs.ap=%p) => this.ap = %p", + (rhs.IsValid() ? rhs.m_opaque_ap.get() : NULL), + m_opaque_ap.get()); + } +} + +SBValueList::SBValueList (const ValueListImpl *lldb_object_ptr) : + m_opaque_ap () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (lldb_object_ptr) + m_opaque_ap.reset (new ValueListImpl (*lldb_object_ptr)); + + if (log) + { + log->Printf ("SBValueList::SBValueList (lldb_object_ptr=%p) => this.ap = %p", + lldb_object_ptr, + m_opaque_ap.get()); + } +} + +SBValueList::~SBValueList () +{ +} + +bool +SBValueList::IsValid () const +{ + return (m_opaque_ap.get() != NULL); +} + +void +SBValueList::Clear() +{ + m_opaque_ap.reset(); +} + +const SBValueList & +SBValueList::operator = (const SBValueList &rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_ap.reset (new ValueListImpl (*rhs)); + else + m_opaque_ap.reset (); + } + return *this; +} + +ValueListImpl * +SBValueList::operator->() +{ + return m_opaque_ap.get(); +} + +ValueListImpl & +SBValueList::operator*() +{ + return *m_opaque_ap; +} + +const ValueListImpl * +SBValueList::operator->() const +{ + return m_opaque_ap.get(); +} + +const ValueListImpl & +SBValueList::operator*() const +{ + return *m_opaque_ap; +} + +void +SBValueList::Append (const SBValue &val_obj) +{ + CreateIfNeeded (); + m_opaque_ap->Append (val_obj); +} + +void +SBValueList::Append (lldb::ValueObjectSP& val_obj_sp) +{ + if (val_obj_sp) + { + CreateIfNeeded (); + m_opaque_ap->Append (SBValue(val_obj_sp)); + } +} + +void +SBValueList::Append (const lldb::SBValueList& value_list) +{ + if (value_list.IsValid()) + { + CreateIfNeeded (); + m_opaque_ap->Append (*value_list); + } +} + + +SBValue +SBValueList::GetValueAtIndex (uint32_t idx) const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + //if (log) + // log->Printf ("SBValueList::GetValueAtIndex (uint32_t idx) idx = %d", idx); + + SBValue sb_value; + if (m_opaque_ap.get()) + sb_value = m_opaque_ap->GetValueAtIndex (idx); + + if (log) + { + SBStream sstr; + sb_value.GetDescription (sstr); + log->Printf ("SBValueList::GetValueAtIndex (this.ap=%p, idx=%d) => SBValue (this.sp = %p, '%s')", + m_opaque_ap.get(), idx, sb_value.GetSP().get(), sstr.GetData()); + } + + return sb_value; +} + +uint32_t +SBValueList::GetSize () const +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + //if (log) + // log->Printf ("SBValueList::GetSize ()"); + + uint32_t size = 0; + if (m_opaque_ap.get()) + size = m_opaque_ap->GetSize(); + + if (log) + log->Printf ("SBValueList::GetSize (this.ap=%p) => %d", m_opaque_ap.get(), size); + + return size; +} + +void +SBValueList::CreateIfNeeded () +{ + if (m_opaque_ap.get() == NULL) + m_opaque_ap.reset (new ValueListImpl()); +} + + +SBValue +SBValueList::FindValueObjectByUID (lldb::user_id_t uid) +{ + SBValue sb_value; + if (m_opaque_ap.get()) + sb_value = m_opaque_ap->FindValueByUID(uid); + return sb_value; +} + +void * +SBValueList::opaque_ptr () +{ + return m_opaque_ap.get(); +} + +ValueListImpl & +SBValueList::ref () +{ + CreateIfNeeded(); + return *m_opaque_ap.get(); +} + + diff --git a/contrib/llvm/tools/lldb/source/API/SBWatchpoint.cpp b/contrib/llvm/tools/lldb/source/API/SBWatchpoint.cpp new file mode 100644 index 0000000..194695c --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBWatchpoint.cpp @@ -0,0 +1,298 @@ +//===-- SBWatchpoint.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/SBWatchpoint.h" +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBStream.h" + +#include "lldb/lldb-types.h" +#include "lldb/lldb-defines.h" +#include "lldb/Breakpoint/Watchpoint.h" +#include "lldb/Breakpoint/WatchpointList.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + + +SBWatchpoint::SBWatchpoint () : + m_opaque_sp () +{ +} + +SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp) : + m_opaque_sp (wp_sp) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + { + SBStream sstr; + GetDescription (sstr, lldb::eDescriptionLevelBrief); + log->Printf ("SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp" + "=%p) => this.sp = %p (%s)", wp_sp.get(), m_opaque_sp.get(), sstr.GetData()); + } +} + +SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +const SBWatchpoint & +SBWatchpoint::operator = (const SBWatchpoint &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + + +SBWatchpoint::~SBWatchpoint () +{ +} + +watch_id_t +SBWatchpoint::GetID () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + watch_id_t watch_id = LLDB_INVALID_WATCH_ID; + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + watch_id = watchpoint_sp->GetID(); + + if (log) + { + if (watch_id == LLDB_INVALID_WATCH_ID) + log->Printf ("SBWatchpoint(%p)::GetID () => LLDB_INVALID_WATCH_ID", watchpoint_sp.get()); + else + log->Printf ("SBWatchpoint(%p)::GetID () => %u", watchpoint_sp.get(), watch_id); + } + + return watch_id; +} + +bool +SBWatchpoint::IsValid() const +{ + return (bool) m_opaque_sp; +} + +SBError +SBWatchpoint::GetError () +{ + SBError sb_error; + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + sb_error.SetError(watchpoint_sp->GetError()); + } + return sb_error; +} + +int32_t +SBWatchpoint::GetHardwareIndex () +{ + int32_t hw_index = -1; + + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + hw_index = watchpoint_sp->GetHardwareIndex(); + } + + return hw_index; +} + +addr_t +SBWatchpoint::GetWatchAddress () +{ + addr_t ret_addr = LLDB_INVALID_ADDRESS; + + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + ret_addr = watchpoint_sp->GetLoadAddress(); + } + + return ret_addr; +} + +size_t +SBWatchpoint::GetWatchSize () +{ + size_t watch_size = 0; + + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + watch_size = watchpoint_sp->GetByteSize(); + } + + return watch_size; +} + +void +SBWatchpoint::SetEnabled (bool enabled) +{ + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + watchpoint_sp->GetTarget().DisableWatchpointByID(watchpoint_sp->GetID()); + } +} + +bool +SBWatchpoint::IsEnabled () +{ + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + return watchpoint_sp->IsEnabled(); + } + else + return false; +} + +uint32_t +SBWatchpoint::GetHitCount () +{ + uint32_t count = 0; + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + count = watchpoint_sp->GetHitCount(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBWatchpoint(%p)::GetHitCount () => %u", watchpoint_sp.get(), count); + + return count; +} + +uint32_t +SBWatchpoint::GetIgnoreCount () +{ + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + return watchpoint_sp->GetIgnoreCount(); + } + else + return 0; +} + +void +SBWatchpoint::SetIgnoreCount (uint32_t n) +{ + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + watchpoint_sp->SetIgnoreCount (n); + } +} + +const char * +SBWatchpoint::GetCondition () +{ + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + return watchpoint_sp->GetConditionText (); + } + return NULL; +} + +void +SBWatchpoint::SetCondition (const char *condition) +{ + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + watchpoint_sp->SetCondition (condition); + } +} + +bool +SBWatchpoint::GetDescription (SBStream &description, DescriptionLevel level) +{ + Stream &strm = description.ref(); + + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) + { + Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex()); + watchpoint_sp->GetDescription (&strm, level); + strm.EOL(); + } + else + strm.PutCString ("No value"); + + return true; +} + +void +SBWatchpoint::Clear () +{ + m_opaque_sp.reset(); +} + +lldb::WatchpointSP +SBWatchpoint::GetSP () const +{ + return m_opaque_sp; +} + +void +SBWatchpoint::SetSP (const lldb::WatchpointSP &sp) +{ + m_opaque_sp = sp; +} + +bool +SBWatchpoint::EventIsWatchpointEvent (const lldb::SBEvent &event) +{ + return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != NULL; + +} + +WatchpointEventType +SBWatchpoint::GetWatchpointEventTypeFromEvent (const SBEvent& event) +{ + if (event.IsValid()) + return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent (event.GetSP()); + return eWatchpointEventTypeInvalidType; +} + +SBWatchpoint +SBWatchpoint::GetWatchpointFromEvent (const lldb::SBEvent& event) +{ + SBWatchpoint sb_watchpoint; + if (event.IsValid()) + sb_watchpoint.m_opaque_sp = Watchpoint::WatchpointEventData::GetWatchpointFromEvent (event.GetSP()); + return sb_watchpoint; +} |