diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/API')
54 files changed, 25810 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..d6e32b6 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBAddress.cpp @@ -0,0 +1,328 @@ +//===-- 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 (new Address()) +{ +} + +SBAddress::SBAddress (const Address *lldb_object_ptr) : + m_opaque_ap (new Address()) +{ + if (lldb_object_ptr) + ref() = *lldb_object_ptr; +} + +SBAddress::SBAddress (const SBAddress &rhs) : + m_opaque_ap (new Address()) +{ + 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(new Address()) +{ + 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 (new Address()); + } + return *this; +} + +bool +SBAddress::IsValid () const +{ + return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid(); +} + +void +SBAddress::Clear () +{ + m_opaque_ap.reset (new Address()); +} + +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 (new Address()); +} + +lldb::addr_t +SBAddress::GetFileAddress () const +{ + if (m_opaque_ap->IsValid()) + 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->IsValid()) + { + 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", + static_cast<void*>(target_sp.get())); + else + log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64, + static_cast<void*>(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->IsValid()) + { + 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->IsValid()) + sb_section.SetSP (m_opaque_ap->GetSection()); + return sb_section; +} + +lldb::addr_t +SBAddress::GetOffset () +{ + if (m_opaque_ap->IsValid()) + 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->IsValid()) + { + 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->IsValid()) + sb_module.SetSP (m_opaque_ap->GetModule()); + return sb_module; +} + +SBSymbolContext +SBAddress::GetSymbolContext (uint32_t resolve_scope) +{ + SBSymbolContext sb_sc; + if (m_opaque_ap->IsValid()) + m_opaque_ap->CalculateSymbolContext (&sb_sc.ref(), resolve_scope); + return sb_sc; +} + +SBCompileUnit +SBAddress::GetCompileUnit () +{ + SBCompileUnit sb_comp_unit; + if (m_opaque_ap->IsValid()) + sb_comp_unit.reset(m_opaque_ap->CalculateSymbolContextCompileUnit()); + return sb_comp_unit; +} + +SBFunction +SBAddress::GetFunction () +{ + SBFunction sb_function; + if (m_opaque_ap->IsValid()) + sb_function.reset(m_opaque_ap->CalculateSymbolContextFunction()); + return sb_function; +} + +SBBlock +SBAddress::GetBlock () +{ + SBBlock sb_block; + if (m_opaque_ap->IsValid()) + sb_block.SetPtr(m_opaque_ap->CalculateSymbolContextBlock()); + return sb_block; +} + +SBSymbol +SBAddress::GetSymbol () +{ + SBSymbol sb_symbol; + if (m_opaque_ap->IsValid()) + sb_symbol.reset(m_opaque_ap->CalculateSymbolContextSymbol()); + return sb_symbol; +} + +SBLineEntry +SBAddress::GetLineEntry () +{ + SBLineEntry sb_line_entry; + if (m_opaque_ap->IsValid()) + { + 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->IsValid()) + 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..dd4c80c --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp @@ -0,0 +1,800 @@ +//===-- 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/SBStringList.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/Debugger.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/SectionLoadList.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", + static_cast<void*>(m_opaque_sp.get())); + else + log->Printf ("SBBreakpoint(%p)::GetID () => %u", + static_cast<void*>(m_opaque_sp.get()), break_id); + } + + return break_id; +} + + +bool +SBBreakpoint::IsValid() const +{ + if (!m_opaque_sp) + return false; + else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID())) + return true; + else + return false; +} + +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)", + static_cast<void*>(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)", + static_cast<void*>(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)", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(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 ")", + static_cast<void*>(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, + static_cast<void*>(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)", + static_cast<void*>(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", + static_cast<void*>(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)", + static_cast<void*>(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", + static_cast<void*>(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)", + static_cast<void*>(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", + static_cast<void*>(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, + static_cast<void*>(m_opaque_sp.get()), + static_cast<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, + static_cast<void*>(m_opaque_sp.get()), + static_cast<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) + { + void *pointer = &callback; + log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)", + static_cast<void*>(m_opaque_sp.get()), + *static_cast<void**>(&pointer), static_cast<void*>(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); + } +} + +void +SBBreakpoint::SetScriptCallbackFunction (const char *callback_function_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)", + static_cast<void*>(m_opaque_sp.get()), + callback_function_name); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + BreakpointOptions *bp_options = m_opaque_sp->GetOptions(); + m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options, + callback_function_name); + } +} + +SBError +SBBreakpoint::SetScriptCallbackBody (const char *callback_body_text) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)", + static_cast<void*>(m_opaque_sp.get()), callback_body_text); + + SBError sb_error; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + BreakpointOptions *bp_options = m_opaque_sp->GetOptions(); + Error error = m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options, + callback_body_text); + sb_error.SetError(error); + } + else + sb_error.SetErrorString("invalid breakpoint"); + + return sb_error; +} + +bool +SBBreakpoint::AddName (const char *new_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::AddName (name=%s)", + static_cast<void*>(m_opaque_sp.get()), + new_name); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + Error error; // Think I'm just going to swallow the error here, it's probably more annoying to have to provide it. + return m_opaque_sp->AddName(new_name, error); + } + + return false; +} + +void +SBBreakpoint::RemoveName (const char *name_to_remove) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::RemoveName (name=%s)", + static_cast<void*>(m_opaque_sp.get()), + name_to_remove); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->RemoveName(name_to_remove); + } +} + +bool +SBBreakpoint::MatchesName (const char *name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::MatchesName (name=%s)", + static_cast<void*>(m_opaque_sp.get()), + name); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + return m_opaque_sp->MatchesName(name); + } + + return false; +} + +void +SBBreakpoint::GetNames (SBStringList &names) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::GetNames ()", + static_cast<void*>(m_opaque_sp.get())); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + std::vector<std::string> names_vec; + m_opaque_sp->GetNames(names_vec); + for (std::string name : names_vec) + { + names.AppendString (name.c_str()); + } + } +} + +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..4390e9a --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBBreakpointLocation.cpp @@ -0,0 +1,369 @@ +//===-- 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/Core/Debugger.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target/ThreadSpec.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)", + static_cast<void*>(break_loc_sp.get()), + static_cast<void*>(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::SetScriptCallbackFunction (const char *callback_function_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpointLocation(%p)::SetScriptCallbackFunction (callback=%s)", + static_cast<void*>(m_opaque_sp.get()), + callback_function_name); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + BreakpointOptions *bp_options = m_opaque_sp->GetLocationOptions(); + m_opaque_sp->GetBreakpoint().GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options, + callback_function_name); + } +} + +SBError +SBBreakpointLocation::SetScriptCallbackBody (const char *callback_body_text) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)", + static_cast<void*>(m_opaque_sp.get()), callback_body_text); + + SBError sb_error; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetBreakpoint().GetTarget().GetAPIMutex()); + BreakpointOptions *bp_options = m_opaque_sp->GetLocationOptions(); + Error error = m_opaque_sp->GetBreakpoint().GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options, + callback_body_text); + sb_error.SetError(error); + } + else + sb_error.SetErrorString("invalid breakpoint"); + + return sb_error; +} + +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", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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..73eac51 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBBroadcaster.cpp @@ -0,0 +1,202 @@ +//===-- 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, static_cast<void*>(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)", + static_cast<void*>(broadcaster), owns, + static_cast<void*>(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)", + static_cast<void*>(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)", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(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)", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(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..193d06e --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBCommandInterpreter.cpp @@ -0,0 +1,811 @@ +//===-- 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/SBExecutionContext.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; + +SBCommandInterpreterRunOptions::SBCommandInterpreterRunOptions() +{ + m_opaque_up.reset(new CommandInterpreterRunOptions()); +} + +SBCommandInterpreterRunOptions::~SBCommandInterpreterRunOptions() +{ + +} + +bool +SBCommandInterpreterRunOptions::GetStopOnContinue () const +{ + return m_opaque_up->GetStopOnContinue(); +} + +void +SBCommandInterpreterRunOptions::SetStopOnContinue (bool stop_on_continue) +{ + m_opaque_up->SetStopOnContinue(stop_on_continue); +} + +bool +SBCommandInterpreterRunOptions::GetStopOnError () const +{ + return m_opaque_up->GetStopOnError(); +} + +void +SBCommandInterpreterRunOptions::SetStopOnError (bool stop_on_error) +{ + m_opaque_up->SetStopOnError(stop_on_error); +} + +bool +SBCommandInterpreterRunOptions::GetStopOnCrash () const +{ + return m_opaque_up->GetStopOnCrash(); +} + +void +SBCommandInterpreterRunOptions::SetStopOnCrash (bool stop_on_crash) +{ + m_opaque_up->SetStopOnCrash(stop_on_crash); +} + +bool +SBCommandInterpreterRunOptions::GetEchoCommands () const +{ + return m_opaque_up->GetEchoCommands(); +} + +void +SBCommandInterpreterRunOptions::SetEchoCommands (bool echo_commands) +{ + m_opaque_up->SetEchoCommands(echo_commands); +} + +bool +SBCommandInterpreterRunOptions::GetPrintResults () const +{ + return m_opaque_up->GetPrintResults(); +} + +void +SBCommandInterpreterRunOptions::SetPrintResults (bool print_results) +{ + m_opaque_up->SetPrintResults(print_results); +} + +bool +SBCommandInterpreterRunOptions::GetAddToHistory () const +{ + return m_opaque_up->GetAddToHistory(); +} + +void +SBCommandInterpreterRunOptions::SetAddToHistory (bool add_to_history) +{ + m_opaque_up->SetAddToHistory(add_to_history); +} + +lldb_private::CommandInterpreterRunOptions * +SBCommandInterpreterRunOptions::get () const +{ + return m_opaque_up.get(); +} + +lldb_private::CommandInterpreterRunOptions & +SBCommandInterpreterRunOptions::ref () const +{ + return *m_opaque_up.get(); +} + +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)", + static_cast<void*>(interpreter), + static_cast<void*>(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; +} + +bool +SBCommandInterpreter::IsActive () +{ + if (m_opaque_ptr) + return m_opaque_ptr->IsActive (); + return false; +} + +const char * +SBCommandInterpreter::GetIOHandlerControlSequence(char ch) +{ + if (m_opaque_ptr) + return m_opaque_ptr->GetDebugger().GetTopIOHandlerControlSequence (ch).GetCString(); + return NULL; +} + +lldb::ReturnStatus +SBCommandInterpreter::HandleCommand (const char *command_line, SBCommandReturnObject &result, bool add_to_history) +{ + SBExecutionContext sb_exe_ctx; + return HandleCommand (command_line, sb_exe_ctx, result, add_to_history); +} + +lldb::ReturnStatus +SBCommandInterpreter::HandleCommand (const char *command_line, SBExecutionContext &override_context, 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)", + static_cast<void*>(m_opaque_ptr), command_line, + static_cast<void*>(result.get()), add_to_history); + + ExecutionContext ctx, *ctx_ptr; + if (override_context.get()) + { + ctx = override_context.get()->Lock(true); + ctx_ptr = &ctx; + } + else + ctx_ptr = nullptr; + + + result.Clear(); + if (command_line && m_opaque_ptr) + { + result.ref().SetInteractive(false); + m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref(), ctx_ptr); + } + 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", + static_cast<void*>(m_opaque_ptr), command_line, + static_cast<void*>(result.get()), sstr.GetData(), + add_to_history, result.GetStatus()); + } + + return result.GetStatus(); +} + +void +SBCommandInterpreter::HandleCommandsFromFile (lldb::SBFileSpec &file, + lldb::SBExecutionContext &override_context, + lldb::SBCommandInterpreterRunOptions &options, + lldb::SBCommandReturnObject result) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + { + SBStream s; + file.GetDescription (s); + log->Printf ("SBCommandInterpreter(%p)::HandleCommandsFromFile (file=\"%s\", SBCommandReturnObject(%p))", + static_cast<void*>(m_opaque_ptr), s.GetData(), + static_cast<void*>(result.get())); + } + + if (!m_opaque_ptr) + { + result->AppendError ("SBCommandInterpreter is not valid."); + result->SetStatus (eReturnStatusFailed); + return; + } + + if (!file.IsValid()) + { + SBStream s; + file.GetDescription (s); + result->AppendErrorWithFormat ("File is not valid: %s.", s.GetData()); + result->SetStatus (eReturnStatusFailed); + } + + FileSpec tmp_spec = file.ref(); + ExecutionContext ctx, *ctx_ptr; + if (override_context.get()) + { + ctx = override_context.get()->Lock(true); + ctx_ptr = &ctx; + } + else + ctx_ptr = nullptr; + + + m_opaque_ptr->HandleCommandsFromFile (tmp_spec, ctx_ptr, options.ref(), result.ref()); + +} + + +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 > static_cast<ptrdiff_t>(current_line_size) || + last_char - current_line > static_cast<ptrdiff_t>(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)", + static_cast<void*>(m_opaque_ptr), current_line, + static_cast<uint64_t>(cursor - current_line), + static_cast<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.", + static_cast<void*>(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)", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(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)", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(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))", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(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))", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(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)", + static_cast<void*>(m_opaque_ptr), static_cast<void*>(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); + +// these are the Pythonic implementations of the required callbacks +// these are scripting-language specific, which is why they belong here +// we still need to use function pointers to them instead of relying +// on linkage-time resolution because the SWIG stuff and this file +// get built at different times +extern "C" bool +LLDBSwigPythonBreakpointCallbackFunction (const char *python_function_name, + const char *session_dictionary_name, + const lldb::StackFrameSP& sb_frame, + const lldb::BreakpointLocationSP& sb_bp_loc); + +extern "C" bool +LLDBSwigPythonWatchpointCallbackFunction (const char *python_function_name, + const char *session_dictionary_name, + const lldb::StackFrameSP& sb_frame, + const lldb::WatchpointSP& sb_wp); + +extern "C" bool +LLDBSwigPythonCallTypeScript (const char *python_function_name, + void *session_dictionary, + const lldb::ValueObjectSP& valobj_sp, + void** pyfunct_wrapper, + const lldb::TypeSummaryOptionsSP& options_sp, + std::string& retval); + +extern "C" void* +LLDBSwigPythonCreateSyntheticProvider (const char *python_class_name, + const char *session_dictionary_name, + const lldb::ValueObjectSP& valobj_sp); + + +extern "C" void* +LLDBSwigPythonCreateScriptedThreadPlan (const char *python_class_name, + const char *session_dictionary_name, + const lldb::ThreadPlanSP& thread_plan_sp); + +extern "C" bool +LLDBSWIGPythonCallThreadPlan (void *implementor, + const char *method_name, + Event *event_sp, + bool &got_error); + +extern "C" uint32_t +LLDBSwigPython_CalculateNumChildren (void *implementor); + +extern "C" void * +LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx); + +extern "C" int +LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name); + +extern "C" void * +LLDBSWIGPython_CastPyObjectToSBValue (void* data); + +extern lldb::ValueObjectSP +LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data); + +extern "C" bool +LLDBSwigPython_UpdateSynthProviderInstance (void* implementor); + +extern "C" bool +LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor); + +extern "C" void * +LLDBSwigPython_GetValueSynthProviderInstance (void* implementor); + +extern "C" bool +LLDBSwigPythonCallCommand (const char *python_function_name, + const char *session_dictionary_name, + lldb::DebuggerSP& debugger, + const char* args, + lldb_private::CommandReturnObject &cmd_retobj, + lldb::ExecutionContextRefSP exe_ctx_ref_sp); + +extern "C" bool +LLDBSwigPythonCallModuleInit (const char *python_module_name, + const char *session_dictionary_name, + lldb::DebuggerSP& debugger); + +extern "C" void* +LLDBSWIGPythonCreateOSPlugin (const char *python_class_name, + const char *session_dictionary_name, + const lldb::ProcessSP& process_sp); + +extern "C" bool +LLDBSWIGPythonRunScriptKeywordProcess (const char* python_function_name, + const char* session_dictionary_name, + lldb::ProcessSP& process, + std::string& output); + +extern "C" bool +LLDBSWIGPythonRunScriptKeywordThread (const char* python_function_name, + const char* session_dictionary_name, + lldb::ThreadSP& thread, + std::string& output); + +extern "C" bool +LLDBSWIGPythonRunScriptKeywordTarget (const char* python_function_name, + const char* session_dictionary_name, + lldb::TargetSP& target, + std::string& output); + +extern "C" bool +LLDBSWIGPythonRunScriptKeywordFrame (const char* python_function_name, + const char* session_dictionary_name, + lldb::StackFrameSP& frame, + std::string& output); + +extern "C" bool +LLDBSWIGPythonRunScriptKeywordValue (const char* python_function_name, + const char* session_dictionary_name, + lldb::ValueObjectSP& value, + std::string& output); + +extern "C" void* +LLDBSWIGPython_GetDynamicSetting (void* module, + const char* setting, + const lldb::TargetSP& target_sp); + + +#endif + +void +SBCommandInterpreter::InitializeSWIG () +{ + static bool g_initialized = false; + if (!g_initialized) + { + g_initialized = true; +#ifndef LLDB_DISABLE_PYTHON + ScriptInterpreter::InitializeInterpreter (init_lldb, + LLDBSwigPythonBreakpointCallbackFunction, + LLDBSwigPythonWatchpointCallbackFunction, + LLDBSwigPythonCallTypeScript, + LLDBSwigPythonCreateSyntheticProvider, + LLDBSwigPython_CalculateNumChildren, + LLDBSwigPython_GetChildAtIndex, + LLDBSwigPython_GetIndexOfChildWithName, + LLDBSWIGPython_CastPyObjectToSBValue, + LLDBSWIGPython_GetValueObjectSPFromSBValue, + LLDBSwigPython_UpdateSynthProviderInstance, + LLDBSwigPython_MightHaveChildrenSynthProviderInstance, + LLDBSwigPython_GetValueSynthProviderInstance, + LLDBSwigPythonCallCommand, + LLDBSwigPythonCallModuleInit, + LLDBSWIGPythonCreateOSPlugin, + LLDBSWIGPythonRunScriptKeywordProcess, + LLDBSWIGPythonRunScriptKeywordThread, + LLDBSWIGPythonRunScriptKeywordTarget, + LLDBSWIGPythonRunScriptKeywordFrame, + LLDBSWIGPythonRunScriptKeywordValue, + LLDBSWIGPython_GetDynamicSetting, + LLDBSwigPythonCreateScriptedThreadPlan, + LLDBSWIGPythonCallThreadPlan); +#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..1ae2df7 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBCommandReturnObject.cpp @@ -0,0 +1,356 @@ +//===-- 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\"", + static_cast<void*>(m_opaque_ap.get()), + m_opaque_ap->GetOutputData()); + + return m_opaque_ap->GetOutputData(); + } + + if (log) + log->Printf ("SBCommandReturnObject(%p)::GetOutput () => NULL", + static_cast<void*>(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\"", + static_cast<void*>(m_opaque_ap.get()), + m_opaque_ap->GetErrorData()); + + return m_opaque_ap->GetErrorData(); + } + + if (log) + log->Printf ("SBCommandReturnObject(%p)::GetError () => NULL", + static_cast<void*>(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..956b6cf --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBCommunication.cpp @@ -0,0 +1,295 @@ +//===-- 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/Log.h" +#include "lldb/Host/ConnectionFileDescriptor.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, + static_cast<void*>(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(Connection::CreateDefaultConnection(url)); + 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", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(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)...", + static_cast<void*>(m_opaque), static_cast<void*>(dst), + static_cast<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, + static_cast<void*>(m_opaque), static_cast<void*>(dst), + static_cast<uint64_t>(dst_len), timeout_usec, + Communication::ConnectionStatusAsCString (status), + static_cast<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, + static_cast<void*>(m_opaque), static_cast<const void*>(src), + static_cast<uint64_t>(src_len), + Communication::ConnectionStatusAsCString (status), + static_cast<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", + static_cast<void*>(m_opaque), success); + + return success; +} + + +bool +SBCommunication::ReadThreadStop () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBCommunication(%p)::ReadThreadStop ()...", + static_cast<void*>(m_opaque)); + + bool success = false; + if (m_opaque) + success = m_opaque->StopReadThread (); + + if (log) + log->Printf ("SBCommunication(%p)::ReadThreadStop () => %i", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(m_opaque), + reinterpret_cast<void*>(reinterpret_cast<intptr_t>(callback)), + static_cast<void*>(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)", + static_cast<void*>(m_opaque), + static_cast<void*>(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..5d904ce --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBCompileUnit.cpp @@ -0,0 +1,295 @@ +//===-- 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'", + static_cast<void*>(m_opaque_ptr), idx, + static_cast<void*>(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", + static_cast<void*>(m_opaque_ptr), start_idx, line, + inline_file_spec + ? static_cast<const void*>(inline_file_spec->get()) + : NULL); + } + else + { + log->Printf ("SBCompileUnit(%p)::FindLineEntryIndex (start_idx=%u, line=%u, SBFileSpec(%p)) => %u", + static_cast<void*>(m_opaque_ptr), start_idx, line, + inline_file_spec + ? static_cast<const void*>(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'", + static_cast<void*>(m_opaque_ptr), idx, + static_cast<const void*>(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; +} + +lldb::LanguageType +SBCompileUnit::GetLanguage () +{ + if (m_opaque_ptr) + return m_opaque_ptr->GetLanguage(); + return lldb::eLanguageTypeUnknown; +} + +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..a585852 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBData.cpp @@ -0,0 +1,805 @@ +//===-- 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 <inttypes.h> // PRIu64 + +#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 () => " + "( %" PRIu64 " )", (uint64_t)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)", + static_cast<void*>(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)", static_cast<void*>(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)", static_cast<void*>(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)", static_cast<void*>(error.get()), offset, + reinterpret_cast<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)", static_cast<void*>(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)", static_cast<void*>(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)", static_cast<void*>(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 ")", static_cast<void*>(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)", static_cast<void*>(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)", static_cast<void*>(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)", static_cast<void*>(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 ")", static_cast<void*>(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)", + static_cast<void*>(error.get()), offset, + static_cast<const void*>(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=%" PRIu64 ") => " + "(%p)", static_cast<void*>(error.get()), offset, + static_cast<void*>(buf), static_cast<uint64_t>(size), + static_cast<void*>(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=%" PRIu64 ",endian=%d,addr_size=%c) => " + "(%p)", static_cast<void*>(error.get()), + static_cast<const void*>(buf), static_cast<uint64_t>(size), + endian, addr_size, static_cast<void*>(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)", + static_cast<void*>(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", + static_cast<const void*>(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", + static_cast<const void*>(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 = %" PRIu64 ") => " + "false", static_cast<void*>(array), + static_cast<uint64_t>(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 = %" PRIu64 ") => " + "true", static_cast<void*>(array), + static_cast<uint64_t>(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 = %" PRIu64 ") => " + "false", static_cast<void*>(array), + static_cast<uint64_t>(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 = %" PRIu64 ") => " + "true", static_cast<void*>(array), + static_cast<uint64_t>(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 = %" PRIu64 ") => " + "false", static_cast<void*>(array), + static_cast<uint64_t>(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 = %" PRIu64 ") => " + "true", static_cast<void*>(array), + static_cast<uint64_t>(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 = %" PRIu64 ") => " + "false", static_cast<void*>(array), + static_cast<uint64_t>(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 = %" PRIu64 ") => " + "true", static_cast<void*>(array), + static_cast<uint64_t>(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 = %" PRIu64 ") => " + "false", static_cast<void*>(array), + static_cast<uint64_t>(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 = %" PRIu64 ") => " + "true", static_cast<void*>(array), + static_cast<uint64_t>(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..a95f2ff --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp @@ -0,0 +1,1396 @@ +//===-- 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/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/Core/StreamFile.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" + +#include "llvm/Support/DynamicLibrary.h" + +using namespace lldb; +using namespace lldb_private; + + +SBInputReader::SBInputReader() +{ +} +SBInputReader::~SBInputReader() +{ +} + +SBError +SBInputReader::Initialize(lldb::SBDebugger& sb_debugger, unsigned long (*)(void*, lldb::SBInputReader*, lldb::InputReaderAction, char const*, unsigned long), void*, lldb::InputReaderGranularity, char const*, char const*, bool) +{ + return SBError(); +} + +void +SBInputReader::SetIsDone(bool) +{ +} +bool +SBInputReader::IsActive() const +{ + return false; +} + +static llvm::sys::DynamicLibrary +LoadPlugin (const lldb::DebuggerSP &debugger_sp, const FileSpec& spec, Error& error) +{ + llvm::sys::DynamicLibrary dynlib = llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str()); + if (dynlib.isValid()) + { + typedef bool (*LLDBCommandPluginInit) (lldb::SBDebugger& debugger); + + lldb::SBDebugger debugger_sb(debugger_sp); + // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) function. + // TODO: mangle this differently for your system - on OSX, the first underscore needs to be removed and the second one stays + LLDBCommandPluginInit init_func = (LLDBCommandPluginInit)dynlib.getAddressOfSymbol("_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); + if (init_func) + { + if (init_func(debugger_sb)) + return dynlib; + else + error.SetErrorString("plug-in refused to load (lldb::PluginInitialize(lldb::SBDebugger) returned false)"); + } + else + { + error.SetErrorString("plug-in is missing the required initialization: lldb::PluginInitialize(lldb::SBDebugger)"); + } + } + else + { + if (spec.Exists()) + error.SetErrorString("this file does not represent a loadable dylib"); + else + error.SetErrorString("no such file"); + } + return llvm::sys::DynamicLibrary(); +} + +void +SBDebugger::Initialize () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger::Initialize ()"); + + SBCommandInterpreter::InitializeSWIG (); + + Debugger::Initialize(LoadPlugin); +} + +void +SBDebugger::Terminate () +{ + Debugger::Terminate(); +} + +void +SBDebugger::Clear () +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBDebugger(%p)::Clear ()", + static_cast<void*>(m_opaque_sp.get())); + + if (m_opaque_sp) + m_opaque_sp->ClearIOHandlers (); + + 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; + + // Currently we have issues if this function is called simultaneously on two different + // threads. The issues mainly revolve around the fact that the lldb_private::FormatManager + // uses global collections and having two threads parsing the .lldbinit files can cause + // mayhem. So to get around this for now we need to use a mutex to prevent bad things + // from happening. + static Mutex g_mutex(Mutex::eMutexTypeRecursive); + Mutex::Locker locker(g_mutex); + + debugger.reset(Debugger::CreateInstance(callback, baton)); + + if (log) + { + SBStream sstr; + debugger.GetDescription (sstr); + log->Printf ("SBDebugger::Create () => SBDebugger(%p): %s", + static_cast<void*>(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", + static_cast<void*>(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)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(fh), transfer_ownership); + + if (m_opaque_sp) + m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership); +} + +FILE * +SBDebugger::GetInputFileHandle () +{ + if (m_opaque_sp) + { + StreamFileSP stream_file_sp (m_opaque_sp->GetInputFile()); + if (stream_file_sp) + return stream_file_sp->GetFile().GetStream(); + } + return NULL; +} + +FILE * +SBDebugger::GetOutputFileHandle () +{ + if (m_opaque_sp) + { + StreamFileSP stream_file_sp (m_opaque_sp->GetOutputFile()); + if (stream_file_sp) + return stream_file_sp->GetFile().GetStream(); + } + return NULL; +} + +FILE * +SBDebugger::GetErrorFileHandle () +{ + if (m_opaque_sp) + if (m_opaque_sp) + { + StreamFileSP stream_file_sp (m_opaque_sp->GetErrorFile()); + if (stream_file_sp) + return stream_file_sp->GetFile().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)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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 lldb_private::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)", + static_cast<void*>(m_opaque_sp.get()), filename, + target_triple, platform_name, add_dependent_modules, + sb_error.GetCString(), static_cast<void*>(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)", + static_cast<void*>(m_opaque_sp.get()), filename, + target_triple, static_cast<void*>(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)", + static_cast<void*>(m_opaque_sp.get()), filename, arch_cstr, + static_cast<void*>(target_sp.get())); + + return sb_target; +} + +SBTarget +SBDebugger::CreateTarget (const char *filename) +{ + 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, + NULL, + add_dependent_modules, + NULL, + 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)", + static_cast<void*>(m_opaque_sp.get()), filename, + static_cast<void*>(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", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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 (lldb::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", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(target_sp.get()), sstr.GetData()); + } +} + +SBPlatform +SBDebugger::GetSelectedPlatform() +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBPlatform sb_platform; + DebuggerSP debugger_sp(m_opaque_sp); + if (debugger_sp) + { + sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform()); + } + if (log) + log->Printf ("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(sb_platform.GetSP().get()), + sb_platform.GetName()); + return sb_platform; +} + +void +SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + DebuggerSP debugger_sp(m_opaque_sp); + if (debugger_sp) + { + debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP()); + } + + if (log) + log->Printf ("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(sb_platform.GetSP().get()), + sb_platform.GetName()); +} + +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 (); +} + +void +SBDebugger::PushInputReader (SBInputReader &reader) +{ +} + +void +SBDebugger::RunCommandInterpreter (bool auto_handle_events, + bool spawn_thread) +{ + if (m_opaque_sp) + { + CommandInterpreterRunOptions options; + + m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(auto_handle_events, + spawn_thread, + options); + } +} + +void +SBDebugger::RunCommandInterpreter (bool auto_handle_events, + bool spawn_thread, + SBCommandInterpreterRunOptions &options, + int &num_errors, + bool &quit_requested, + bool &stopped_for_crash) + +{ + if (m_opaque_sp) + { + CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); + interp.RunCommandInterpreter(auto_handle_events, spawn_thread, options.ref()); + num_errors = interp.GetNumErrors(); + quit_requested = interp.GetQuitRequested(); + stopped_for_crash = interp.GetStoppedForCrash(); + } +} + +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); + 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\"", + static_cast<void*>(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_cstr) +{ + SBError sb_error; + if (m_opaque_sp) + { + if (platform_name_cstr && platform_name_cstr[0]) + { + ConstString platform_name (platform_name_cstr); + PlatformSP platform_sp (Platform::Find (platform_name)); + + if (platform_sp) + { + // Already have a platform with this name, just select it + m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp); + } + else + { + // We don't have a platform by this name yet, create one + platform_sp = Platform::Create (platform_name, sb_error.ref()); + if (platform_sp) + { + // We created the platform, now append and select it + bool make_selected = true; + m_opaque_sp->GetPlatformList().Append (platform_sp, make_selected); + } + } + } + else + { + sb_error.ref().SetErrorString("invalid platform name"); + } + } + else + { + sb_error.ref().SetErrorString("invalid debugger"); + } + 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..8aea675 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBDeclaration.cpp @@ -0,0 +1,209 @@ +//===-- 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", + static_cast<void*>(m_opaque_ap.get()), + static_cast<const void*>(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", + static_cast<void*>(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..157997b --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBError.cpp @@ -0,0 +1,237 @@ +//===-- 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", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(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..c62c495 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBEvent.cpp @@ -0,0 +1,252 @@ +//===-- 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 (Event *event_ptr) : + m_event_sp (), + m_opaque_ptr (event_ptr) +{ +} + +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)", + static_cast<void*>(get()), event_type, sstr.GetData()); + else + log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x", + static_cast<void*>(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", + static_cast<void*>(get()), + static_cast<void*>(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\"", + static_cast<void*>(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/SBExecutionContext.cpp b/contrib/llvm/tools/lldb/source/API/SBExecutionContext.cpp new file mode 100644 index 0000000..dc20c60 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBExecutionContext.cpp @@ -0,0 +1,129 @@ +//===-- SBExecutionContext.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/SBExecutionContext.h" + +#include "lldb/API/SBTarget.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBThread.h" +#include "lldb/API/SBFrame.h" + +#include "lldb/Target/ExecutionContext.h" + +using namespace lldb; +using namespace lldb_private; + +SBExecutionContext::SBExecutionContext() : +m_exe_ctx_sp() +{ +} + +SBExecutionContext::SBExecutionContext (const lldb::SBExecutionContext &rhs) : +m_exe_ctx_sp(rhs.m_exe_ctx_sp) +{ +} + +SBExecutionContext::SBExecutionContext (lldb::ExecutionContextRefSP exe_ctx_ref_sp) : +m_exe_ctx_sp(exe_ctx_ref_sp) +{ +} + +SBExecutionContext::SBExecutionContext (const lldb::SBTarget &target) : +m_exe_ctx_sp(new ExecutionContextRef()) +{ + m_exe_ctx_sp->SetTargetSP(target.GetSP()); +} + +SBExecutionContext::SBExecutionContext (const lldb::SBProcess &process) : +m_exe_ctx_sp(new ExecutionContextRef()) +{ + m_exe_ctx_sp->SetProcessSP(process.GetSP()); +} + +SBExecutionContext::SBExecutionContext (lldb::SBThread thread) : +m_exe_ctx_sp(new ExecutionContextRef()) +{ + m_exe_ctx_sp->SetThreadPtr(thread.get()); +} + +SBExecutionContext::SBExecutionContext (const lldb::SBFrame &frame) : +m_exe_ctx_sp(new ExecutionContextRef()) +{ + m_exe_ctx_sp->SetFrameSP(frame.GetFrameSP()); +} + +SBExecutionContext::~SBExecutionContext() +{ +} + +const SBExecutionContext & +SBExecutionContext::operator = (const lldb::SBExecutionContext &rhs) +{ + m_exe_ctx_sp = rhs.m_exe_ctx_sp; + return *this; +} + +ExecutionContextRef * +SBExecutionContext::get () const +{ + return m_exe_ctx_sp.get(); +} + +SBTarget +SBExecutionContext::GetTarget () const +{ + SBTarget sb_target; + if (m_exe_ctx_sp) + { + TargetSP target_sp(m_exe_ctx_sp->GetTargetSP()); + if (target_sp) + sb_target.SetSP(target_sp); + } + return sb_target; +} + +SBProcess +SBExecutionContext::GetProcess () const +{ + SBProcess sb_process; + if (m_exe_ctx_sp) + { + ProcessSP process_sp(m_exe_ctx_sp->GetProcessSP()); + if (process_sp) + sb_process.SetSP(process_sp); + } + return sb_process; +} + +SBThread +SBExecutionContext::GetThread () const +{ + SBThread sb_thread; + if (m_exe_ctx_sp) + { + ThreadSP thread_sp(m_exe_ctx_sp->GetThreadSP()); + if (thread_sp) + sb_thread.SetThread(thread_sp); + } + return sb_thread; +} + +SBFrame +SBExecutionContext::GetFrame () const +{ + SBFrame sb_frame; + if (m_exe_ctx_sp) + { + StackFrameSP frame_sp(m_exe_ctx_sp->GetFrameSP()); + if (frame_sp) + sb_frame.SetFrameSP(frame_sp); + } + return sb_frame; +} + 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..448ff4c --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBExpressionOptions.cpp @@ -0,0 +1,199 @@ +//===-- 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); +} + +uint32_t +SBExpressionOptions::GetOneThreadTimeoutInMicroSeconds () const +{ + return m_opaque_ap->GetOneThreadTimeoutUsec (); +} + +void +SBExpressionOptions::SetOneThreadTimeoutInMicroSeconds (uint32_t timeout) +{ + m_opaque_ap->SetOneThreadTimeoutUsec (timeout); +} + +bool +SBExpressionOptions::GetTryAllThreads () const +{ + return m_opaque_ap->GetTryAllThreads (); +} + +void +SBExpressionOptions::SetTryAllThreads (bool run_others) +{ + m_opaque_ap->SetTryAllThreads (run_others); +} + +bool +SBExpressionOptions::GetStopOthers () const +{ + return m_opaque_ap->GetStopOthers (); +} + +void +SBExpressionOptions::SetStopOthers (bool run_others) +{ + m_opaque_ap->SetStopOthers (run_others); +} + +bool +SBExpressionOptions::GetTrapExceptions () const +{ + return m_opaque_ap->GetTrapExceptions (); +} + +void +SBExpressionOptions::SetTrapExceptions (bool trap_exceptions) +{ + m_opaque_ap->SetTrapExceptions (trap_exceptions); +} + +void +SBExpressionOptions::SetLanguage (lldb::LanguageType language) +{ + m_opaque_ap->SetLanguage(language); +} + +void +SBExpressionOptions::SetCancelCallback (lldb::ExpressionCancelCallback callback, void *baton) +{ + m_opaque_ap->SetCancelCallback (callback, baton); +} + +bool +SBExpressionOptions::GetGenerateDebugInfo () +{ + return m_opaque_ap->GetGenerateDebugInfo(); +} + +void +SBExpressionOptions::SetGenerateDebugInfo (bool b) +{ + return m_opaque_ap->SetGenerateDebugInfo(b); +} + +bool +SBExpressionOptions::GetSuppressPersistentResult () +{ + return m_opaque_ap->GetResultIsInternal (); +} + +void +SBExpressionOptions::SetSuppressPersistentResult (bool b) +{ + return m_opaque_ap->SetResultIsInternal (b); +} + + +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..8d63fc5 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBFileSpec.cpp @@ -0,0 +1,213 @@ +//===-- 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 <inttypes.h> // PRIu64 +#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" + +#include "llvm/ADT/SmallString.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)) +{ +} + +// Deprecated!!! +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->operator bool(); +} + +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", + static_cast<void*>(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) +{ + llvm::SmallString<64> result(src_path); + lldb_private::FileSpec::Resolve (result); + size_t result_length = std::min(dst_len-1, result.size()); + ::strncpy(dst_path, result.c_str(), result_length + 1); + return result_length; +} + +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\"", + static_cast<void*>(m_opaque_ap.get()), s); + else + log->Printf ("SBFileSpec(%p)::GetFilename () => NULL", + static_cast<void*>(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\"", + static_cast<void*>(m_opaque_ap.get()), s); + else + log->Printf ("SBFileSpec(%p)::GetDirectory () => NULL", + static_cast<void*>(m_opaque_ap.get())); + } + return s; +} + +void +SBFileSpec::SetFilename(const char *filename) +{ + if (filename && filename[0]) + m_opaque_ap->GetFilename().SetCString(filename); + else + m_opaque_ap->GetFilename().Clear(); +} + +void +SBFileSpec::SetDirectory(const char *directory) +{ + if (directory && directory[0]) + m_opaque_ap->GetDirectory().SetCString(directory); + else + m_opaque_ap->GetDirectory().Clear(); +} + +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", + static_cast<void*>(m_opaque_ap.get()), result, dst_path, + static_cast<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..a457a75 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBFileSpecList.cpp @@ -0,0 +1,143 @@ +//===-- 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)", + static_cast<void*>(rhs.m_opaque_ap.get()), + static_cast<void*>(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..325f40f --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBFrame.cpp @@ -0,0 +1,1541 @@ +//===-- 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", + static_cast<void*>(lldb_object_sp.get()), + static_cast<void*>(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)", + static_cast<void*>(frame), resolve_scope, + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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", + static_cast<void*>(frame)); + } + } + if (log) + log->Printf ("SBFrame(%p)::GetBlock () => SBBlock(%p)", + static_cast<void*>(frame), + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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", + static_cast<void*>(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, + static_cast<void*>(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", + static_cast<void*>(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, + static_cast<void*>(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, + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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)", + static_cast<void*>(frame), name, + static_cast<void*>(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) + { + VariableList variable_list; + + switch (value_type) + { + case eValueTypeVariableGlobal: // global variable + case eValueTypeVariableStatic: // static variable + case eValueTypeVariableArgument: // function argument variables + case eValueTypeVariableLocal: // function local variables + { + 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)) + { + if (value_type == eValueTypeVariableGlobal) + { + const bool get_file_globals = true; + VariableList* frame_vars = frame->GetVariableList(get_file_globals); + if (frame_vars) + frame_vars->AppendVariablesIfUnique(variable_list); + } + ConstString const_name(name); + VariableSP variable_sp(variable_list.FindVariable(const_name,value_type)); + if (variable_sp) + { + 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)", + static_cast<void*>(frame), name, value_type, + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetFramePtr()), + static_cast<void*>(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", + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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)", + static_cast<void*>(frame), + static_cast<void*>(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)); + + ExpressionResults exe_results = eExpressionSetupError; + 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) + { + if (target->GetDisplayExpressionsInCrashlogs()) + { + 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()); + } + + exe_results = target->EvaluateExpression (expr, + frame, + expr_value_sp, + options.ref()); + expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue()); + + if (target->GetDisplayExpressionsInCrashlogs()) + Host::SetCrashDescription (NULL); + } + 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)", + static_cast<void*>(frame), expr, + static_cast<void*>(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..bf5e918 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBFunction.cpp @@ -0,0 +1,241 @@ +//===-- 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\"", + static_cast<void*>(m_opaque_ptr), cstr); + else + log->Printf ("SBFunction(%p)::GetName () => NULL", + static_cast<void*>(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\"", + static_cast<void*>(m_opaque_ptr), cstr); + else + log->Printf ("SBFunction(%p)::GetMangledName () => NULL", + static_cast<void*>(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) + { + const bool prefer_file_cache = false; + sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture(), + NULL, + flavor, + exe_ctx, + m_opaque_ptr->GetAddressRange(), + prefer_file_cache)); + } + } + 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; +} + +lldb::LanguageType +SBFunction::GetLanguage () +{ + if (m_opaque_ptr) + { + if (m_opaque_ptr->GetCompileUnit()) + return m_opaque_ptr->GetCompileUnit()->GetLanguage(); + } + return lldb::eLanguageTypeUnknown; +} + + 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..008ca4d --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBHostOS.cpp @@ -0,0 +1,125 @@ +//===-- 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" +#include "lldb/Host/HostInfo.h" +#include "lldb/Host/HostNativeThread.h" +#include "lldb/Host/HostThread.h" +#include "lldb/Host/ThreadLauncher.h" + +using namespace lldb; +using namespace lldb_private; + + + +SBFileSpec +SBHostOS::GetProgramFileSpec () +{ + SBFileSpec sb_filespec; + sb_filespec.SetFileSpec(HostInfo::GetProgramFileSpec()); + return sb_filespec; +} + +SBFileSpec +SBHostOS::GetLLDBPythonPath () +{ + SBFileSpec sb_lldb_python_filespec; + FileSpec lldb_python_spec; + if (HostInfo::GetLLDBPath(ePathTypePythonDir, lldb_python_spec)) + { + sb_lldb_python_filespec.SetFileSpec (lldb_python_spec); + } + return sb_lldb_python_filespec; +} + + +SBFileSpec +SBHostOS::GetLLDBPath (lldb::PathType path_type) +{ + SBFileSpec sb_fspec; + FileSpec fspec; + if (HostInfo::GetLLDBPath(path_type, fspec)) + sb_fspec.SetFileSpec (fspec); + return sb_fspec; +} + +lldb::thread_t +SBHostOS::ThreadCreate +( + const char *name, + lldb::thread_func_t thread_function, + 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, reinterpret_cast<void*>(reinterpret_cast<intptr_t>(thread_function)), + static_cast<void*>(thread_arg), + static_cast<void*>(error_ptr)); + + // FIXME: You should log the return value? + + HostThread thread(ThreadLauncher::LaunchThread(name, thread_function, thread_arg, error_ptr ? error_ptr->get() : NULL)); + return thread.Release(); +} + +void +SBHostOS::ThreadCreated (const char *name) +{ +} + +bool +SBHostOS::ThreadCancel (lldb::thread_t thread, SBError *error_ptr) +{ + Error error; + HostThread host_thread(thread); + error = host_thread.Cancel(); + if (error_ptr) + error_ptr->SetError(error); + host_thread.Release(); + return error.Success(); +} + +bool +SBHostOS::ThreadDetach (lldb::thread_t thread, SBError *error_ptr) +{ + Error error; +#if defined(_WIN32) + if (error_ptr) + error_ptr->SetErrorString("ThreadDetach is not supported on this platform"); +#else + HostThread host_thread(thread); + error = host_thread.GetNativeThread().Detach(); + if (error_ptr) + error_ptr->SetError(error); + host_thread.Release(); +#endif + return error.Success(); +} + +bool +SBHostOS::ThreadJoin (lldb::thread_t thread, lldb::thread_result_t *result, SBError *error_ptr) +{ + Error error; + HostThread host_thread(thread); + error = host_thread.Join(result); + if (error_ptr) + error_ptr->SetError(error); + host_thread.Release(); + return error.Success(); +} + + 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..eccc4e2 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBInstruction.cpp @@ -0,0 +1,261 @@ +//===-- 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/Module.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) + { + SymbolContext sc; + const Address &addr = m_opaque_sp->GetAddress(); + ModuleSP module_sp (addr.GetModule()); + if (module_sp) + module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); + // Use the "ref()" instead of the "get()" accessor in case the SBStream + // didn't have a stream already created, one will get created... + const char *disassemble_format = "${addr-file-or-load}: "; + m_opaque_sp->Dump (&s.ref(), 0, true, false, NULL, &sc, NULL, disassemble_format); + return true; + } + return false; +} + +void +SBInstruction::Print (FILE *out) +{ + if (out == NULL) + return; + + if (m_opaque_sp) + { + SymbolContext sc; + const Address &addr = m_opaque_sp->GetAddress(); + ModuleSP module_sp (addr.GetModule()); + if (module_sp) + module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); + StreamFile out_stream (out, false); + const char *disassemble_format = "${addr-file-or-load}: "; + m_opaque_sp->Dump (&out_stream, 0, true, false, NULL, &sc, NULL, disassemble_format); + } +} + +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..31585b3 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBInstructionList.cpp @@ -0,0 +1,146 @@ +//===-- 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/Module.h" +#include "lldb/Core/Stream.h" +#include "lldb/Symbol/SymbolContext.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(); + const char *disassemble_format = "${addr-file-or-load}: "; + SymbolContext sc; + SymbolContext prev_sc; + for (size_t i=0; i<num_instructions; ++i) + { + Instruction *inst = m_opaque_sp->GetInstructionList().GetInstructionAtIndex (i).get(); + if (inst == NULL) + break; + + const Address &addr = inst->GetAddress(); + prev_sc = sc; + ModuleSP module_sp (addr.GetModule()); + if (module_sp) + { + module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc); + } + + inst->Dump (&sref, max_opcode_byte_size, true, false, NULL, &sc, &prev_sc, disassemble_format); + 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..833eea3 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBLineEntry.cpp @@ -0,0 +1,254 @@ +//===-- 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", + static_cast<void*>(m_opaque_ap.get()), + static_cast<void*>(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", + static_cast<void*>(m_opaque_ap.get()), + static_cast<void*>(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", + static_cast<void*>(m_opaque_ap.get()), + static_cast<const void*>(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", + static_cast<void*>(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..8731873 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBListener.cpp @@ -0,0 +1,451 @@ +//===-- 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, static_cast<void*>(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 (const lldb::ListenerSP &listener_sp) : + m_opaque_sp (listener_sp), + m_opaque_ptr (listener_sp.get()) +{ +} + +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", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(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", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(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))...", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(event.get())); + } + else + { + log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p))...", + static_cast<void*>(m_opaque_ptr), timeout_secs, + static_cast<void*>(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", + static_cast<void*>(m_opaque_ptr), + static_cast<void*>(event.get()), success); + } + else + { + log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p)) => %i", + static_cast<void*>(m_opaque_ptr), timeout_secs, + static_cast<void*>(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..0d7dda1 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBModule.cpp @@ -0,0 +1,692 @@ +//===-- 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, true, 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)", + static_cast<void*>(module_sp.get()), + static_cast<const void*>(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)", + static_cast<void*>(module_sp.get()), + static_cast<const void*>(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", + static_cast<void*>(module_sp.get()), + static_cast<const void*>(platform_file.get()), + platform_file->GetPath().c_str(), result); + return result; +} + +lldb::SBFileSpec +SBModule::GetRemoteInstallFileSpec () +{ + SBFileSpec sb_file_spec; + ModuleSP module_sp (GetSP ()); + if (module_sp) + sb_file_spec.SetFileSpec (module_sp->GetRemoteInstallFileSpec()); + return sb_file_spec; +} + +bool +SBModule::SetRemoteInstallFileSpec (lldb::SBFileSpec &file) +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + module_sp->SetRemoteInstallFileSpec(file.ref()); + return true; + } + return false; +} + + +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", + static_cast<void*>(module_sp.get()), s.GetData()); + } + else + log->Printf ("SBModule(%p)::GetUUIDBytes () => NULL", + static_cast<void*>(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_string_buffer[sizeof (uuid_string_buffer) - 1] = '\0'; + 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", + static_cast<void*>(module_sp.get()), s.GetData()); + } + else + log->Printf ("SBModule(%p)::GetUUIDString () => NULL", + static_cast<void*>(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::SBType +SBModule::GetTypeByID (lldb::user_id_t uid) +{ + ModuleSP module_sp (GetSP ()); + if (module_sp) + { + SymbolVendor* vendor = module_sp->GetSymbolVendor(); + if (vendor) + { + Type *type_ptr = vendor->ResolveTypeUID(uid); + if (type_ptr) + return SBType(type_ptr->shared_from_this()); + } + } + return SBType(); +} + +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..17c83ab --- /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->operator bool(); +} + +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/SBPlatform.cpp b/contrib/llvm/tools/lldb/source/API/SBPlatform.cpp new file mode 100644 index 0000000..d3e769a --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBPlatform.cpp @@ -0,0 +1,633 @@ +//===-- SBPlatform.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/SBPlatform.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBFileSpec.h" +#include "lldb/Core/ArchSpec.h" +#include "lldb/Core/Error.h" +#include "lldb/Host/File.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Platform.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// PlatformConnectOptions +//---------------------------------------------------------------------- +struct PlatformConnectOptions { + PlatformConnectOptions(const char *url = NULL) : + m_url(), + m_rsync_options(), + m_rsync_remote_path_prefix(), + m_rsync_enabled(false), + m_rsync_omit_hostname_from_remote_path(false), + m_local_cache_directory () + { + if (url && url[0]) + m_url = url; + } + + ~PlatformConnectOptions() + { + } + + std::string m_url; + std::string m_rsync_options; + std::string m_rsync_remote_path_prefix; + bool m_rsync_enabled; + bool m_rsync_omit_hostname_from_remote_path; + ConstString m_local_cache_directory; +}; + +//---------------------------------------------------------------------- +// PlatformShellCommand +//---------------------------------------------------------------------- +struct PlatformShellCommand { + PlatformShellCommand(const char *shell_command = NULL) : + m_command(), + m_working_dir(), + m_status(0), + m_signo(0), + m_timeout_sec(UINT32_MAX) + { + if (shell_command && shell_command[0]) + m_command = shell_command; + } + + ~PlatformShellCommand() + { + } + + std::string m_command; + std::string m_working_dir; + std::string m_output; + int m_status; + int m_signo; + uint32_t m_timeout_sec; +}; +//---------------------------------------------------------------------- +// SBPlatformConnectOptions +//---------------------------------------------------------------------- +SBPlatformConnectOptions::SBPlatformConnectOptions (const char *url) : + m_opaque_ptr(new PlatformConnectOptions(url)) +{ + +} + +SBPlatformConnectOptions::SBPlatformConnectOptions(const SBPlatformConnectOptions &rhs) : + m_opaque_ptr(new PlatformConnectOptions()) +{ + *m_opaque_ptr = *rhs.m_opaque_ptr; +} + +SBPlatformConnectOptions::~SBPlatformConnectOptions () +{ + delete m_opaque_ptr; +} + +void +SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) +{ + *m_opaque_ptr = *rhs.m_opaque_ptr; +} + +const char * +SBPlatformConnectOptions::GetURL() +{ + if (m_opaque_ptr->m_url.empty()) + return NULL; + return m_opaque_ptr->m_url.c_str(); +} + +void +SBPlatformConnectOptions::SetURL(const char *url) +{ + if (url && url[0]) + m_opaque_ptr->m_url = url; + else + m_opaque_ptr->m_url.clear(); +} + +bool +SBPlatformConnectOptions::GetRsyncEnabled() +{ + return m_opaque_ptr->m_rsync_enabled; +} + +void +SBPlatformConnectOptions::EnableRsync (const char *options, + const char *remote_path_prefix, + bool omit_hostname_from_remote_path) +{ + m_opaque_ptr->m_rsync_enabled = true; + m_opaque_ptr->m_rsync_omit_hostname_from_remote_path = omit_hostname_from_remote_path; + if (remote_path_prefix && remote_path_prefix[0]) + m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix; + else + m_opaque_ptr->m_rsync_remote_path_prefix.clear(); + + if (options && options[0]) + m_opaque_ptr->m_rsync_options = options; + else + m_opaque_ptr->m_rsync_options.clear(); + +} + +void +SBPlatformConnectOptions::DisableRsync () +{ + m_opaque_ptr->m_rsync_enabled = false; +} + +const char * +SBPlatformConnectOptions::GetLocalCacheDirectory() +{ + return m_opaque_ptr->m_local_cache_directory.GetCString(); +} + +void +SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) +{ + if (path && path[0]) + m_opaque_ptr->m_local_cache_directory.SetCString(path); + else + m_opaque_ptr->m_local_cache_directory = ConstString(); +} + +//---------------------------------------------------------------------- +// SBPlatformShellCommand +//---------------------------------------------------------------------- +SBPlatformShellCommand::SBPlatformShellCommand (const char *shell_command) : + m_opaque_ptr(new PlatformShellCommand(shell_command)) +{ +} + +SBPlatformShellCommand::SBPlatformShellCommand (const SBPlatformShellCommand &rhs) : + m_opaque_ptr(new PlatformShellCommand()) +{ + *m_opaque_ptr = *rhs.m_opaque_ptr; +} + +SBPlatformShellCommand::~SBPlatformShellCommand() +{ + delete m_opaque_ptr; +} + +void +SBPlatformShellCommand::Clear() +{ + m_opaque_ptr->m_output = std::move(std::string()); + m_opaque_ptr->m_status = 0; + m_opaque_ptr->m_signo = 0; +} + +const char * +SBPlatformShellCommand::GetCommand() +{ + if (m_opaque_ptr->m_command.empty()) + return NULL; + return m_opaque_ptr->m_command.c_str(); +} + +void +SBPlatformShellCommand::SetCommand(const char *shell_command) +{ + if (shell_command && shell_command[0]) + m_opaque_ptr->m_command = shell_command; + else + m_opaque_ptr->m_command.clear(); +} + +const char * +SBPlatformShellCommand::GetWorkingDirectory () +{ + if (m_opaque_ptr->m_working_dir.empty()) + return NULL; + return m_opaque_ptr->m_working_dir.c_str(); +} + +void +SBPlatformShellCommand::SetWorkingDirectory (const char *path) +{ + if (path && path[0]) + m_opaque_ptr->m_working_dir = path; + else + m_opaque_ptr->m_working_dir.clear(); +} + +uint32_t +SBPlatformShellCommand::GetTimeoutSeconds () +{ + return m_opaque_ptr->m_timeout_sec; +} + +void +SBPlatformShellCommand::SetTimeoutSeconds (uint32_t sec) +{ + m_opaque_ptr->m_timeout_sec = sec; +} + +int +SBPlatformShellCommand::GetSignal () +{ + return m_opaque_ptr->m_signo; +} + +int +SBPlatformShellCommand::GetStatus () +{ + return m_opaque_ptr->m_status; +} + +const char * +SBPlatformShellCommand::GetOutput () +{ + if (m_opaque_ptr->m_output.empty()) + return NULL; + return m_opaque_ptr->m_output.c_str(); +} + +//---------------------------------------------------------------------- +// SBPlatform +//---------------------------------------------------------------------- +SBPlatform::SBPlatform () : + m_opaque_sp () +{ + +} + +SBPlatform::SBPlatform (const char *platform_name) : + m_opaque_sp () +{ + Error error; + if (platform_name && platform_name[0]) + m_opaque_sp = Platform::Create (ConstString(platform_name), error); +} + +SBPlatform::~SBPlatform() +{ +} + +bool +SBPlatform::IsValid () const +{ + return m_opaque_sp.get() != NULL; +} + +void +SBPlatform::Clear () +{ + m_opaque_sp.reset(); +} + +const char * +SBPlatform::GetName () +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + return platform_sp->GetName().GetCString(); + return NULL; +} + +lldb::PlatformSP +SBPlatform::GetSP () const +{ + return m_opaque_sp; +} + +void +SBPlatform::SetSP (const lldb::PlatformSP& platform_sp) +{ + m_opaque_sp = platform_sp; +} + +const char * +SBPlatform::GetWorkingDirectory() +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + return platform_sp->GetWorkingDirectory().GetCString(); + return NULL; +} + +bool +SBPlatform::SetWorkingDirectory(const char *path) +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + if (path) + platform_sp->SetWorkingDirectory(ConstString(path)); + else + platform_sp->SetWorkingDirectory(ConstString()); + return true; + } + return false; +} + +SBError +SBPlatform::ConnectRemote (SBPlatformConnectOptions &connect_options) +{ + SBError sb_error; + PlatformSP platform_sp(GetSP()); + if (platform_sp && connect_options.GetURL()) + { + Args args; + args.AppendArgument(connect_options.GetURL()); + sb_error.ref() = platform_sp->ConnectRemote(args); + } + else + { + sb_error.SetErrorString("invalid platform"); + } + return sb_error; +} + +void +SBPlatform::DisconnectRemote () +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + platform_sp->DisconnectRemote(); +} + +bool +SBPlatform::IsConnected() +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + platform_sp->IsConnected(); + return false; +} + +const char * +SBPlatform::GetTriple() +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + ArchSpec arch(platform_sp->GetRemoteSystemArchitecture()); + if (arch.IsValid()) + { + // Const-ify the string so we don't need to worry about the lifetime of the string + return ConstString(arch.GetTriple().getTriple().c_str()).GetCString(); + } + } + return NULL; +} + +const char * +SBPlatform::GetOSBuild() +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + std::string s; + if (platform_sp->GetOSBuildString(s)) + { + if (!s.empty()) + { + // Const-ify the string so we don't need to worry about the lifetime of the string + return ConstString(s.c_str()).GetCString(); + } + } + } + return NULL; +} + +const char * +SBPlatform::GetOSDescription() +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + std::string s; + if (platform_sp->GetOSKernelDescription(s)) + { + if (!s.empty()) + { + // Const-ify the string so we don't need to worry about the lifetime of the string + return ConstString(s.c_str()).GetCString(); + } + } + } + return NULL; +} + +const char * +SBPlatform::GetHostname () +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + return platform_sp->GetHostname(); + return NULL; +} + +uint32_t +SBPlatform::GetOSMajorVersion () +{ + uint32_t major, minor, update; + PlatformSP platform_sp(GetSP()); + if (platform_sp && platform_sp->GetOSVersion(major, minor, update)) + return major; + return UINT32_MAX; + +} + +uint32_t +SBPlatform::GetOSMinorVersion () +{ + uint32_t major, minor, update; + PlatformSP platform_sp(GetSP()); + if (platform_sp && platform_sp->GetOSVersion(major, minor, update)) + return minor; + return UINT32_MAX; +} + +uint32_t +SBPlatform::GetOSUpdateVersion () +{ + uint32_t major, minor, update; + PlatformSP platform_sp(GetSP()); + if (platform_sp && platform_sp->GetOSVersion(major, minor, update)) + return update; + return UINT32_MAX; +} + +SBError +SBPlatform::Get (SBFileSpec &src, + SBFileSpec &dst) +{ + SBError sb_error; + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref()); + } + else + { + sb_error.SetErrorString("invalid platform"); + } + return sb_error; +} + +SBError +SBPlatform::Put (SBFileSpec &src, + SBFileSpec &dst) +{ + SBError sb_error; + + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + if (src.Exists()) + { + uint32_t permissions = src.ref().GetPermissions(); + if (permissions == 0) + { + if (src.ref().GetFileType() == FileSpec::eFileTypeDirectory) + permissions = eFilePermissionsDirectoryDefault; + else + permissions = eFilePermissionsFileDefault; + } + + sb_error.ref() = platform_sp->PutFile(src.ref(), + dst.ref(), + permissions); + } + else + { + sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str()); + } + } + else + { + sb_error.SetErrorString("invalid platform"); + } + return sb_error; +} + +SBError +SBPlatform::Install (SBFileSpec &src, + SBFileSpec &dst) +{ + SBError sb_error; + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + if (src.Exists()) + { + sb_error.ref() = platform_sp->Install(src.ref(), dst.ref()); + } + else + { + sb_error.ref().SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str()); + } + } + else + { + sb_error.SetErrorString("invalid platform"); + } + return sb_error; +} + + +SBError +SBPlatform::Run (SBPlatformShellCommand &shell_command) +{ + SBError sb_error; + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + if (platform_sp->IsConnected()) + { + const char *command = shell_command.GetCommand(); + if (command) + { + const char *working_dir = shell_command.GetWorkingDirectory(); + if (working_dir == NULL) + { + working_dir = platform_sp->GetWorkingDirectory().GetCString(); + if (working_dir) + shell_command.SetWorkingDirectory(working_dir); + } + sb_error.ref() = platform_sp->RunShellCommand(command, + working_dir, + &shell_command.m_opaque_ptr->m_status, + &shell_command.m_opaque_ptr->m_signo, + &shell_command.m_opaque_ptr->m_output, + shell_command.m_opaque_ptr->m_timeout_sec); + } + else + { + sb_error.SetErrorString("invalid shell command (empty)"); + } + } + else + { + sb_error.SetErrorString("not connected"); + } + } + else + { + sb_error.SetErrorString("invalid platform"); + } + return sb_error; +} + +SBError +SBPlatform::MakeDirectory (const char *path, uint32_t file_permissions) +{ + SBError sb_error; + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + sb_error.ref() = platform_sp->MakeDirectory(path, file_permissions); + } + else + { + sb_error.SetErrorString("invalid platform"); + } + return sb_error; +} + +uint32_t +SBPlatform::GetFilePermissions (const char *path) +{ + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + uint32_t file_permissions = 0; + platform_sp->GetFilePermissions(path, file_permissions); + return file_permissions; + } + return 0; + +} + +SBError +SBPlatform::SetFilePermissions (const char *path, uint32_t file_permissions) +{ + SBError sb_error; + PlatformSP platform_sp(GetSP()); + if (platform_sp) + { + sb_error.ref() = platform_sp->SetFilePermissions(path, file_permissions); + } + else + { + sb_error.SetErrorString("invalid platform"); + } + return sb_error; + +} + 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..9a0b23b --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBProcess.cpp @@ -0,0 +1,1403 @@ +//===-- 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" + +// C Includes +#include <inttypes.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/SystemRuntime.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/SBThreadCollection.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" +#include "lldb/API/SBUnixSignals.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))...", + static_cast<void*>(m_opaque_wp.lock().get()), + static_cast<void*>(argv), static_cast<void*>(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, + static_cast<void*>(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", + static_cast<void*>(process_sp.get()), + static_cast<void*>(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", + static_cast<void*>(process_sp.get()), pid, + static_cast<void*>(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", + static_cast<void*>(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)", + static_cast<void*>(process_sp.get()), + static_cast<void*>(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)", + static_cast<void*>(process_sp.get()), tid, context, + static_cast<void*>(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)", + static_cast<void*>(process_sp.get()), + static_cast<void*>(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=%" PRIu64 ") => %" PRIu64, + static_cast<void*>(process_sp.get()), src, + static_cast<uint64_t>(src_len), + static_cast<uint64_t>(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, + static_cast<void*>(process_sp.get()), + static_cast<int>(bytes_read), dst, + static_cast<uint64_t>(dst_len), + static_cast<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, + static_cast<void*>(process_sp.get()), + static_cast<int>(bytes_read), dst, + static_cast<uint64_t>(dst_len), + static_cast<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, + static_cast<void*>(process_sp.get()), + static_cast<int>(bytes_read), dst, + static_cast<uint64_t>(dst_len), + static_cast<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", + static_cast<void*>(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", + static_cast<void*>(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)", + static_cast<void*>(process_sp.get()), + static_cast<uint32_t>(index), + static_cast<void*>(thread_sp.get())); + + return sb_thread; +} + +uint32_t +SBProcess::GetNumQueues () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num_queues = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + num_queues = process_sp->GetQueueList().GetSize(); + } + + if (log) + log->Printf ("SBProcess(%p)::GetNumQueues () => %d", + static_cast<void*>(process_sp.get()), num_queues); + + return num_queues; +} + +SBQueue +SBProcess::GetQueueAtIndex (size_t index) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBQueue sb_queue; + QueueSP queue_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index); + sb_queue.SetQueue (queue_sp); + } + + if (log) + log->Printf ("SBProcess(%p)::GetQueueAtIndex (index=%d) => SBQueue(%p)", + static_cast<void*>(process_sp.get()), + static_cast<uint32_t>(index), + static_cast<void*>(queue_sp.get())); + + return sb_queue; +} + + +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", + static_cast<void*>(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)", + static_cast<void*>(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", + static_cast<void*>(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, + static_cast<void*>(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, + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(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 ()...", + static_cast<void*>(process_sp.get())); + + if (process_sp) + { + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + + if (process_sp->GetTarget().GetDebugger().GetAsyncExecution ()) + sb_error.ref() = process_sp->Resume (); + else + sb_error.ref() = process_sp->ResumeSynchronous (NULL); + } + else + sb_error.SetErrorString ("SBProcess is invalid"); + + if (log) + { + SBStream sstr; + sb_error.GetDescription (sstr); + log->Printf ("SBProcess(%p)::Continue () => SBError (%p): %s", + static_cast<void*>(process_sp.get()), + static_cast<void*>(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", + static_cast<void*>(process_sp.get()), + static_cast<void*>(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", + static_cast<void*>(process_sp.get()), + static_cast<void*>(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", + static_cast<void*>(process_sp.get()), + static_cast<void*>(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", + static_cast<void*>(process_sp.get()), signo, + static_cast<void*>(sb_error.get()), sstr.GetData()); + } + return sb_error; +} + +SBUnixSignals +SBProcess::GetUnixSignals() +{ + SBUnixSignals sb_unix_signals; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + sb_unix_signals.SetSP(process_sp); + } + + return sb_unix_signals; +} + +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)", + static_cast<void*>(process_sp.get()), tid, + static_cast<void*>(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)", + static_cast<void*>(process_sp.get()), index_id, + static_cast<void*>(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", + static_cast<void*>(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)", + static_cast<void*>(process_sp.get()), + static_cast<void*>(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))...", + static_cast<void*>(process_sp.get()), addr, + static_cast<void*>(dst), static_cast<uint64_t>(dst_len), + static_cast<void*>(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", + static_cast<void*>(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, + static_cast<void*>(process_sp.get()), addr, + static_cast<void*>(dst), static_cast<uint64_t>(dst_len), + static_cast<void*>(sb_error.get()), sstr.GetData(), + static_cast<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", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(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))...", + static_cast<void*>(process_sp.get()), addr, + static_cast<const void*>(src), + static_cast<uint64_t>(src_len), + static_cast<void*>(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", + static_cast<void*>(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, + static_cast<void*>(process_sp.get()), addr, + static_cast<const void*>(src), + static_cast<uint64_t>(src_len), + static_cast<void*>(sb_error.get()), sstr.GetData(), + static_cast<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", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + else + sb_error.SetErrorString("invalid process"); + return sb_error; +} + +lldb::SBError +SBProcess::SendEventData (const char *event_data) +{ + 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->SendEventData (event_data)); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBProcess(%p)::SendEventData() => error: process is running", + static_cast<void*>(process_sp.get())); + sb_error.SetErrorString("process is running"); + } + } + else + sb_error.SetErrorString("invalid process"); + return sb_error; +} + +uint32_t +SBProcess::GetNumExtendedBacktraceTypes () +{ + ProcessSP process_sp(GetSP()); + if (process_sp && process_sp->GetSystemRuntime()) + { + SystemRuntime *runtime = process_sp->GetSystemRuntime(); + return runtime->GetExtendedBacktraceTypes().size(); + } + return 0; +} + +const char * +SBProcess::GetExtendedBacktraceTypeAtIndex (uint32_t idx) +{ + ProcessSP process_sp(GetSP()); + if (process_sp && process_sp->GetSystemRuntime()) + { + SystemRuntime *runtime = process_sp->GetSystemRuntime(); + const std::vector<ConstString> &names = runtime->GetExtendedBacktraceTypes(); + if (idx < names.size()) + { + return names[idx].AsCString(); + } + else + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBProcess(%p)::GetExtendedBacktraceTypeAtIndex() => error: requested extended backtrace name out of bounds", + static_cast<void*>(process_sp.get())); + } + } + return NULL; +} + +SBThreadCollection +SBProcess::GetHistoryThreads (addr_t addr) +{ + ProcessSP process_sp(GetSP()); + SBThreadCollection threads; + if (process_sp) + { + threads = SBThreadCollection(process_sp->GetHistoryThreads(addr)); + } + return threads; +} + +bool +SBProcess::IsInstrumentationRuntimePresent(InstrumentationRuntimeType type) +{ + ProcessSP process_sp(GetSP()); + if (! process_sp) + return false; + + InstrumentationRuntimeSP runtime_sp = process_sp->GetInstrumentationRuntime(type); + + if (! runtime_sp.get()) + return false; + + return runtime_sp->IsActive(); +} diff --git a/contrib/llvm/tools/lldb/source/API/SBQueue.cpp b/contrib/llvm/tools/lldb/source/API/SBQueue.cpp new file mode 100644 index 0000000..b19ed72 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBQueue.cpp @@ -0,0 +1,452 @@ +//===-- SBQueue.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 <inttypes.h> + +#include "lldb/API/SBQueue.h" + +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBThread.h" +#include "lldb/API/SBQueueItem.h" + +#include "lldb/Core/Log.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueItem.h" +#include "lldb/Target/Thread.h" + +using namespace lldb; +using namespace lldb_private; + +namespace lldb_private +{ + + class QueueImpl + { + public: + QueueImpl () : + m_queue_wp(), + m_threads(), + m_thread_list_fetched(false), + m_pending_items(), + m_pending_items_fetched(false) + { + } + + QueueImpl (const lldb::QueueSP &queue_sp) : + m_queue_wp(), + m_threads(), + m_thread_list_fetched(false), + m_pending_items(), + m_pending_items_fetched(false) + { + m_queue_wp = queue_sp; + } + + QueueImpl (const QueueImpl &rhs) + { + if (&rhs == this) + return; + m_queue_wp = rhs.m_queue_wp; + m_threads = rhs.m_threads; + m_thread_list_fetched = rhs.m_thread_list_fetched; + m_pending_items = rhs.m_pending_items; + m_pending_items_fetched = rhs.m_pending_items_fetched; + } + + ~QueueImpl () + { + } + + bool + IsValid () + { + return m_queue_wp.lock() != NULL; + } + + void + Clear () + { + m_queue_wp.reset(); + m_thread_list_fetched = false; + m_threads.clear(); + m_pending_items_fetched = false; + m_pending_items.clear(); + } + + void + SetQueue (const lldb::QueueSP &queue_sp) + { + Clear(); + m_queue_wp = queue_sp; + } + + lldb::queue_id_t + GetQueueID () const + { + lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID; + lldb::QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + result = queue_sp->GetID(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBQueue(%p)::GetQueueID () => 0x%" PRIx64, + static_cast<const void*>(this), result); + return result; + } + + uint32_t + GetIndexID () const + { + uint32_t result = LLDB_INVALID_INDEX32; + lldb::QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + result = queue_sp->GetIndexID(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBQueueImpl(%p)::GetIndexID () => %d", + static_cast<const void*>(this), result); + return result; + } + + const char * + GetName () const + { + const char *name = NULL; + lldb::QueueSP queue_sp = m_queue_wp.lock (); + if (queue_sp.get()) + { + name = queue_sp->GetName(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBQueueImpl(%p)::GetName () => %s", + static_cast<const void*>(this), + name ? name : "NULL"); + + return name; + } + + void + FetchThreads () + { + if (m_thread_list_fetched == false) + { + lldb::QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock())) + { + const std::vector<ThreadSP> thread_list(queue_sp->GetThreads()); + m_thread_list_fetched = true; + const uint32_t num_threads = thread_list.size(); + for (uint32_t idx = 0; idx < num_threads; ++idx) + { + ThreadSP thread_sp = thread_list[idx]; + if (thread_sp && thread_sp->IsValid()) + { + m_threads.push_back (thread_sp); + } + } + } + } + } + } + + void + FetchItems () + { + if (m_pending_items_fetched == false) + { + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock())) + { + const std::vector<QueueItemSP> queue_items(queue_sp->GetPendingItems()); + m_pending_items_fetched = true; + const uint32_t num_pending_items = queue_items.size(); + for (uint32_t idx = 0; idx < num_pending_items; ++idx) + { + QueueItemSP item = queue_items[idx]; + if (item && item->IsValid()) + { + m_pending_items.push_back (item); + } + } + } + } + } + } + + uint32_t + GetNumThreads () + { + uint32_t result = 0; + + FetchThreads(); + if (m_thread_list_fetched) + { + result = m_threads.size(); + } + return result; + } + + lldb::SBThread + GetThreadAtIndex (uint32_t idx) + { + FetchThreads(); + + SBThread sb_thread; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp && idx < m_threads.size()) + { + ProcessSP process_sp = queue_sp->GetProcess(); + if (process_sp) + { + ThreadSP thread_sp = m_threads[idx].lock(); + if (thread_sp) + { + sb_thread.SetThread (thread_sp); + } + } + } + return sb_thread; + } + + uint32_t + GetNumPendingItems () + { + uint32_t result = 0; + + QueueSP queue_sp = m_queue_wp.lock(); + if (m_pending_items_fetched == false && queue_sp) + { + result = queue_sp->GetNumPendingWorkItems(); + } + else + { + result = m_pending_items.size(); + } + return result; + } + + lldb::SBQueueItem + GetPendingItemAtIndex (uint32_t idx) + { + SBQueueItem result; + FetchItems(); + if (m_pending_items_fetched && idx < m_pending_items.size()) + { + result.SetQueueItem (m_pending_items[idx]); + } + return result; + } + + uint32_t + GetNumRunningItems () + { + uint32_t result = 0; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + result = queue_sp->GetNumRunningWorkItems(); + return result; + } + + lldb::SBProcess + GetProcess () + { + SBProcess result; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + result.SetSP (queue_sp->GetProcess()); + } + return result; + } + + lldb::QueueKind + GetKind () + { + lldb::QueueKind kind = eQueueKindUnknown; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + kind = queue_sp->GetKind(); + + return kind; + } + + private: + lldb::QueueWP m_queue_wp; + std::vector<lldb::ThreadWP> m_threads; // threads currently executing this queue's items + bool m_thread_list_fetched; // have we tried to fetch the threads list already? + std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued + bool m_pending_items_fetched; // have we tried to fetch the item list already? + }; + +} + +SBQueue::SBQueue () : + m_opaque_sp (new QueueImpl()) +{ +} + +SBQueue::SBQueue (const QueueSP& queue_sp) : + m_opaque_sp (new QueueImpl (queue_sp)) +{ +} + +SBQueue::SBQueue (const SBQueue &rhs) +{ + if (&rhs == this) + return; + + m_opaque_sp = rhs.m_opaque_sp; +} + +const lldb::SBQueue & +SBQueue::operator = (const lldb::SBQueue &rhs) +{ + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +SBQueue::~SBQueue() +{ +} + +bool +SBQueue::IsValid() const +{ + bool is_valid = m_opaque_sp->IsValid (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::IsValid() == %s", m_opaque_sp->GetQueueID(), + is_valid ? "true" : "false"); + return is_valid; +} + + +void +SBQueue::Clear () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::Clear()", m_opaque_sp->GetQueueID()); + m_opaque_sp->Clear(); +} + + +void +SBQueue::SetQueue (const QueueSP& queue_sp) +{ + m_opaque_sp->SetQueue (queue_sp); +} + +lldb::queue_id_t +SBQueue::GetQueueID () const +{ + lldb::queue_id_t qid = m_opaque_sp->GetQueueID (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetQueueID() == 0x%" PRIx64, m_opaque_sp->GetQueueID(), (uint64_t) qid); + return qid; +} + +uint32_t +SBQueue::GetIndexID () const +{ + uint32_t index_id = m_opaque_sp->GetIndexID (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetIndexID() == 0x%" PRIx32, m_opaque_sp->GetQueueID(), index_id); + return index_id; +} + +const char * +SBQueue::GetName () const +{ + const char *name = m_opaque_sp->GetName (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetName() == %s", m_opaque_sp->GetQueueID(), + name ? name : ""); + return name; +} + +uint32_t +SBQueue::GetNumThreads () +{ + uint32_t numthreads = m_opaque_sp->GetNumThreads (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetNumThreads() == %d", m_opaque_sp->GetQueueID(), numthreads); + return numthreads; +} + +SBThread +SBQueue::GetThreadAtIndex (uint32_t idx) +{ + SBThread th = m_opaque_sp->GetThreadAtIndex (idx); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetThreadAtIndex(%d)", m_opaque_sp->GetQueueID(), idx); + return th; +} + + +uint32_t +SBQueue::GetNumPendingItems () +{ + uint32_t pending_items = m_opaque_sp->GetNumPendingItems (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetNumPendingItems() == %d", m_opaque_sp->GetQueueID(), pending_items); + return pending_items; +} + +SBQueueItem +SBQueue::GetPendingItemAtIndex (uint32_t idx) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetPendingItemAtIndex(%d)", m_opaque_sp->GetQueueID(), idx); + return m_opaque_sp->GetPendingItemAtIndex (idx); +} + +uint32_t +SBQueue::GetNumRunningItems () +{ + uint32_t running_items = m_opaque_sp->GetNumRunningItems (); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueue(0x%" PRIx64 ")::GetNumRunningItems() == %d", m_opaque_sp->GetQueueID(), running_items); + return running_items; +} + +SBProcess +SBQueue::GetProcess () +{ + return m_opaque_sp->GetProcess(); +} + +lldb::QueueKind +SBQueue::GetKind () +{ + return m_opaque_sp->GetKind(); +} diff --git a/contrib/llvm/tools/lldb/source/API/SBQueueItem.cpp b/contrib/llvm/tools/lldb/source/API/SBQueueItem.cpp new file mode 100644 index 0000000..6a1aa7b --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBQueueItem.cpp @@ -0,0 +1,168 @@ +//===-- SBQueueItem.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-forward.h" + +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBQueueItem.h" +#include "lldb/API/SBThread.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/Log.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/QueueItem.h" +#include "lldb/Target/Thread.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// Constructors +//---------------------------------------------------------------------- +SBQueueItem::SBQueueItem () : + m_queue_item_sp() +{ +} + +SBQueueItem::SBQueueItem (const QueueItemSP& queue_item_sp) : + m_queue_item_sp (queue_item_sp) +{ +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBQueueItem::~SBQueueItem() +{ + m_queue_item_sp.reset(); +} + +bool +SBQueueItem::IsValid() const +{ + bool is_valid = m_queue_item_sp.get() != NULL; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueueItem(%p)::IsValid() == %s", + static_cast<void*>(m_queue_item_sp.get()), + is_valid ? "true" : "false"); + return is_valid; +} + + +void +SBQueueItem::Clear () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf("SBQueueItem(%p)::Clear()", + static_cast<void*>(m_queue_item_sp.get())); + m_queue_item_sp.reset(); +} + + +void +SBQueueItem::SetQueueItem (const QueueItemSP& queue_item_sp) +{ + m_queue_item_sp = queue_item_sp; +} + + +lldb::QueueItemKind +SBQueueItem::GetKind () const +{ + QueueItemKind result = eQueueItemKindUnknown; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (m_queue_item_sp) + { + result = m_queue_item_sp->GetKind (); + } + if (log) + log->Printf("SBQueueItem(%p)::GetKind() == %d", + static_cast<void*>(m_queue_item_sp.get()), + static_cast<int>(result)); + return result; +} + +void +SBQueueItem::SetKind (lldb::QueueItemKind kind) +{ + if (m_queue_item_sp) + { + m_queue_item_sp->SetKind (kind); + } +} + +SBAddress +SBQueueItem::GetAddress () const +{ + SBAddress result; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (m_queue_item_sp) + { + result.SetAddress (&m_queue_item_sp->GetAddress()); + } + if (log) + { + StreamString sstr; + const Address *addr = result.get(); + if (addr) + addr->Dump (&sstr, NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4); + log->Printf ("SBQueueItem(%p)::GetAddress() == SBAddress(%p): %s", + static_cast<void*>(m_queue_item_sp.get()), + static_cast<void*>(result.get()), sstr.GetData()); + } + return result; +} + +void +SBQueueItem::SetAddress (SBAddress addr) +{ + if (m_queue_item_sp) + { + m_queue_item_sp->SetAddress (addr.ref()); + } +} + +SBThread +SBQueueItem::GetExtendedBacktraceThread (const char *type) +{ + SBThread result; + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (m_queue_item_sp) + { + ProcessSP process_sp = m_queue_item_sp->GetProcessSP(); + Process::StopLocker stop_locker; + if (process_sp && stop_locker.TryLock(&process_sp->GetRunLock())) + { + ThreadSP thread_sp; + ConstString type_const (type); + thread_sp = m_queue_item_sp->GetExtendedBacktraceThread (type_const); + if (thread_sp) + { + // Save this in the Process' ExtendedThreadList so a strong pointer retains the + // object + process_sp->GetExtendedThreadList().AddThread (thread_sp); + result.SetThread (thread_sp); + if (log) + { + const char *queue_name = thread_sp->GetQueueName(); + if (queue_name == NULL) + queue_name = ""; + log->Printf ("SBQueueItem(%p)::GetExtendedBacktraceThread() = new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", + static_cast<void*>(m_queue_item_sp.get()), + static_cast<void*>(thread_sp.get()), + static_cast<uint64_t>(thread_sp->GetQueueID()), + queue_name); + } + } + } + } + return result; +} 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..809eca6 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBSection.cpp @@ -0,0 +1,299 @@ +//===-- 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; +} + +uint32_t +SBSection::GetTargetByteSize () +{ + SectionSP section_sp (GetSP()); + if (section_sp.get()) + return section_sp->GetTargetByteSize(); + return 0; +} + +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..f5b5c08 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBStream.cpp @@ -0,0 +1,189 @@ +//===-- 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; + else + open_options |= File::eOpenOptionTruncate; + stream_file->GetFile().Open (path, open_options, lldb::eFilePermissionsFileDefault); + + 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..12a3b31 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBSymbol.cpp @@ -0,0 +1,227 @@ +//===-- 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\"", + static_cast<void*>(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\"", + static_cast<void*>(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()); + const bool prefer_file_cache = false; + sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture (), + NULL, + flavor_string, + exe_ctx, + symbol_range, + prefer_file_cache)); + } + } + } + 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..481fa1a --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBSymbolContext.cpp @@ -0,0 +1,287 @@ +//===-- 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", + static_cast<void*>(m_opaque_ap.get()), + static_cast<void*>(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)", + static_cast<void*>(m_opaque_ap.get()), + static_cast<void*>(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)", + static_cast<void*>(m_opaque_ap.get()), + static_cast<void*>(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)", + static_cast<void*>(m_opaque_ap.get()), + static_cast<void*>(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..b87b1ac --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTarget.cpp @@ -0,0 +1,2931 @@ +//===-- 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/ValueObjectConstResult.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" +#include "llvm/Support/Regex.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); +} + +SBFileSpec +SBLaunchInfo::GetExecutableFile () +{ + return SBFileSpec (m_opaque_sp->GetExecutableFile()); +} + +void +SBLaunchInfo::SetExecutableFile (SBFileSpec exe_file, bool add_as_first_arg) +{ + m_opaque_sp->SetExecutableFile(exe_file.ref(), add_as_first_arg); +} + +SBListener +SBLaunchInfo::GetListener () +{ + return SBListener(m_opaque_sp->GetListener()); +} + +void +SBLaunchInfo::SetListener (SBListener &listener) +{ + m_opaque_sp->SetListener(listener.GetSP()); +} + +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 () +{ + // Constify this string so that it is saved in the string pool. Otherwise + // it would be freed when this function goes out of scope. + ConstString shell(m_opaque_sp->GetShell().GetPath().c_str()); + return shell.AsCString(); +} + +void +SBLaunchInfo::SetShell (const char * path) +{ + m_opaque_sp->SetShell (FileSpec(path, false)); +} + +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); +} + +void +SBLaunchInfo::SetLaunchEventData (const char *data) +{ + m_opaque_sp->SetLaunchEventData (data); +} + +const char * +SBLaunchInfo::GetLaunchEventData () const +{ + return m_opaque_sp->GetLaunchEventData (); +} + +void +SBLaunchInfo::SetDetachOnError (bool enable) +{ + m_opaque_sp->SetDetachOnError (enable); +} + +bool +SBLaunchInfo::GetDetachOnError () const +{ + return m_opaque_sp->GetDetachOnError (); +} + +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(); +} + +SBListener +SBAttachInfo::GetListener () +{ + return SBListener(m_opaque_sp->GetListener()); +} + +void +SBAttachInfo::SetListener (SBListener &listener) +{ + m_opaque_sp->SetListener(listener.GetSP()); +} + +//---------------------------------------------------------------------- +// 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)", + static_cast<void*>(target_sp.get()), + static_cast<void*>(process_sp.get())); + + return sb_process; +} + +SBPlatform +SBTarget::GetPlatform () +{ + TargetSP target_sp(GetSP()); + if (!target_sp) + return SBPlatform(); + + SBPlatform platform; + platform.m_opaque_sp = target_sp->GetPlatform(); + + return platform; +} + +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); +} + +SBError +SBTarget::Install() +{ + SBError sb_error; + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + sb_error.ref() = target_sp->Install(NULL); + } + return sb_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))...", + static_cast<void*>(target_sp.get()), + static_cast<void*>(argv), static_cast<void*>(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, + static_cast<void*>(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; + } + } + + 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); + + if (listener.IsValid()) + launch_info.SetListener(listener.GetSP()); + + error.SetError (target_sp->Launch(launch_info, NULL)); + + sb_process.SetSP(target_sp->GetProcessSP()); + } + else + { + error.SetErrorString ("SBTarget is invalid"); + } + + log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); + if (log) + log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", + static_cast<void*>(target_sp.get()), + static_cast<void*>(sb_process.GetSP().get())); + + return sb_process; +} + +SBProcess +SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBProcess sb_process; + TargetSP target_sp(GetSP()); + + if (log) + log->Printf ("SBTarget(%p)::Launch (launch_info, error)...", + static_cast<void*>(target_sp.get())); + + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + StateType state = eStateInvalid; + { + ProcessSP 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; + } + } + } + + lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref(); + + if (!launch_info.GetExecutableFile()) + { + 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 (target_sp->Launch (launch_info, NULL)); + sb_process.SetSP(target_sp->GetProcessSP()); + } + else + { + error.SetErrorString ("SBTarget is invalid"); + } + + log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); + if (log) + log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", + static_cast<void*>(target_sp.get()), + static_cast<void*>(sb_process.GetSP().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)...", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(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)", + static_cast<void*>(target_sp.get()), + static_cast<void*>(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)...", + static_cast<void*>(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)", + static_cast<void*>(target_sp.get()), + static_cast<void*>(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)...", + static_cast<void*>(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)", + static_cast<void*>(target_sp.get()), + static_cast<void*>(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)...", + static_cast<void*>(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)", + static_cast<void*>(target_sp.get()), + static_cast<void*>(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)", + static_cast<void*>(target_sp.get()), + static_cast<const void*>(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->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; +} + +lldb::SBAddress +SBTarget::ResolveFileAddress (lldb::addr_t file_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->ResolveFileAddress (file_addr, addr)) + return sb_addr; + } + + addr.SetRawAddress(file_addr); + return sb_addr; +} + +lldb::SBAddress +SBTarget::ResolvePastLoadAddress (uint32_t stop_id, 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->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; +} + +size_t +SBTarget::ReadMemory (const SBAddress addr, + void *buf, + size_t size, + lldb::SBError &error) +{ + SBError sb_error; + size_t bytes_read = 0; + TargetSP target_sp(GetSP()); + if (target_sp) + { + Mutex::Locker api_locker (target_sp->GetAPIMutex()); + bytes_read = target_sp->ReadMemory(addr.ref(), false, buf, size, sb_error.ref()); + } + else + { + sb_error.SetErrorString("invalid target"); + } + + return bytes_read; +} + +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; + const bool hardware = false; + *sb_bp = target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, check_inlines, skip_prologue, internal, hardware); + } + + 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", + static_cast<void*>(target_sp.get()), path, line, + static_cast<void*>(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 bool hardware = 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, hardware); + } + else + { + *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal, hardware); + } + } + + if (log) + log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)", + static_cast<void*>(target_sp.get()), symbol_name, + module_name, static_cast<void*>(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 bool hardware = 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, + hardware); + } + + if (log) + log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", name_type: %d) => SBBreakpoint(%p)", + static_cast<void*>(target_sp.get()), symbol_name, + name_type_mask, static_cast<void*>(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 bool hardware = 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, + hardware); + } + + if (log) + { + log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbols={", + static_cast<void*>(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, + static_cast<void*>(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 bool hardware = 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, hardware); + } + else + { + *sb_bp = target_sp->CreateFuncRegexBreakpoint (NULL, NULL, regexp, skip_prologue, internal, hardware); + } + } + + if (log) + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", + static_cast<void*>(target_sp.get()), symbol_name_regex, + module_name, static_cast<void*>(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 bool hardware = false; + const LazyBool skip_prologue = eLazyBoolCalculate; + + *sb_bp = target_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, skip_prologue, internal, hardware); + } + + if (log) + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\") => SBBreakpoint(%p)", + static_cast<void*>(target_sp.get()), symbol_name_regex, + static_cast<void*>(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()); + const bool hardware = false; + *sb_bp = target_sp->CreateBreakpoint (address, false, hardware); + } + + if (log) + log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%" PRIu64 ") => SBBreakpoint(%p)", + static_cast<void*>(target_sp.get()), + static_cast<uint64_t>(address), + static_cast<void*>(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; + const bool hardware = false; + 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, hardware); + } + else + { + *sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false, hardware); + } + } + + 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)", + static_cast<void*>(target_sp.get()), source_regex, path, + module_name, static_cast<void*>(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()); + const bool hardware = false; + RegularExpression regexp(source_regex); + *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false, hardware); + } + + if (log) + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\") => SBBreakpoint(%p)", + static_cast<void*>(target_sp.get()), source_regex, + static_cast<void*>(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()); + const bool hardware = false; + *sb_bp = target_sp->CreateExceptionBreakpoint (language, catch_bp, throw_bp, hardware); + } + + if (log) + log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: %s throw: %s) => SBBreakpoint(%p)", + static_cast<void*>(target_sp.get()), + LanguageRuntime::GetNameForLanguageType(language), + catch_bp ? "on" : "off", throw_bp ? "on" : "off", + static_cast<void*>(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", + static_cast<void*>(target_sp.get()), + static_cast<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)", + static_cast<void*>(target_sp.get()), + static_cast<uint32_t>(bp_id), + static_cast<void*>(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", + static_cast<void*>(target_sp.get()), + static_cast<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)", + static_cast<void*>(target_sp.get()), + static_cast<uint32_t>(wp_id), + static_cast<void*>(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)", + static_cast<void*>(target_sp.get()), addr, + static_cast<uint32_t>(size), + static_cast<void*>(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; +} + +SBValue +SBTarget::CreateValueFromAddress (const char *name, SBAddress addr, SBType type) +{ + SBValue sb_value; + lldb::ValueObjectSP new_value_sp; + if (IsValid() && name && *name && addr.IsValid() && type.IsValid()) + { + lldb::addr_t load_addr(addr.GetLoadAddress(*this)); + ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false))); + ClangASTType ast_type(type.GetSP()->GetClangASTType(true)); + new_value_sp = ValueObject::CreateValueObjectFromAddress(name, load_addr, exe_ctx, ast_type); + } + sb_value.SetSP(new_value_sp); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBTarget(%p)::CreateValueFromAddress => \"%s\"", + static_cast<void*>(m_opaque_sp.get()), + new_value_sp->GetName().AsCString()); + else + log->Printf ("SBTarget(%p)::CreateValueFromAddress => NULL", + static_cast<void*>(m_opaque_sp.get())); + } + return sb_value; +} + +lldb::SBValue +SBTarget::CreateValueFromData (const char *name, lldb::SBData data, lldb::SBType type) +{ + SBValue sb_value; + lldb::ValueObjectSP new_value_sp; + if (IsValid() && name && *name && data.IsValid() && type.IsValid()) + { + DataExtractorSP extractor(*data); + ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false))); + ClangASTType ast_type(type.GetSP()->GetClangASTType(true)); + new_value_sp = ValueObject::CreateValueObjectFromData(name, *extractor, exe_ctx, ast_type); + } + sb_value.SetSP(new_value_sp); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBTarget(%p)::CreateValueFromData => \"%s\"", + static_cast<void*>(m_opaque_sp.get()), + new_value_sp->GetName().AsCString()); + else + log->Printf ("SBTarget(%p)::CreateValueFromData => NULL", + static_cast<void*>(m_opaque_sp.get())); + } + return sb_value; +} + +lldb::SBValue +SBTarget::CreateValueFromExpression (const char *name, const char* expr) +{ + SBValue sb_value; + lldb::ValueObjectSP new_value_sp; + if (IsValid() && name && *name && expr && *expr) + { + ExecutionContext exe_ctx (ExecutionContextRef(ExecutionContext(m_opaque_sp.get(),false))); + new_value_sp = ValueObject::CreateValueObjectFromExpression(name, expr, exe_ctx); + } + sb_value.SetSP(new_value_sp); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBTarget(%p)::CreateValueFromExpression => \"%s\"", + static_cast<void*>(m_opaque_sp.get()), + new_value_sp->GetName().AsCString()); + else + log->Printf ("SBTarget(%p)::CreateValueFromExpression => NULL", + static_cast<void*>(m_opaque_sp.get())); + } + return sb_value; +} + +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()); + else + module_spec.GetArchitecture() = target_sp->GetArchitecture(); + + 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", + static_cast<void*>(target_sp.get()), num); + + return num; +} + +void +SBTarget::Clear () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBTarget(%p)::Clear ()", + static_cast<void*>(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::GetDataByteSize () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + return target_sp->GetArchitecture().GetDataByteSize() ; + } + return 0; +} + +uint32_t +SBTarget::GetCodeByteSize () +{ + TargetSP target_sp(GetSP()); + if (target_sp) + { + return target_sp->GetArchitecture().GetCodeByteSize() ; + } + return 0; +} + +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)", + static_cast<void*>(target_sp.get()), idx, + static_cast<void*>(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)", + static_cast<void*>(target_sp.get()), + static_cast<void*>(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::SBSymbolContextList +SBTarget::FindGlobalFunctions(const char *name, uint32_t max_matches, MatchType matchtype) +{ + lldb::SBSymbolContextList sb_sc_list; + if (name && name[0]) + { + TargetSP target_sp(GetSP()); + if (target_sp) + { + std::string regexstr; + switch (matchtype) + { + case eMatchTypeRegex: + target_sp->GetImages().FindFunctions(RegularExpression(name), true, true, true, *sb_sc_list); + break; + case eMatchTypeStartsWith: + regexstr = llvm::Regex::escape(name) + ".*"; + target_sp->GetImages().FindFunctions(RegularExpression(regexstr.c_str()), true, true, true, *sb_sc_list); + break; + default: + target_sp->GetImages().FindFunctions(ConstString(name), eFunctionNameTypeAny, true, true, true, *sb_sc_list); + break; + } + } + } + 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) + { + DeclVendor *objc_decl_vendor = objc_language_runtime->GetDeclVendor(); + + if (objc_decl_vendor) + { + std::vector <clang::NamedDecl *> decls; + + if (objc_decl_vendor->FindDecls(const_typename, true, 1, decls) > 0) + { + if (ClangASTType type = ClangASTContext::GetTypeForDecl(decls[0])) + { + return SBType(type); + } + } + } + } + } + + // 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) + { + DeclVendor *objc_decl_vendor = objc_language_runtime->GetDeclVendor(); + + if (objc_decl_vendor) + { + std::vector <clang::NamedDecl *> decls; + + if (objc_decl_vendor->FindDecls(const_typename, true, 1, decls) > 0) + { + for (clang::NamedDecl *decl : decls) + { + if (ClangASTType type = ClangASTContext::GetTypeForDecl(decl)) + { + 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; +} + +SBValueList +SBTarget::FindGlobalVariables(const char *name, uint32_t max_matches, MatchType matchtype) +{ + SBValueList sb_value_list; + + TargetSP target_sp(GetSP()); + if (name && target_sp) + { + VariableList variable_list; + const bool append = true; + + std::string regexstr; + uint32_t match_count; + switch (matchtype) + { + case eMatchTypeNormal: + match_count = target_sp->GetImages().FindGlobalVariables(ConstString(name), + append, + max_matches, + variable_list); + break; + case eMatchTypeRegex: + match_count = target_sp->GetImages().FindGlobalVariables(RegularExpression(name), + append, + max_matches, + variable_list); + break; + case eMatchTypeStartsWith: + regexstr = llvm::Regex::escape(name) + ".*"; + match_count = target_sp->GetImages().FindGlobalVariables(RegularExpression(regexstr.c_str()), + append, + max_matches, + variable_list); + break; + } + + + 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 + { + ProcessSP process_sp (target_sp->GetProcessSP()); + if (target_sp->SetSectionLoadAddress (section_sp, section_base_addr)) + { + // Flush info in the process (stack frames, etc) + 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 + { + ProcessSP process_sp (target_sp->GetProcessSP()); + if (target_sp->SetSectionUnloaded (section.GetSP())) + { + // Flush info in the process (stack frames, etc) + 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, true, 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) + { + ProcessSP process_sp (target_sp->GetProcessSP()); + + 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->SetSectionUnloaded (section_sp); + } + 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; + ExpressionResults exe_results = eExpressionSetupError; + 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)", + static_cast<void*>(frame), expr, + static_cast<void*>(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..6524d10 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBThread.cpp @@ -0,0 +1,1600 @@ +//===-- 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/Core/StructuredData.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Target/SystemRuntime.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Queue.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/SBThreadPlan.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() +{ +} + +lldb::SBQueue +SBThread::GetQueue () const +{ + SBQueue sb_queue; + QueueSP queue_sp; + 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())) + { + queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); + if (queue_sp) + { + sb_queue.SetQueue (queue_sp); + } + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetQueueKind() => error: process is running", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetQueueKind () => SBQueue(%p)", + static_cast<void*>(exe_ctx.GetThreadPtr()), static_cast<void*>(queue_sp.get())); + + return sb_queue; +} + + +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", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetStopReason () => %s", + static_cast<void*>(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: + case eStopReasonInstrumentation: + // 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", + static_cast<void*>(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: + case eStopReasonInstrumentation: + // 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 (idx & 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", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + return 0; +} + +bool +SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream) +{ + Stream &strm = stream.ref(); + + ExecutionContext exe_ctx (m_opaque_sp.get()); + if (! exe_ctx.HasThreadScope()) + return false; + + + StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); + StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); + if (! info) + return false; + + info->Dump(strm); + + return true; +} + +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\"", + static_cast<void*>(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'", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetName () => %s", + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetQueueName () => %s", + static_cast<void*>(exe_ctx.GetThreadPtr()), + name ? name : "NULL"); + + return name; +} + +lldb::queue_id_t +SBThread::GetQueueID () const +{ + queue_id_t id = LLDB_INVALID_QUEUE_ID; + 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())) + { + id = exe_ctx.GetThreadPtr()->GetQueueID(); + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, + static_cast<void*>(exe_ctx.GetThreadPtr()), id); + + return id; +} + +bool +SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + bool success = false; + 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(); + StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); + if (info_root_sp) + { + StructuredData::ObjectSP node = info_root_sp->GetObjectForDotSeparatedPath (path); + if (node) + { + if (node->GetType() == StructuredData::Type::eTypeString) + { + strm.Printf ("%s", node->GetAsString()->GetValue().c_str()); + success = true; + } + if (node->GetType() == StructuredData::Type::eTypeInteger) + { + strm.Printf ("0x%" PRIx64, node->GetAsInteger()->GetValue()); + success = true; + } + if (node->GetType() == StructuredData::Type::eTypeFloat) + { + strm.Printf ("0x%f", node->GetAsFloat()->GetValue()); + success = true; + } + if (node->GetType() == StructuredData::Type::eTypeBoolean) + { + if (node->GetAsBoolean()->GetValue() == true) + strm.Printf ("true"); + else + strm.Printf ("false"); + success = true; + } + if (node->GetType() == StructuredData::Type::eTypeNull) + { + strm.Printf ("null"); + success = true; + } + } + } + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetInfoItemByPathAsString() => error: process is running", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetInfoItemByPathAsString () => %s", + static_cast<void*>(exe_ctx.GetThreadPtr()), + strm.GetData()); + + return success; +} + + +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()); + + if (process->GetTarget().GetDebugger().GetAsyncExecution ()) + sb_error.ref() = process->Resume (); + else + sb_error.ref() = process->ResumeSynchronous (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')", + static_cast<void*>(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 ()) + { + const LazyBool avoid_no_debug = eLazyBoolCalculate; + SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); + new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, + sc.line_entry.range, + sc, + stop_other_threads, + avoid_no_debug); + } + 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')", + static_cast<void*>(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 ()) + { + const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate; + const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate; + SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); + new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, + sc.line_entry.range, + sc, + target_name, + stop_other_threads, + step_in_avoids_code_without_debug_info, + step_out_avoids_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 ()", + static_cast<void*>(exe_ctx.GetThreadPtr())); + + if (exe_ctx.HasThreadScope()) + { + bool abort_other_plans = false; + bool stop_other_threads = false; + + Thread *thread = exe_ctx.GetThreadPtr(); + + const LazyBool avoid_no_debug = eLazyBoolCalculate; + ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, + NULL, + false, + stop_other_threads, + eVoteYes, + eVoteNoOpinion, + 0, + avoid_no_debug)); + + // 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)", + static_cast<void*>(exe_ctx.GetThreadPtr()), + static_cast<void*>(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)", + static_cast<void*>(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 ")", + static_cast<void*>(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)", + static_cast<void*>(exe_ctx.GetThreadPtr()), + static_cast<void*>(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::StepUsingScriptedThreadPlan (const char *script_class_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBError sb_error; + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (log) + { + log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s", + static_cast<void*>(exe_ctx.GetThreadPtr()), + script_class_name); + } + + + if (!exe_ctx.HasThreadScope()) + { + sb_error.SetErrorString("this SBThread object is invalid"); + return sb_error; + } + + Thread *thread = exe_ctx.GetThreadPtr(); + ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false); + + if (thread_plan_sp) + sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get()); + else + { + sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name); + if (log) + log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s", + static_cast<void*>(exe_ctx.GetThreadPtr()), + script_class_name); + } + + return sb_error; +} + +SBError +SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + SBError sb_error; + + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + + if (log) + log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", + static_cast<void*>(exe_ctx.GetThreadPtr()), + file_spec->GetPath().c_str(), line); + + if (!exe_ctx.HasThreadScope()) + { + sb_error.SetErrorString("this SBThread object is invalid"); + return sb_error; + } + + Thread *thread = exe_ctx.GetThreadPtr(); + + Error err = thread->JumpToLine (file_spec.get(), line, true); + sb_error.SetError (err); + 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)", + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + if (log) + log->Printf ("SBThread(%p)::Suspend() => %i", + static_cast<void*>(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())) + { + const bool override_suspend = true; + exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend); + result = true; + } + else + { + if (log) + log->Printf ("SBThread(%p)::Resume() => error: process is running", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + if (log) + log->Printf ("SBThread(%p)::Resume() => %i", + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetThreadPtr()), + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log) + log->Printf ("SBThread(%p)::GetNumFrames () => %u", + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetThreadPtr()), idx, + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log) + { + SBStream frame_desc_strm; + sb_frame.GetDescription (frame_desc_strm); + log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", + static_cast<void*>(exe_ctx.GetThreadPtr()), + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(exe_ctx.GetThreadPtr()), idx, + static_cast<void*>(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; +} + +SBThread +SBThread::GetExtendedBacktraceThread (const char *type) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + SBThread sb_origin_thread; + + if (exe_ctx.HasThreadScope()) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + { + ThreadSP real_thread(exe_ctx.GetThreadSP()); + if (real_thread) + { + ConstString type_const (type); + Process *process = exe_ctx.GetProcessPtr(); + if (process) + { + SystemRuntime *runtime = process->GetSystemRuntime(); + if (runtime) + { + ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const)); + if (new_thread_sp) + { + // Save this in the Process' ExtendedThreadList so a strong pointer retains the + // object. + process->GetExtendedThreadList().AddThread (new_thread_sp); + sb_origin_thread.SetThread (new_thread_sp); + if (log) + { + const char *queue_name = new_thread_sp->GetQueueName(); + if (queue_name == NULL) + queue_name = ""; + log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread " + "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", + static_cast<void*>(exe_ctx.GetThreadPtr()), + static_cast<void*>(new_thread_sp.get()), + new_thread_sp->GetQueueID(), + queue_name); + } + } + } + } + } + } + else + { + if (log) + log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", + static_cast<void*>(exe_ctx.GetThreadPtr())); + } + } + + if (log && sb_origin_thread.IsValid() == false) + log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread", + static_cast<void*>(exe_ctx.GetThreadPtr())); + return sb_origin_thread; +} + +uint32_t +SBThread::GetExtendedBacktraceOriginatingIndexID () +{ + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); + if (thread_sp) + return thread_sp->GetExtendedBacktraceOriginatingIndexID(); + return LLDB_INVALID_INDEX32; +} + +bool +SBThread::SafeToCallFunctions () +{ + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); + if (thread_sp) + return thread_sp->SafeToCallFunctions(); + return true; +} + +lldb_private::Thread * +SBThread::operator->() +{ + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); + if (thread_sp) + return thread_sp.get(); + else + return NULL; +} + +lldb_private::Thread * +SBThread::get() +{ + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); + if (thread_sp) + return thread_sp.get(); + else + return NULL; +} + diff --git a/contrib/llvm/tools/lldb/source/API/SBThreadCollection.cpp b/contrib/llvm/tools/lldb/source/API/SBThreadCollection.cpp new file mode 100644 index 0000000..841f932 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBThreadCollection.cpp @@ -0,0 +1,97 @@ +//===-- SBThreadCollection.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/SBThreadCollection.h" +#include "lldb/API/SBThread.h" +#include "lldb/Target/ThreadList.h" + +using namespace lldb; +using namespace lldb_private; + + +SBThreadCollection::SBThreadCollection () : + m_opaque_sp() +{ +} + +SBThreadCollection::SBThreadCollection(const SBThreadCollection &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + +const SBThreadCollection & +SBThreadCollection::operator = (const SBThreadCollection &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +SBThreadCollection::SBThreadCollection (const ThreadCollectionSP &threads) : + m_opaque_sp(threads) +{ +} + +SBThreadCollection::~SBThreadCollection () +{ +} + +void +SBThreadCollection::SetOpaque (const lldb::ThreadCollectionSP &threads) +{ + m_opaque_sp = threads; +} + +lldb_private::ThreadCollection * +SBThreadCollection::get() const +{ + return m_opaque_sp.get(); +} + +lldb_private::ThreadCollection * +SBThreadCollection::operator->() const +{ + return m_opaque_sp.operator->(); +} + +lldb::ThreadCollectionSP & +SBThreadCollection::operator*() +{ + return m_opaque_sp; +} + +const lldb::ThreadCollectionSP & +SBThreadCollection::operator*() const +{ + return m_opaque_sp; +} + + +bool +SBThreadCollection::IsValid () const +{ + return m_opaque_sp.get() != NULL; +} + +size_t +SBThreadCollection::GetSize () +{ + if (m_opaque_sp) + return m_opaque_sp->GetSize(); + return 0; +} + +SBThread +SBThreadCollection::GetThreadAtIndex(size_t idx) +{ + SBThread thread; + if (m_opaque_sp && idx < m_opaque_sp->GetSize()) + thread = m_opaque_sp->GetThreadAtIndex(idx); + return thread; +} diff --git a/contrib/llvm/tools/lldb/source/API/SBThreadPlan.cpp b/contrib/llvm/tools/lldb/source/API/SBThreadPlan.cpp new file mode 100644 index 0000000..02b1a8d --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBThreadPlan.cpp @@ -0,0 +1,285 @@ +//===-- 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/Core/StructuredData.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Target/SystemRuntime.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Queue.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/ThreadPlanPython.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/SBThreadPlan.h" +#include "lldb/API/SBValue.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// Constructors +//---------------------------------------------------------------------- +SBThreadPlan::SBThreadPlan () +{ +} + +SBThreadPlan::SBThreadPlan (const ThreadPlanSP& lldb_object_sp) : + m_opaque_sp (lldb_object_sp) +{ +} + +SBThreadPlan::SBThreadPlan (const SBThreadPlan &rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ + +} + +SBThreadPlan::SBThreadPlan (lldb::SBThread &sb_thread, const char *class_name) +{ + Thread *thread = sb_thread.get(); + if (thread) + m_opaque_sp.reset(new ThreadPlanPython(*thread, class_name)); +} + +//---------------------------------------------------------------------- +// Assignment operator +//---------------------------------------------------------------------- + +const lldb::SBThreadPlan & +SBThreadPlan::operator = (const SBThreadPlan &rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBThreadPlan::~SBThreadPlan() +{ +} + +lldb_private::ThreadPlan * +SBThreadPlan::get() +{ + return m_opaque_sp.get(); +} + +bool +SBThreadPlan::IsValid() const +{ + return m_opaque_sp.get() != NULL; +} + +void +SBThreadPlan::Clear () +{ + m_opaque_sp.reset(); +} + +lldb::StopReason +SBThreadPlan::GetStopReason() +{ + return eStopReasonNone; +} + +size_t +SBThreadPlan::GetStopReasonDataCount() +{ + return 0; +} + +uint64_t +SBThreadPlan::GetStopReasonDataAtIndex(uint32_t idx) +{ + return 0; +} + +SBThread +SBThreadPlan::GetThread () const +{ + if (m_opaque_sp) + { + return SBThread(m_opaque_sp->GetThread().shared_from_this()); + } + else + return SBThread(); +} + +bool +SBThreadPlan::GetDescription (lldb::SBStream &description) const +{ + if (m_opaque_sp) + { + m_opaque_sp->GetDescription(description.get(), eDescriptionLevelFull); + } + else + { + description.Printf("Empty SBThreadPlan"); + } + return true; +} + +void +SBThreadPlan::SetThreadPlan (const ThreadPlanSP& lldb_object_sp) +{ + m_opaque_sp = lldb_object_sp; +} + +void +SBThreadPlan::SetPlanComplete (bool success) +{ + if (m_opaque_sp) + m_opaque_sp->SetPlanComplete (success); +} + +bool +SBThreadPlan::IsPlanComplete() +{ + if (m_opaque_sp) + return m_opaque_sp->IsPlanComplete(); + else + return true; +} + +bool +SBThreadPlan::IsValid() +{ + if (m_opaque_sp) + return m_opaque_sp->ValidatePlan(nullptr); + else + return false; +} + + // This section allows an SBThreadPlan to push another of the common types of plans... + // + // FIXME, you should only be able to queue thread plans from inside the methods of a + // Scripted Thread Plan. Need a way to enforce that. + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepOverRange (SBAddress &sb_start_address, + lldb::addr_t size) +{ + if (m_opaque_sp) + { + Address *start_address = sb_start_address.get(); + if (!start_address) + { + return SBThreadPlan(); + } + + AddressRange range (*start_address, size); + SymbolContext sc; + start_address->CalculateSymbolContext(&sc); + return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange (false, + range, + sc, + eAllThreads)); + } + else + { + return SBThreadPlan(); + } +} + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepInRange (SBAddress &sb_start_address, + lldb::addr_t size) +{ + if (m_opaque_sp) + { + Address *start_address = sb_start_address.get(); + if (!start_address) + { + return SBThreadPlan(); + } + + AddressRange range (*start_address, size); + SymbolContext sc; + start_address->CalculateSymbolContext(&sc); + return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepInRange (false, + range, + sc, + NULL, + eAllThreads)); + } + else + { + return SBThreadPlan(); + } +} + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepOut (uint32_t frame_idx_to_step_to, bool first_insn) +{ + if (m_opaque_sp) + { + SymbolContext sc; + sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything); + return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForStepOut (false, + &sc, + first_insn, + false, + eVoteYes, + eVoteNoOpinion, + frame_idx_to_step_to)); + } + else + { + return SBThreadPlan(); + } +} + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForRunToAddress (SBAddress sb_address) +{ + if (m_opaque_sp) + { + Address *address = sb_address.get(); + if (!address) + return SBThreadPlan(); + + return SBThreadPlan (m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress (false, + *address, + false)); + } + else + { + return SBThreadPlan(); + } +} + + 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..8a0f5d8 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBType.cpp @@ -0,0 +1,853 @@ +//===-- 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 "lldb/API/SBDefines.h" +#include "lldb/API/SBType.h" +#include "lldb/API/SBTypeEnumMember.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" + +#include "clang/AST/Decl.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(); + + if (rhs.IsValid() == false) + return false; + + return *m_opaque_sp.get() == *rhs.m_opaque_sp.get(); +} + +bool +SBType::operator != (SBType &rhs) +{ + if (IsValid() == false) + return rhs.IsValid(); + + if (rhs.IsValid() == false) + return true; + + return *m_opaque_sp.get() != *rhs.m_opaque_sp.get(); +} + +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(false).GetByteSize(); + +} + +bool +SBType::IsPointerType() +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType(true).IsPointerType(); +} + +bool +SBType::IsArrayType() +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType(true).IsArrayType(nullptr, nullptr, nullptr); +} + +bool +SBType::IsReferenceType() +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType(true).IsReferenceType(); +} + +SBType +SBType::GetPointerType() +{ + if (!IsValid()) + return SBType(); + + return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointerType()))); +} + +SBType +SBType::GetPointeeType() +{ + if (!IsValid()) + return SBType(); + return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetPointeeType()))); +} + +SBType +SBType::GetReferenceType() +{ + if (!IsValid()) + return SBType(); + return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetReferenceType()))); +} + +SBType +SBType::GetTypedefedType() +{ + if (!IsValid()) + return SBType(); + return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetTypedefedType()))); +} + +SBType +SBType::GetDereferencedType() +{ + if (!IsValid()) + return SBType(); + return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetDereferencedType()))); +} + +SBType +SBType::GetArrayElementType() +{ + if (!IsValid()) + return SBType(); + return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetClangASTType(true).GetArrayElementType()))); +} + +bool +SBType::IsFunctionType () +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType(true).IsFunctionType(); +} + +bool +SBType::IsPolymorphicClass () +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType(true).IsPolymorphicClass(); +} + +bool +SBType::IsTypedefType () +{ + if (!IsValid()) + return false; + return m_opaque_sp->GetClangASTType(true).IsTypedefType(); +} + +lldb::SBType +SBType::GetFunctionReturnType () +{ + if (IsValid()) + { + ClangASTType return_clang_type (m_opaque_sp->GetClangASTType(true).GetFunctionReturnType()); + if (return_clang_type.IsValid()) + return SBType(return_clang_type); + } + return lldb::SBType(); +} + +lldb::SBTypeList +SBType::GetFunctionArgumentTypes () +{ + SBTypeList sb_type_list; + if (IsValid()) + { + ClangASTType func_type(m_opaque_sp->GetClangASTType(true)); + size_t count = func_type.GetNumberOfFunctionArguments(); + for (size_t i = 0; + i < count; + i++) + { + sb_type_list.Append(SBType(func_type.GetFunctionArgumentAtIndex(i))); + } + } + return sb_type_list; +} + +uint32_t +SBType::GetNumberOfMemberFunctions () +{ + if (IsValid()) + { + return m_opaque_sp->GetClangASTType(true).GetNumMemberFunctions(); + } + return 0; +} + +lldb::SBTypeMemberFunction +SBType::GetMemberFunctionAtIndex (uint32_t idx) +{ + SBTypeMemberFunction sb_func_type; + if (IsValid()) + sb_func_type.reset(new TypeMemberFunctionImpl(m_opaque_sp->GetClangASTType(true).GetMemberFunctionAtIndex(idx))); + return sb_func_type; +} + +lldb::SBType +SBType::GetUnqualifiedType() +{ + if (!IsValid()) + return SBType(); + return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetUnqualifiedType()))); +} + +lldb::SBType +SBType::GetCanonicalType() +{ + if (IsValid()) + return SBType(TypeImplSP(new TypeImpl(m_opaque_sp->GetCanonicalType()))); + return SBType(); +} + + +lldb::BasicType +SBType::GetBasicType() +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType(false).GetBasicTypeEnumeration (); + return eBasicTypeInvalid; +} + +SBType +SBType::GetBasicType(lldb::BasicType basic_type) +{ + if (IsValid()) + return SBType (ClangASTContext::GetBasicType (m_opaque_sp->GetClangASTContext(false), basic_type)); + return SBType(); +} + +uint32_t +SBType::GetNumberOfDirectBaseClasses () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType(true).GetNumDirectBaseClasses(); + return 0; +} + +uint32_t +SBType::GetNumberOfVirtualBaseClasses () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType(true).GetNumVirtualBaseClasses(); + return 0; +} + +uint32_t +SBType::GetNumberOfFields () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType(true).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 (true)); + 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 (true)); + 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; +} + +SBTypeEnumMemberList +SBType::GetEnumMembers () +{ + SBTypeEnumMemberList sb_enum_member_list; + if (IsValid()) + { + const clang::EnumDecl *enum_decl = m_opaque_sp->GetClangASTType(true).GetFullyUnqualifiedType().GetAsEnumDecl(); + if (enum_decl) + { + clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos; + for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos) + { + SBTypeEnumMember enum_member; + enum_member.reset(new TypeEnumMemberImpl(*enum_pos, ClangASTType(m_opaque_sp->GetClangASTContext(true), enum_decl->getIntegerType()))); + sb_enum_member_list.Append(enum_member); + } + } + } + return sb_enum_member_list; +} + +SBTypeMember +SBType::GetFieldAtIndex (uint32_t idx) +{ + SBTypeMember sb_type_member; + if (IsValid()) + { + ClangASTType this_type (m_opaque_sp->GetClangASTType (false)); + 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(false).IsCompleteType(); +} + +uint32_t +SBType::GetTypeFlags () +{ + if (!IsValid()) + return 0; + return m_opaque_sp->GetClangASTType(true).GetTypeInfo(); +} + +const char* +SBType::GetName() +{ + if (!IsValid()) + return ""; + return m_opaque_sp->GetName().GetCString(); +} + +const char * +SBType::GetDisplayTypeName () +{ + if (!IsValid()) + return ""; + return m_opaque_sp->GetDisplayTypeName().GetCString(); +} + +lldb::TypeClass +SBType::GetTypeClass () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType(true).GetTypeClass(); + return lldb::eTypeClassInvalid; +} + +uint32_t +SBType::GetNumberOfTemplateArguments () +{ + if (IsValid()) + return m_opaque_sp->GetClangASTType(false).GetNumTemplateArguments(); + return 0; +} + +lldb::SBType +SBType::GetTemplateArgumentType (uint32_t idx) +{ + if (IsValid()) + { + TemplateArgumentKind kind = eTemplateArgumentKindNull; + ClangASTType template_arg_type = m_opaque_sp->GetClangASTType(false).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(false).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(); +} + +SBTypeMemberFunction::SBTypeMemberFunction() : +m_opaque_sp() +{ +} + +SBTypeMemberFunction::~SBTypeMemberFunction() +{ +} + +SBTypeMemberFunction::SBTypeMemberFunction (const SBTypeMemberFunction& rhs) : + m_opaque_sp(rhs.m_opaque_sp) +{ +} + +lldb::SBTypeMemberFunction& +SBTypeMemberFunction::operator = (const lldb::SBTypeMemberFunction& rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +bool +SBTypeMemberFunction::IsValid() const +{ + return m_opaque_sp.get(); +} + +const char * +SBTypeMemberFunction::GetName () +{ + if (m_opaque_sp) + return m_opaque_sp->GetName().GetCString(); + return NULL; +} + +SBType +SBTypeMemberFunction::GetType () +{ + SBType sb_type; + if (m_opaque_sp) + { + sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetType()))); + } + return sb_type; +} + +lldb::SBType +SBTypeMemberFunction::GetReturnType () +{ + SBType sb_type; + if (m_opaque_sp) + { + sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetReturnType()))); + } + return sb_type; +} + +uint32_t +SBTypeMemberFunction::GetNumberOfArguments () +{ + if (m_opaque_sp) + return m_opaque_sp->GetNumArguments(); + return 0; +} + +lldb::SBType +SBTypeMemberFunction::GetArgumentTypeAtIndex (uint32_t i) +{ + SBType sb_type; + if (m_opaque_sp) + { + sb_type.SetSP(lldb::TypeImplSP(new TypeImpl(m_opaque_sp->GetArgumentAtIndex(i)))); + } + return sb_type; +} + +lldb::MemberFunctionKind +SBTypeMemberFunction::GetKind () +{ + if (m_opaque_sp) + return m_opaque_sp->GetKind(); + return lldb::eMemberFunctionKindUnknown; + +} + +bool +SBTypeMemberFunction::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + Stream &strm = description.ref(); + + if (m_opaque_sp) + return m_opaque_sp->GetDescription(strm); + + return false; +} + +void +SBTypeMemberFunction::reset(TypeMemberFunctionImpl *type_member_impl) +{ + m_opaque_sp.reset(type_member_impl); +} + +TypeMemberFunctionImpl & +SBTypeMemberFunction::ref () +{ + if (!m_opaque_sp) + m_opaque_sp.reset (new TypeMemberFunctionImpl()); + return *m_opaque_sp.get(); +} + +const TypeMemberFunctionImpl & +SBTypeMemberFunction::ref () const +{ + return *m_opaque_sp.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..9fe4dad --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeCategory.cpp @@ -0,0 +1,583 @@ +//===-- 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 (!IsValid()) + return 0; + + return m_opaque_sp->GetTypeFormatsContainer()->GetCount() + m_opaque_sp->GetRegexTypeFormatsContainer()->GetCount(); +} + +uint32_t +SBTypeCategory::GetNumSummaries () +{ + if (!IsValid()) + return 0; + return m_opaque_sp->GetTypeSummariesContainer()->GetCount() + m_opaque_sp->GetRegexTypeSummariesContainer()->GetCount(); +} + +uint32_t +SBTypeCategory::GetNumFilters () +{ + if (!IsValid()) + return 0; + return m_opaque_sp->GetTypeFiltersContainer()->GetCount() + m_opaque_sp->GetRegexTypeFiltersContainer()->GetCount(); +} + +#ifndef LLDB_DISABLE_PYTHON +uint32_t +SBTypeCategory::GetNumSynthetics () +{ + if (!IsValid()) + return 0; + return m_opaque_sp->GetTypeSyntheticsContainer()->GetCount() + m_opaque_sp->GetRegexTypeSyntheticsContainer()->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 (!IsValid()) + return SBTypeNameSpecifier(); + return SBTypeNameSpecifier(m_opaque_sp->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->GetRegexTypeFiltersContainer()->GetExact(ConstString(spec.GetName()), children_sp); + else + m_opaque_sp->GetTypeFiltersContainer()->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 (!IsValid()) + return SBTypeFormat(); + + if (!spec.IsValid()) + return SBTypeFormat(); + + lldb::TypeFormatImplSP format_sp; + + if (spec.IsRegex()) + m_opaque_sp->GetRegexTypeFormatsContainer()->GetExact(ConstString(spec.GetName()), format_sp); + else + m_opaque_sp->GetTypeFormatsContainer()->GetExact(ConstString(spec.GetName()), format_sp); + + if (!format_sp) + return lldb::SBTypeFormat(); + + return lldb::SBTypeFormat(format_sp); +} + +#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->GetRegexTypeSummariesContainer()->GetExact(ConstString(spec.GetName()), summary_sp); + else + m_opaque_sp->GetTypeSummariesContainer()->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->GetRegexTypeSyntheticsContainer()->GetExact(ConstString(spec.GetName()), children_sp); + else + m_opaque_sp->GetTypeSyntheticsContainer()->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 (!IsValid()) + return SBTypeFormat(); + return SBTypeFormat(m_opaque_sp->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 (!IsValid()) + return false; + + if (!type_name.IsValid()) + return false; + + if (!format.IsValid()) + return false; + + if (type_name.IsRegex()) + m_opaque_sp->GetRegexTypeFormatsContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), format.GetSP()); + else + m_opaque_sp->GetTypeFormatsContainer()->Add(ConstString(type_name.GetName()), format.GetSP()); + + return true; +} + +bool +SBTypeCategory::DeleteTypeFormat (SBTypeNameSpecifier type_name) +{ + if (!IsValid()) + return false; + + if (!type_name.IsValid()) + return false; + + if (type_name.IsRegex()) + return m_opaque_sp->GetRegexTypeFormatsContainer()->Delete(ConstString(type_name.GetName())); + else + return m_opaque_sp->GetTypeFormatsContainer()->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->GetRegexTypeSummariesContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), summary.GetSP()); + else + m_opaque_sp->GetTypeSummariesContainer()->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->GetRegexTypeSummariesContainer()->Delete(ConstString(type_name.GetName())); + else + return m_opaque_sp->GetTypeSummariesContainer()->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->GetRegexTypeFiltersContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), filter.GetSP()); + else + m_opaque_sp->GetTypeFiltersContainer()->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->GetRegexTypeFiltersContainer()->Delete(ConstString(type_name.GetName())); + else + return m_opaque_sp->GetTypeFiltersContainer()->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->GetRegexTypeSyntheticsContainer()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), synth.GetSP()); + else + m_opaque_sp->GetTypeSyntheticsContainer()->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->GetRegexTypeSyntheticsContainer()->Delete(ConstString(type_name.GetName())); + else + return m_opaque_sp->GetTypeSyntheticsContainer()->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/SBTypeEnumMember.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeEnumMember.cpp new file mode 100644 index 0000000..47c57dd --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeEnumMember.cpp @@ -0,0 +1,192 @@ +//===-- SBTypeEnumMember.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/SBDefines.h" +#include "lldb/API/SBType.h" +#include "lldb/API/SBTypeEnumMember.h" +#include "lldb/API/SBStream.h" +#include "lldb/Core/Stream.h" +#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/Type.h" + +using namespace lldb; +using namespace lldb_private; +using namespace clang; + +SBTypeEnumMember::SBTypeEnumMember() : + m_opaque_sp() +{ +} + +SBTypeEnumMember::~SBTypeEnumMember() +{ +} +SBTypeEnumMember::SBTypeEnumMember (const lldb::TypeEnumMemberImplSP &enum_member_sp) : + m_opaque_sp(enum_member_sp) +{ +} + +SBTypeEnumMember::SBTypeEnumMember (const SBTypeEnumMember& rhs) : + m_opaque_sp() +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_sp.reset(new TypeEnumMemberImpl(rhs.ref())); + } +} + +SBTypeEnumMember& +SBTypeEnumMember::operator = (const SBTypeEnumMember& rhs) +{ + if (this != &rhs) + { + if (rhs.IsValid()) + m_opaque_sp.reset(new TypeEnumMemberImpl(rhs.ref())); + } + return *this; +} + +bool +SBTypeEnumMember::IsValid() const +{ + return m_opaque_sp.get(); +} + +const char * +SBTypeEnumMember::GetName () +{ + if (m_opaque_sp.get()) + return m_opaque_sp->GetName().GetCString(); + return NULL; +} + +int64_t +SBTypeEnumMember::GetValueAsSigned() +{ + if (m_opaque_sp.get()) + return m_opaque_sp->GetValueAsSigned(); + return 0; +} + +uint64_t +SBTypeEnumMember::GetValueAsUnsigned() +{ + if (m_opaque_sp.get()) + return m_opaque_sp->GetValueAsUnsigned(); + return 0; +} + +SBType +SBTypeEnumMember::GetType () +{ + SBType sb_type; + if (m_opaque_sp.get()) + { + sb_type.SetSP(m_opaque_sp->GetIntegerType()); + } + return sb_type; + +} + +void +SBTypeEnumMember::reset(TypeEnumMemberImpl *type_member_impl) +{ + m_opaque_sp.reset(type_member_impl); +} + +TypeEnumMemberImpl & +SBTypeEnumMember::ref () +{ + if (m_opaque_sp.get() == NULL) + m_opaque_sp.reset (new TypeEnumMemberImpl()); + return *m_opaque_sp.get(); +} + +const TypeEnumMemberImpl & +SBTypeEnumMember::ref () const +{ + return *m_opaque_sp.get(); +} + + +SBTypeEnumMemberList::SBTypeEnumMemberList() : + m_opaque_ap(new TypeEnumMemberListImpl()) +{ +} + +SBTypeEnumMemberList::SBTypeEnumMemberList(const SBTypeEnumMemberList& rhs) : + m_opaque_ap(new TypeEnumMemberListImpl()) +{ + for (uint32_t i = 0, rhs_size = const_cast<SBTypeEnumMemberList&>(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast<SBTypeEnumMemberList&>(rhs).GetTypeEnumMemberAtIndex(i)); +} + +bool +SBTypeEnumMemberList::IsValid () +{ + return (m_opaque_ap.get() != NULL); +} + +SBTypeEnumMemberList& +SBTypeEnumMemberList::operator = (const SBTypeEnumMemberList& rhs) +{ + if (this != &rhs) + { + m_opaque_ap.reset (new TypeEnumMemberListImpl()); + for (uint32_t i = 0, rhs_size = const_cast<SBTypeEnumMemberList&>(rhs).GetSize(); i < rhs_size; i++) + Append(const_cast<SBTypeEnumMemberList&>(rhs).GetTypeEnumMemberAtIndex(i)); + } + return *this; +} + +void +SBTypeEnumMemberList::Append (SBTypeEnumMember enum_member) +{ + if (enum_member.IsValid()) + m_opaque_ap->Append (enum_member.m_opaque_sp); +} + +SBTypeEnumMember +SBTypeEnumMemberList::GetTypeEnumMemberAtIndex(uint32_t index) +{ + if (m_opaque_ap.get()) + return SBTypeEnumMember(m_opaque_ap->GetTypeEnumMemberAtIndex(index)); + return SBTypeEnumMember(); +} + +uint32_t +SBTypeEnumMemberList::GetSize() +{ + return m_opaque_ap->GetSize(); +} + +SBTypeEnumMemberList::~SBTypeEnumMemberList() +{ +} + +bool +SBTypeEnumMember::GetDescription (lldb::SBStream &description, + lldb::DescriptionLevel description_level) +{ + Stream &strm = description.ref(); + + if (m_opaque_sp.get()) + { + if( m_opaque_sp->GetIntegerType()->GetDescription(strm, description_level) ) + { + strm.Printf(" %s", m_opaque_sp->GetName().GetCString()); + } + } + else + { + strm.PutCString ("No value"); + } + return true; +} 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..d3ec9bc --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeFormat.cpp @@ -0,0 +1,193 @@ +//===-- 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(format,options))) +{ +} + +SBTypeFormat::SBTypeFormat (const char* type, + uint32_t options) +: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl_EnumType(ConstString(type ? type : ""),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() && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat) + return ((TypeFormatImpl_Format*)m_opaque_sp.get())->GetFormat(); + return lldb::eFormatInvalid; +} + +const char* +SBTypeFormat::GetTypeName () +{ + if (IsValid() && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeEnum) + return ((TypeFormatImpl_EnumType*)m_opaque_sp.get())->GetTypeName().AsCString(""); + return ""; +} + +uint32_t +SBTypeFormat::GetOptions() +{ + if (IsValid()) + return m_opaque_sp->GetOptions(); + return 0; +} + +void +SBTypeFormat::SetFormat (lldb::Format fmt) +{ + if (CopyOnWrite_Impl(Type::eTypeFormat)) + ((TypeFormatImpl_Format*)m_opaque_sp.get())->SetFormat(fmt); +} + +void +SBTypeFormat::SetTypeName (const char* type) +{ + if (CopyOnWrite_Impl(Type::eTypeEnum)) + ((TypeFormatImpl_EnumType*)m_opaque_sp.get())->SetTypeName(ConstString(type ? type : "")); +} + +void +SBTypeFormat::SetOptions (uint32_t value) +{ + if (CopyOnWrite_Impl(Type::eTypeKeepSame)) + 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(Type type) +{ + if (!IsValid()) + return false; + + if (m_opaque_sp.unique() && + ((type == Type::eTypeKeepSame) || + (type == Type::eTypeFormat && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat) || + (type == Type::eTypeEnum && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeEnum)) + ) + return true; + + if (type == Type::eTypeKeepSame) + { + if (m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat) + type = Type::eTypeFormat; + else + type = Type::eTypeEnum; + } + + if (type == Type::eTypeFormat) + SetSP(TypeFormatImplSP(new TypeFormatImpl_Format(GetFormat(),GetOptions()))); + else + SetSP(TypeFormatImplSP(new TypeFormatImpl_EnumType(ConstString(GetTypeName()),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..3d03c6a --- /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(true))); +} + +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..8a235bf --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBTypeSummary.cpp @@ -0,0 +1,432 @@ +//===-- 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 + +SBTypeSummaryOptions::SBTypeSummaryOptions() +{ + m_opaque_ap.reset(new TypeSummaryOptions()); +} + +SBTypeSummaryOptions::SBTypeSummaryOptions (const lldb::SBTypeSummaryOptions &rhs) +{ + if (rhs.m_opaque_ap) + m_opaque_ap.reset(new TypeSummaryOptions(*rhs.m_opaque_ap.get())); + else + m_opaque_ap.reset(new TypeSummaryOptions()); +} + +SBTypeSummaryOptions::~SBTypeSummaryOptions () +{ +} + +bool +SBTypeSummaryOptions::IsValid() +{ + return m_opaque_ap.get(); +} + +lldb::LanguageType +SBTypeSummaryOptions::GetLanguage () +{ + if (IsValid()) + return m_opaque_ap->GetLanguage(); + return lldb::eLanguageTypeUnknown; +} + +lldb::TypeSummaryCapping +SBTypeSummaryOptions::GetCapping () +{ + if (IsValid()) + return m_opaque_ap->GetCapping(); + return eTypeSummaryCapped; +} + +void +SBTypeSummaryOptions::SetLanguage (lldb::LanguageType l) +{ + if (IsValid()) + m_opaque_ap->SetLanguage(l); +} + +void +SBTypeSummaryOptions::SetCapping (lldb::TypeSummaryCapping c) +{ + if (IsValid()) + m_opaque_ap->SetCapping(c); +} + +lldb_private::TypeSummaryOptions * +SBTypeSummaryOptions::operator->() +{ + return m_opaque_ap.get(); +} + +const lldb_private::TypeSummaryOptions * +SBTypeSummaryOptions::operator->() const +{ + return m_opaque_ap.get(); +} + +lldb_private::TypeSummaryOptions * +SBTypeSummaryOptions::get () +{ + return m_opaque_ap.get(); +} + +lldb_private::TypeSummaryOptions & +SBTypeSummaryOptions::ref() +{ + return *m_opaque_ap.get(); +} + +const lldb_private::TypeSummaryOptions & +SBTypeSummaryOptions::ref() const +{ + return *m_opaque_ap.get(); +} + +SBTypeSummaryOptions::SBTypeSummaryOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr) +{ + SetOptions(lldb_object_ptr); +} + +void +SBTypeSummaryOptions::SetOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr) +{ + if (lldb_object_ptr) + m_opaque_ap.reset(new TypeSummaryOptions(*lldb_object_ptr)); + else + m_opaque_ap.reset(new TypeSummaryOptions()); +} + +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/SBUnixSignals.cpp b/contrib/llvm/tools/lldb/source/API/SBUnixSignals.cpp new file mode 100644 index 0000000..ca321d8 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBUnixSignals.cpp @@ -0,0 +1,199 @@ +//===-- SBUnixSignals.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-defines.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/UnixSignals.h" +#include "lldb/Core/Log.h" + +#include "lldb/API/SBUnixSignals.h" + +using namespace lldb; +using namespace lldb_private; + +SBUnixSignals::SBUnixSignals () +{} + +SBUnixSignals::SBUnixSignals (const SBUnixSignals &rhs) : + m_opaque_wp(rhs.m_opaque_wp) +{ +} + +SBUnixSignals::SBUnixSignals (ProcessSP &process_sp) : + m_opaque_wp(process_sp) +{ +} + +const SBUnixSignals& +SBUnixSignals::operator = (const SBUnixSignals& rhs) +{ + if (this != &rhs) + m_opaque_wp = rhs.m_opaque_wp; + return *this; +} + +SBUnixSignals::~SBUnixSignals() +{ +} + +ProcessSP +SBUnixSignals::GetSP() const +{ + return m_opaque_wp.lock(); +} + +void +SBUnixSignals::SetSP (const ProcessSP &process_sp) +{ + m_opaque_wp = process_sp; +} + +void +SBUnixSignals::Clear () +{ + m_opaque_wp.reset(); +} + +bool +SBUnixSignals::IsValid() const +{ + return (bool) GetSP(); +} + +const char * +SBUnixSignals::GetSignalAsCString (int32_t signo) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetSignalAsCString(signo); + return NULL; +} + +int32_t +SBUnixSignals::GetSignalNumberFromName (const char *name) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetSignalNumberFromName(name); + return -1; +} + +bool +SBUnixSignals::GetShouldSuppress (int32_t signo) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetShouldSuppress(signo); + return false; +} + +bool +SBUnixSignals::SetShouldSuppress (int32_t signo, bool value) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ProcessSP process_sp(GetSP()); + + if (log) + { + log->Printf ("SBUnixSignals(%p)::SetShouldSuppress (signo=%d, value=%d)", + static_cast<void*>(process_sp.get()), + signo, + value); + } + + if (process_sp) return process_sp->GetUnixSignals().SetShouldSuppress(signo, value); + return false; +} + +bool +SBUnixSignals::GetShouldStop (int32_t signo) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetShouldStop(signo); + return false; +} + +bool +SBUnixSignals::SetShouldStop (int32_t signo, bool value) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ProcessSP process_sp(GetSP()); + + if (log) + { + log->Printf ("SBUnixSignals(%p)::SetShouldStop (signo=%d, value=%d)", + static_cast<void*>(process_sp.get()), + signo, + value); + } + + if (process_sp) return process_sp->GetUnixSignals().SetShouldStop(signo, value); + return false; +} + +bool +SBUnixSignals::GetShouldNotify (int32_t signo) const +{ + ProcessSP process_sp(GetSP()); + if (process_sp) return process_sp->GetUnixSignals().GetShouldNotify(signo); + return false; +} + +bool +SBUnixSignals::SetShouldNotify (int32_t signo, bool value) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ProcessSP process_sp(GetSP()); + + if (log) + { + log->Printf ("SBUnixSignals(%p)::SetShouldNotify (signo=%d, value=%d)", + static_cast<void*>(process_sp.get()), + signo, + value); + } + + if (process_sp) return process_sp->GetUnixSignals().SetShouldNotify(signo, value); + return false; +} + +int32_t +SBUnixSignals::GetNumSignals () const +{ + if (auto process_sp = GetSP()) + { + // only valid while we hold process_sp + UnixSignals *unix_signals_ptr = &process_sp->GetUnixSignals(); + int32_t num_signals = 0; + for (int32_t signo = unix_signals_ptr->GetFirstSignalNumber(); + signo != LLDB_INVALID_SIGNAL_NUMBER; + signo = unix_signals_ptr->GetNextSignalNumber(signo)) + { + num_signals++; + } + return num_signals; + } + return LLDB_INVALID_SIGNAL_NUMBER; +} + +int32_t +SBUnixSignals::GetSignalAtIndex (int32_t index) const +{ + if (auto process_sp = GetSP()) + { + // only valid while we hold process_sp + UnixSignals *unix_signals_ptr = &process_sp->GetUnixSignals(); + int32_t idx = 0; + for (int32_t signo = unix_signals_ptr->GetFirstSignalNumber(); + signo != LLDB_INVALID_SIGNAL_NUMBER; + signo = unix_signals_ptr->GetNextSignalNumber(signo)) + { + if (index == idx) return signo; + idx++; + } + } + return LLDB_INVALID_SIGNAL_NUMBER; +} 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..0d3d7ad --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBValue.cpp @@ -0,0 +1,1873 @@ +//===-- 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 () + { + if (m_valobj_sp.get() == NULL) + return false; + else + { + // FIXME: This check is necessary but not sufficient. We for sure don't want to touch SBValues whose owning + // targets have gone away. This check is a little weak in that it enforces that restriction when you call + // IsValid, but since IsValid doesn't lock the target, you have no guarantee that the SBValue won't go + // invalid after you call this... + // Also, an SBValue could depend on data from one of the modules in the target, and those could go away + // independently of the target, for instance if a module is unloaded. But right now, neither SBValues + // nor ValueObjects know which modules they depend on. So I have no good way to make that check without + // tracking that in all the ValueObject subclasses. + TargetSP target_sp = m_valobj_sp->GetTargetSP(); + if (target_sp && target_sp->IsValid()) + return true; + else + return false; + } + } + + 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()); + else + return ValueObjectSP(); + + 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", + static_cast<void*>(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->IsValid() && 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\"", + static_cast<void*>(value_sp.get()), name); + else + log->Printf ("SBValue(%p)::GetName () => NULL", + static_cast<void*>(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\"", + static_cast<void*>(value_sp.get()), name); + else + log->Printf ("SBValue(%p)::GetTypeName () => NULL", + static_cast<void*>(value_sp.get())); + } + + return name; +} + +const char * +SBValue::GetDisplayTypeName () +{ + 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->GetDisplayTypeName().GetCString(); + } + + if (log) + { + if (name) + log->Printf ("SBValue(%p)::GetTypeName () => \"%s\"", + static_cast<void*>(value_sp.get()), name); + else + log->Printf ("SBValue(%p)::GetTypeName () => NULL", + static_cast<void*>(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, + static_cast<void*>(value_sp.get()), + static_cast<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", + static_cast<void*>(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\"", + static_cast<void*>(value_sp.get()), cstr); + else + log->Printf ("SBValue(%p)::GetValue() => NULL", + static_cast<void*>(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", + static_cast<void*>(value_sp.get())); + break; + case eValueTypeVariableGlobal: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableGlobal", + static_cast<void*>(value_sp.get())); + break; + case eValueTypeVariableStatic: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableStatic", + static_cast<void*>(value_sp.get())); + break; + case eValueTypeVariableArgument: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableArgument", + static_cast<void*>(value_sp.get())); + break; + case eValueTypeVariableLocal: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeVariableLocal", + static_cast<void*>(value_sp.get())); + break; + case eValueTypeRegister: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", + static_cast<void*>(value_sp.get())); + break; + case eValueTypeRegisterSet: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", + static_cast<void*>(value_sp.get())); + break; + case eValueTypeConstResult: + log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", + static_cast<void*>(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\"", + static_cast<void*>(value_sp.get()), cstr); + else + log->Printf ("SBValue(%p)::GetObjectDescription() => NULL", + static_cast<void*>(value_sp.get())); + } + return cstr; +} + +const char * +SBValue::GetTypeValidatorResult () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + const char *cstr = NULL; + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + const auto& validation(value_sp->GetValidationStatus()); + if (TypeValidatorResult::Failure == validation.first) + { + if (validation.second.empty()) + cstr = "unknown error"; + else + cstr = validation.second.c_str(); + } + } + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetTypeValidatorResult() => \"%s\"", + static_cast<void*>(value_sp.get()), cstr); + else + log->Printf ("SBValue(%p)::GetTypeValidatorResult() => NULL", + static_cast<void*>(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->GetTypeImpl())); + sb_type.SetSP(type_sp); + } + if (log) + { + if (type_sp) + log->Printf ("SBValue(%p)::GetType => SBType(%p)", + static_cast<void*>(value_sp.get()), + static_cast<void*>(type_sp.get())); + else + log->Printf ("SBValue(%p)::GetType => NULL", + static_cast<void*>(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", + static_cast<void*>(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\"", + static_cast<void*>(value_sp.get()), cstr); + else + log->Printf ("SBValue(%p)::GetSummary() => NULL", + static_cast<void*>(value_sp.get())); + } + return cstr; +} + +const char * +SBValue::GetSummary (lldb::SBStream& stream, + lldb::SBTypeSummaryOptions& options) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + std::string buffer; + if (value_sp->GetSummaryAsCString(buffer,options.ref()) && !buffer.empty()) + stream.Printf("%s",buffer.c_str()); + } + const char* cstr = stream.GetData(); + if (log) + { + if (cstr) + log->Printf ("SBValue(%p)::GetSummary() => \"%s\"", + static_cast<void*>(value_sp.get()), cstr); + else + log->Printf ("SBValue(%p)::GetSummary() => NULL", + static_cast<void*>(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\"", + static_cast<void*>(value_sp.get()), cstr); + else + log->Printf ("SBValue(%p)::GetLocation() => NULL", + static_cast<void*>(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", + static_cast<void*>(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(false), true),GetPreferDynamicValue(),GetPreferSyntheticValue(), name); + } + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + { + if (new_value_sp) + log->Printf ("SBValue(%p)::CreateChildAtOffset => \"%s\"", + static_cast<void*>(value_sp.get()), + new_value_sp->GetName().AsCString()); + else + log->Printf ("SBValue(%p)::CreateChildAtOffset => NULL", + static_cast<void*>(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(false)),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()); + new_value_sp = ValueObject::CreateValueObjectFromExpression(name, expression, exe_ctx, 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)", + static_cast<void*>(value_sp.get()), name, expression, + static_cast<void*>(new_value_sp.get())); + else + log->Printf ("SBValue(%p)::CreateValueFromExpression(name=\"%s\", expression=\"%s\") => NULL", + static_cast<void*>(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 ast_type(type_impl_sp->GetClangASTType(true)); + ExecutionContext exe_ctx (value_sp->GetExecutionContextRef()); + new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address, exe_ctx, ast_type); + } + 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\"", + static_cast<void*>(value_sp.get()), + new_value_sp->GetName().AsCString()); + else + log->Printf ("SBValue(%p)::CreateValueFromAddress => NULL", + static_cast<void*>(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 = ValueObject::CreateValueObjectFromData(name, **data, exe_ctx, type.GetSP()->GetClangASTType(true)); + 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\"", + static_cast<void*>(value_sp.get()), + new_value_sp->GetName().AsCString()); + else + log->Printf ("SBValue(%p)::CreateValueFromData => NULL", + static_cast<void*>(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)", + static_cast<void*>(value_sp.get()), idx, + static_cast<void*>(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", + static_cast<void*>(value_sp.get()), name); + else + log->Printf ("SBValue(%p)::GetIndexOfChildWithName (name=\"%s\") => %u", + static_cast<void*>(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)", + static_cast<void*>(value_sp.get()), name, + static_cast<void*>(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)", + static_cast<void*>(value_sp.get()), expr_path, + static_cast<void*>(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) + { + bool success = true; + uint64_t ret_val = fail_value; + ret_val = value_sp->GetValueAsSigned(fail_value, &success); + if (!success) + error.SetErrorString("could not resolve value"); + return ret_val; + } + 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) + { + bool success = true; + uint64_t ret_val = fail_value; + ret_val = value_sp->GetValueAsUnsigned(fail_value, &success); + if (!success) + error.SetErrorString("could not resolve value"); + return ret_val; + } + 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) + { + return value_sp->GetValueAsSigned(fail_value); + } + return fail_value; +} + +uint64_t +SBValue::GetValueAsUnsigned(uint64_t fail_value) +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + if (value_sp) + { + return value_sp->GetValueAsUnsigned(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", + static_cast<void*>(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", + static_cast<void*>(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)", + static_cast<void*>(value_sp.get()), + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(m_opaque_sp.get())); + else + log->Printf ("SBValue(%p)::GetTarget () => %p", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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", + static_cast<void*>(m_opaque_sp.get())); + else + log->Printf ("SBValue(%p)::GetProcess () => %p", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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", + static_cast<void*>(m_opaque_sp.get())); + else + log->Printf ("SBValue(%p)::GetThread () => %p", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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", + static_cast<void*>(m_opaque_sp.get())); + else + log->Printf ("SBValue(%p)::GetFrame () => %p", + static_cast<void*>(m_opaque_sp.get()), + static_cast<void*>(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) + value_sp->Dump(strm); + 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)", + static_cast<void*>(value_sp.get()), + static_cast<void*>(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 ")", + static_cast<void*>(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 ")", + static_cast<void*>(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)", + static_cast<void*>(value_sp.get()), item_idx, item_count, + static_cast<void*>(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()); + Error error; + value_sp->GetData(*data_sp, error); + if (error.Success()) + *sb_data = data_sp; + } + if (log) + log->Printf ("SBValue(%p)::GetData () => SBData(%p)", + static_cast<void*>(value_sp.get()), + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(value_sp.get()), + static_cast<void*>(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", + static_cast<void*>(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", + static_cast<void*>(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; +} + +lldb::SBValue +SBValue::Persist () +{ + ValueLocker locker; + lldb::ValueObjectSP value_sp(GetSP(locker)); + SBValue persisted_sb; + if (value_sp) + { + persisted_sb.SetSP(value_sp->Persist()); + } + return persisted_sb; +} 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..71fabe0 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBValueList.cpp @@ -0,0 +1,301 @@ +//===-- 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(); + } + + lldb::SBValue + GetFirstValueByName (const char* name) const + { + if (name) + { + for (auto val : m_values) + { + if (val.IsValid() && val.GetName() && + strcmp(name,val.GetName()) == 0) + 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", + static_cast<void*>(rhs.IsValid() ? rhs.m_opaque_ap.get() : NULL), + static_cast<void*>(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", + static_cast<const void*>(lldb_object_ptr), + static_cast<void*>(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')", + static_cast<void*>(m_opaque_ap.get()), idx, + static_cast<void*>(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", + static_cast<void*>(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; +} + +SBValue +SBValueList::GetFirstValueByName (const char* name) const +{ + SBValue sb_value; + if (m_opaque_ap.get()) + sb_value = m_opaque_ap->GetFirstValueByName(name); + 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..1a1a970 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBWatchpoint.cpp @@ -0,0 +1,303 @@ +//===-- 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)", + static_cast<void*>(wp_sp.get()), + static_cast<void*>(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", + static_cast<void*>(watchpoint_sp.get())); + else + log->Printf ("SBWatchpoint(%p)::GetID () => %u", + static_cast<void*>(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", + static_cast<void*>(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; +} |