|  | //===-- SBTarget.cpp --------------------------------------------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "lldb/lldb-python.h" | 
|  |  | 
|  | #include "lldb/API/SBTarget.h" | 
|  |  | 
|  | #include "lldb/lldb-public.h" | 
|  |  | 
|  | #include "lldb/API/SBDebugger.h" | 
|  | #include "lldb/API/SBBreakpoint.h" | 
|  | #include "lldb/API/SBExpressionOptions.h" | 
|  | #include "lldb/API/SBFileSpec.h" | 
|  | #include "lldb/API/SBListener.h" | 
|  | #include "lldb/API/SBModule.h" | 
|  | #include "lldb/API/SBModuleSpec.h" | 
|  | #include "lldb/API/SBSourceManager.h" | 
|  | #include "lldb/API/SBProcess.h" | 
|  | #include "lldb/API/SBStream.h" | 
|  | #include "lldb/API/SBSymbolContextList.h" | 
|  | #include "lldb/Breakpoint/BreakpointID.h" | 
|  | #include "lldb/Breakpoint/BreakpointIDList.h" | 
|  | #include "lldb/Breakpoint/BreakpointList.h" | 
|  | #include "lldb/Breakpoint/BreakpointLocation.h" | 
|  | #include "lldb/Core/Address.h" | 
|  | #include "lldb/Core/AddressResolver.h" | 
|  | #include "lldb/Core/AddressResolverName.h" | 
|  | #include "lldb/Core/ArchSpec.h" | 
|  | #include "lldb/Core/Debugger.h" | 
|  | #include "lldb/Core/Disassembler.h" | 
|  | #include "lldb/Core/Log.h" | 
|  | #include "lldb/Core/Module.h" | 
|  | #include "lldb/Core/ModuleSpec.h" | 
|  | #include "lldb/Core/RegularExpression.h" | 
|  | #include "lldb/Core/SearchFilter.h" | 
|  | #include "lldb/Core/Section.h" | 
|  | #include "lldb/Core/STLUtils.h" | 
|  | #include "lldb/Core/ValueObjectList.h" | 
|  | #include "lldb/Core/ValueObjectVariable.h" | 
|  | #include "lldb/Host/FileSpec.h" | 
|  | #include "lldb/Host/Host.h" | 
|  | #include "lldb/Interpreter/Args.h" | 
|  | #include "lldb/Symbol/ObjectFile.h" | 
|  | #include "lldb/Symbol/SymbolVendor.h" | 
|  | #include "lldb/Symbol/VariableList.h" | 
|  | #include "lldb/Target/LanguageRuntime.h" | 
|  | #include "lldb/Target/Process.h" | 
|  | #include "lldb/Target/Target.h" | 
|  | #include "lldb/Target/TargetList.h" | 
|  |  | 
|  | #include "lldb/Interpreter/CommandReturnObject.h" | 
|  | #include "../source/Commands/CommandObjectBreakpoint.h" | 
|  |  | 
|  |  | 
|  | using namespace lldb; | 
|  | using namespace lldb_private; | 
|  |  | 
|  | #define DEFAULT_DISASM_BYTE_SIZE 32 | 
|  |  | 
|  | SBLaunchInfo::SBLaunchInfo (const char **argv) : | 
|  | m_opaque_sp(new ProcessLaunchInfo()) | 
|  | { | 
|  | m_opaque_sp->GetFlags().Reset (eLaunchFlagDebug | eLaunchFlagDisableASLR); | 
|  | if (argv && argv[0]) | 
|  | m_opaque_sp->GetArguments().SetArguments(argv); | 
|  | } | 
|  |  | 
|  | SBLaunchInfo::~SBLaunchInfo() | 
|  | { | 
|  | } | 
|  |  | 
|  | lldb_private::ProcessLaunchInfo & | 
|  | SBLaunchInfo::ref () | 
|  | { | 
|  | return *m_opaque_sp; | 
|  | } | 
|  |  | 
|  |  | 
|  | uint32_t | 
|  | SBLaunchInfo::GetUserID() | 
|  | { | 
|  | return m_opaque_sp->GetUserID(); | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBLaunchInfo::GetGroupID() | 
|  | { | 
|  | return m_opaque_sp->GetGroupID(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBLaunchInfo::UserIDIsValid () | 
|  | { | 
|  | return m_opaque_sp->UserIDIsValid(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBLaunchInfo::GroupIDIsValid () | 
|  | { | 
|  | return m_opaque_sp->GroupIDIsValid(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::SetUserID (uint32_t uid) | 
|  | { | 
|  | m_opaque_sp->SetUserID (uid); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::SetGroupID (uint32_t gid) | 
|  | { | 
|  | m_opaque_sp->SetGroupID (gid); | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBLaunchInfo::GetNumArguments () | 
|  | { | 
|  | return m_opaque_sp->GetArguments().GetArgumentCount(); | 
|  | } | 
|  |  | 
|  | const char * | 
|  | SBLaunchInfo::GetArgumentAtIndex (uint32_t idx) | 
|  | { | 
|  | return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::SetArguments (const char **argv, bool append) | 
|  | { | 
|  | if (append) | 
|  | { | 
|  | if (argv) | 
|  | m_opaque_sp->GetArguments().AppendArguments(argv); | 
|  | } | 
|  | else | 
|  | { | 
|  | if (argv) | 
|  | m_opaque_sp->GetArguments().SetArguments(argv); | 
|  | else | 
|  | m_opaque_sp->GetArguments().Clear(); | 
|  | } | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBLaunchInfo::GetNumEnvironmentEntries () | 
|  | { | 
|  | return m_opaque_sp->GetEnvironmentEntries().GetArgumentCount(); | 
|  | } | 
|  |  | 
|  | const char * | 
|  | SBLaunchInfo::GetEnvironmentEntryAtIndex (uint32_t idx) | 
|  | { | 
|  | return m_opaque_sp->GetEnvironmentEntries().GetArgumentAtIndex(idx); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::SetEnvironmentEntries (const char **envp, bool append) | 
|  | { | 
|  | if (append) | 
|  | { | 
|  | if (envp) | 
|  | m_opaque_sp->GetEnvironmentEntries().AppendArguments(envp); | 
|  | } | 
|  | else | 
|  | { | 
|  | if (envp) | 
|  | m_opaque_sp->GetEnvironmentEntries().SetArguments(envp); | 
|  | else | 
|  | m_opaque_sp->GetEnvironmentEntries().Clear(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::Clear () | 
|  | { | 
|  | m_opaque_sp->Clear(); | 
|  | } | 
|  |  | 
|  | const char * | 
|  | SBLaunchInfo::GetWorkingDirectory () const | 
|  | { | 
|  | return m_opaque_sp->GetWorkingDirectory(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::SetWorkingDirectory (const char *working_dir) | 
|  | { | 
|  | m_opaque_sp->SetWorkingDirectory(working_dir); | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBLaunchInfo::GetLaunchFlags () | 
|  | { | 
|  | return m_opaque_sp->GetFlags().Get(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::SetLaunchFlags (uint32_t flags) | 
|  | { | 
|  | m_opaque_sp->GetFlags().Reset(flags); | 
|  | } | 
|  |  | 
|  | const char * | 
|  | SBLaunchInfo::GetProcessPluginName () | 
|  | { | 
|  | return m_opaque_sp->GetProcessPluginName(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::SetProcessPluginName (const char *plugin_name) | 
|  | { | 
|  | return m_opaque_sp->SetProcessPluginName (plugin_name); | 
|  | } | 
|  |  | 
|  | const char * | 
|  | SBLaunchInfo::GetShell () | 
|  | { | 
|  | return m_opaque_sp->GetShell(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::SetShell (const char * path) | 
|  | { | 
|  | m_opaque_sp->SetShell (path); | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBLaunchInfo::GetResumeCount () | 
|  | { | 
|  | return m_opaque_sp->GetResumeCount(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBLaunchInfo::SetResumeCount (uint32_t c) | 
|  | { | 
|  | m_opaque_sp->SetResumeCount (c); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBLaunchInfo::AddCloseFileAction (int fd) | 
|  | { | 
|  | return m_opaque_sp->AppendCloseFileAction(fd); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBLaunchInfo::AddDuplicateFileAction (int fd, int dup_fd) | 
|  | { | 
|  | return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBLaunchInfo::AddOpenFileAction (int fd, const char *path, bool read, bool write) | 
|  | { | 
|  | return m_opaque_sp->AppendOpenFileAction(fd, path, read, write); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBLaunchInfo::AddSuppressFileAction (int fd, bool read, bool write) | 
|  | { | 
|  | return m_opaque_sp->AppendSuppressFileAction(fd, read, write); | 
|  | } | 
|  |  | 
|  |  | 
|  | SBAttachInfo::SBAttachInfo () : | 
|  | m_opaque_sp (new ProcessAttachInfo()) | 
|  | { | 
|  | } | 
|  |  | 
|  | SBAttachInfo::SBAttachInfo (lldb::pid_t pid) : | 
|  | m_opaque_sp (new ProcessAttachInfo()) | 
|  | { | 
|  | m_opaque_sp->SetProcessID (pid); | 
|  | } | 
|  |  | 
|  | SBAttachInfo::SBAttachInfo (const char *path, bool wait_for) : | 
|  | m_opaque_sp (new ProcessAttachInfo()) | 
|  | { | 
|  | if (path && path[0]) | 
|  | m_opaque_sp->GetExecutableFile().SetFile(path, false); | 
|  | m_opaque_sp->SetWaitForLaunch (wait_for); | 
|  | } | 
|  |  | 
|  | SBAttachInfo::SBAttachInfo (const SBAttachInfo &rhs) : | 
|  | m_opaque_sp (new ProcessAttachInfo()) | 
|  | { | 
|  | *m_opaque_sp = *rhs.m_opaque_sp; | 
|  | } | 
|  |  | 
|  | SBAttachInfo::~SBAttachInfo() | 
|  | { | 
|  | } | 
|  |  | 
|  | lldb_private::ProcessAttachInfo & | 
|  | SBAttachInfo::ref () | 
|  | { | 
|  | return *m_opaque_sp; | 
|  | } | 
|  |  | 
|  | SBAttachInfo & | 
|  | SBAttachInfo::operator = (const SBAttachInfo &rhs) | 
|  | { | 
|  | if (this != &rhs) | 
|  | *m_opaque_sp = *rhs.m_opaque_sp; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | lldb::pid_t | 
|  | SBAttachInfo::GetProcessID () | 
|  | { | 
|  | return m_opaque_sp->GetProcessID(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetProcessID (lldb::pid_t pid) | 
|  | { | 
|  | m_opaque_sp->SetProcessID (pid); | 
|  | } | 
|  |  | 
|  |  | 
|  | uint32_t | 
|  | SBAttachInfo::GetResumeCount () | 
|  | { | 
|  | return m_opaque_sp->GetResumeCount(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetResumeCount (uint32_t c) | 
|  | { | 
|  | m_opaque_sp->SetResumeCount (c); | 
|  | } | 
|  |  | 
|  | const char * | 
|  | SBAttachInfo::GetProcessPluginName () | 
|  | { | 
|  | return m_opaque_sp->GetProcessPluginName(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetProcessPluginName (const char *plugin_name) | 
|  | { | 
|  | return m_opaque_sp->SetProcessPluginName (plugin_name); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetExecutable (const char *path) | 
|  | { | 
|  | if (path && path[0]) | 
|  | m_opaque_sp->GetExecutableFile().SetFile(path, false); | 
|  | else | 
|  | m_opaque_sp->GetExecutableFile().Clear(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetExecutable (SBFileSpec exe_file) | 
|  | { | 
|  | if (exe_file.IsValid()) | 
|  | m_opaque_sp->GetExecutableFile() = exe_file.ref(); | 
|  | else | 
|  | m_opaque_sp->GetExecutableFile().Clear(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBAttachInfo::GetWaitForLaunch () | 
|  | { | 
|  | return m_opaque_sp->GetWaitForLaunch(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetWaitForLaunch (bool b) | 
|  | { | 
|  | m_opaque_sp->SetWaitForLaunch (b); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBAttachInfo::GetIgnoreExisting () | 
|  | { | 
|  | return m_opaque_sp->GetIgnoreExisting(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetIgnoreExisting (bool b) | 
|  | { | 
|  | m_opaque_sp->SetIgnoreExisting (b); | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBAttachInfo::GetUserID() | 
|  | { | 
|  | return m_opaque_sp->GetUserID(); | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBAttachInfo::GetGroupID() | 
|  | { | 
|  | return m_opaque_sp->GetGroupID(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBAttachInfo::UserIDIsValid () | 
|  | { | 
|  | return m_opaque_sp->UserIDIsValid(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBAttachInfo::GroupIDIsValid () | 
|  | { | 
|  | return m_opaque_sp->GroupIDIsValid(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetUserID (uint32_t uid) | 
|  | { | 
|  | m_opaque_sp->SetUserID (uid); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetGroupID (uint32_t gid) | 
|  | { | 
|  | m_opaque_sp->SetGroupID (gid); | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBAttachInfo::GetEffectiveUserID() | 
|  | { | 
|  | return m_opaque_sp->GetEffectiveUserID(); | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBAttachInfo::GetEffectiveGroupID() | 
|  | { | 
|  | return m_opaque_sp->GetEffectiveGroupID(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBAttachInfo::EffectiveUserIDIsValid () | 
|  | { | 
|  | return m_opaque_sp->EffectiveUserIDIsValid(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBAttachInfo::EffectiveGroupIDIsValid () | 
|  | { | 
|  | return m_opaque_sp->EffectiveGroupIDIsValid (); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetEffectiveUserID (uint32_t uid) | 
|  | { | 
|  | m_opaque_sp->SetEffectiveUserID(uid); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetEffectiveGroupID (uint32_t gid) | 
|  | { | 
|  | m_opaque_sp->SetEffectiveGroupID(gid); | 
|  | } | 
|  |  | 
|  | lldb::pid_t | 
|  | SBAttachInfo::GetParentProcessID () | 
|  | { | 
|  | return m_opaque_sp->GetParentProcessID(); | 
|  | } | 
|  |  | 
|  | void | 
|  | SBAttachInfo::SetParentProcessID (lldb::pid_t pid) | 
|  | { | 
|  | m_opaque_sp->SetParentProcessID (pid); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBAttachInfo::ParentProcessIDIsValid() | 
|  | { | 
|  | return m_opaque_sp->ParentProcessIDIsValid(); | 
|  | } | 
|  |  | 
|  |  | 
|  | //---------------------------------------------------------------------- | 
|  | // SBTarget constructor | 
|  | //---------------------------------------------------------------------- | 
|  | SBTarget::SBTarget () : | 
|  | m_opaque_sp () | 
|  | { | 
|  | } | 
|  |  | 
|  | SBTarget::SBTarget (const SBTarget& rhs) : | 
|  | m_opaque_sp (rhs.m_opaque_sp) | 
|  | { | 
|  | } | 
|  |  | 
|  | SBTarget::SBTarget(const TargetSP& target_sp) : | 
|  | m_opaque_sp (target_sp) | 
|  | { | 
|  | } | 
|  |  | 
|  | const SBTarget& | 
|  | SBTarget::operator = (const SBTarget& rhs) | 
|  | { | 
|  | if (this != &rhs) | 
|  | m_opaque_sp = rhs.m_opaque_sp; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | //---------------------------------------------------------------------- | 
|  | // Destructor | 
|  | //---------------------------------------------------------------------- | 
|  | SBTarget::~SBTarget() | 
|  | { | 
|  | } | 
|  |  | 
|  | const char * | 
|  | SBTarget::GetBroadcasterClassName () | 
|  | { | 
|  | return Target::GetStaticBroadcasterClass().AsCString(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::IsValid () const | 
|  | { | 
|  | return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid(); | 
|  | } | 
|  |  | 
|  | SBProcess | 
|  | SBTarget::GetProcess () | 
|  | { | 
|  | SBProcess sb_process; | 
|  | ProcessSP process_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | process_sp = target_sp->GetProcessSP(); | 
|  | sb_process.SetSP (process_sp); | 
|  | } | 
|  |  | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)", | 
|  | target_sp.get(), process_sp.get()); | 
|  | } | 
|  |  | 
|  | return sb_process; | 
|  | } | 
|  |  | 
|  | SBDebugger | 
|  | SBTarget::GetDebugger () const | 
|  | { | 
|  | SBDebugger debugger; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | debugger.reset (target_sp->GetDebugger().shared_from_this()); | 
|  | return debugger; | 
|  | } | 
|  |  | 
|  | SBProcess | 
|  | SBTarget::LoadCore (const char *core_file) | 
|  | { | 
|  | SBProcess sb_process; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | FileSpec filespec(core_file, true); | 
|  | ProcessSP process_sp (target_sp->CreateProcess(target_sp->GetDebugger().GetListener(), | 
|  | NULL, | 
|  | &filespec)); | 
|  | if (process_sp) | 
|  | { | 
|  | process_sp->LoadCore(); | 
|  | sb_process.SetSP (process_sp); | 
|  | } | 
|  | } | 
|  | return sb_process; | 
|  | } | 
|  |  | 
|  | SBProcess | 
|  | SBTarget::LaunchSimple | 
|  | ( | 
|  | char const **argv, | 
|  | char const **envp, | 
|  | const char *working_directory | 
|  | ) | 
|  | { | 
|  | char *stdin_path = NULL; | 
|  | char *stdout_path = NULL; | 
|  | char *stderr_path = NULL; | 
|  | uint32_t launch_flags = 0; | 
|  | bool stop_at_entry = false; | 
|  | SBError error; | 
|  | SBListener listener = GetDebugger().GetListener(); | 
|  | return Launch (listener, | 
|  | argv, | 
|  | envp, | 
|  | stdin_path, | 
|  | stdout_path, | 
|  | stderr_path, | 
|  | working_directory, | 
|  | launch_flags, | 
|  | stop_at_entry, | 
|  | error); | 
|  | } | 
|  |  | 
|  | SBProcess | 
|  | SBTarget::Launch | 
|  | ( | 
|  | SBListener &listener, | 
|  | char const **argv, | 
|  | char const **envp, | 
|  | const char *stdin_path, | 
|  | const char *stdout_path, | 
|  | const char *stderr_path, | 
|  | const char *working_directory, | 
|  | uint32_t launch_flags,   // See LaunchFlags | 
|  | bool stop_at_entry, | 
|  | lldb::SBError& error | 
|  | ) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBProcess sb_process; | 
|  | ProcessSP process_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...", | 
|  | target_sp.get(), | 
|  | argv, | 
|  | envp, | 
|  | stdin_path ? stdin_path : "NULL", | 
|  | stdout_path ? stdout_path : "NULL", | 
|  | stderr_path ? stderr_path : "NULL", | 
|  | working_directory ? working_directory : "NULL", | 
|  | launch_flags, | 
|  | stop_at_entry, | 
|  | error.get()); | 
|  | } | 
|  |  | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  |  | 
|  | if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR")) | 
|  | launch_flags |= eLaunchFlagDisableASLR; | 
|  |  | 
|  | StateType state = eStateInvalid; | 
|  | process_sp = target_sp->GetProcessSP(); | 
|  | if (process_sp) | 
|  | { | 
|  | state = process_sp->GetState(); | 
|  |  | 
|  | if (process_sp->IsAlive() && state != eStateConnected) | 
|  | { | 
|  | if (state == eStateAttaching) | 
|  | error.SetErrorString ("process attach is in progress"); | 
|  | else | 
|  | error.SetErrorString ("a process is already being debugged"); | 
|  | return sb_process; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (state == eStateConnected) | 
|  | { | 
|  | // If we are already connected, then we have already specified the | 
|  | // listener, so if a valid listener is supplied, we need to error out | 
|  | // to let the client know. | 
|  | if (listener.IsValid()) | 
|  | { | 
|  | error.SetErrorString ("process is connected and already has a listener, pass empty listener"); | 
|  | return sb_process; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if (listener.IsValid()) | 
|  | process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL); | 
|  | else | 
|  | process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); | 
|  | } | 
|  |  | 
|  | if (process_sp) | 
|  | { | 
|  | sb_process.SetSP (process_sp); | 
|  | if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO")) | 
|  | launch_flags |= eLaunchFlagDisableSTDIO; | 
|  |  | 
|  | ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags); | 
|  |  | 
|  | Module *exe_module = target_sp->GetExecutableModulePointer(); | 
|  | if (exe_module) | 
|  | launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); | 
|  | if (argv) | 
|  | launch_info.GetArguments().AppendArguments (argv); | 
|  | if (envp) | 
|  | launch_info.GetEnvironmentEntries ().SetArguments (envp); | 
|  |  | 
|  | error.SetError (process_sp->Launch (launch_info)); | 
|  | if (error.Success()) | 
|  | { | 
|  | // We we are stopping at the entry point, we can return now! | 
|  | if (stop_at_entry) | 
|  | return sb_process; | 
|  |  | 
|  | // Make sure we are stopped at the entry | 
|  | StateType state = process_sp->WaitForProcessToStop (NULL); | 
|  | if (state == eStateStopped) | 
|  | { | 
|  | // resume the process to skip the entry point | 
|  | error.SetError (process_sp->Resume()); | 
|  | if (error.Success()) | 
|  | { | 
|  | // If we are doing synchronous mode, then wait for the | 
|  | // process to stop yet again! | 
|  | if (target_sp->GetDebugger().GetAsyncExecution () == false) | 
|  | process_sp->WaitForProcessToStop (NULL); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("unable to create lldb_private::Process"); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("SBTarget is invalid"); | 
|  | } | 
|  |  | 
|  | log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", | 
|  | target_sp.get(), process_sp.get()); | 
|  | } | 
|  |  | 
|  | return sb_process; | 
|  | } | 
|  |  | 
|  | SBProcess | 
|  | SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBProcess sb_process; | 
|  | ProcessSP process_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::Launch (launch_info, error)...", target_sp.get()); | 
|  | } | 
|  |  | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | StateType state = eStateInvalid; | 
|  | process_sp = target_sp->GetProcessSP(); | 
|  | if (process_sp) | 
|  | { | 
|  | state = process_sp->GetState(); | 
|  |  | 
|  | if (process_sp->IsAlive() && state != eStateConnected) | 
|  | { | 
|  | if (state == eStateAttaching) | 
|  | error.SetErrorString ("process attach is in progress"); | 
|  | else | 
|  | error.SetErrorString ("a process is already being debugged"); | 
|  | return sb_process; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (state != eStateConnected) | 
|  | process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); | 
|  |  | 
|  | if (process_sp) | 
|  | { | 
|  | sb_process.SetSP (process_sp); | 
|  | lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref(); | 
|  |  | 
|  | Module *exe_module = target_sp->GetExecutableModulePointer(); | 
|  | if (exe_module) | 
|  | launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); | 
|  |  | 
|  | const ArchSpec &arch_spec = target_sp->GetArchitecture(); | 
|  | if (arch_spec.IsValid()) | 
|  | launch_info.GetArchitecture () = arch_spec; | 
|  |  | 
|  | error.SetError (process_sp->Launch (launch_info)); | 
|  | const bool synchronous_execution = target_sp->GetDebugger().GetAsyncExecution () == false; | 
|  | if (error.Success()) | 
|  | { | 
|  | if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) | 
|  | { | 
|  | // If we are doing synchronous mode, then wait for the initial | 
|  | // stop to happen, else, return and let the caller watch for | 
|  | // the stop | 
|  | if (synchronous_execution) | 
|  | process_sp->WaitForProcessToStop (NULL); | 
|  | // We we are stopping at the entry point, we can return now! | 
|  | return sb_process; | 
|  | } | 
|  |  | 
|  | // Make sure we are stopped at the entry | 
|  | StateType state = process_sp->WaitForProcessToStop (NULL); | 
|  | if (state == eStateStopped) | 
|  | { | 
|  | // resume the process to skip the entry point | 
|  | error.SetError (process_sp->Resume()); | 
|  | if (error.Success()) | 
|  | { | 
|  | // If we are doing synchronous mode, then wait for the | 
|  | // process to stop yet again! | 
|  | if (synchronous_execution) | 
|  | process_sp->WaitForProcessToStop (NULL); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("unable to create lldb_private::Process"); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("SBTarget is invalid"); | 
|  | } | 
|  |  | 
|  | log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", | 
|  | target_sp.get(), process_sp.get()); | 
|  | } | 
|  |  | 
|  | return sb_process; | 
|  | } | 
|  |  | 
|  | lldb::SBProcess | 
|  | SBTarget::Attach (SBAttachInfo &sb_attach_info, SBError& error) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBProcess sb_process; | 
|  | ProcessSP process_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::Attach (sb_attach_info, error)...", target_sp.get()); | 
|  | } | 
|  |  | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  |  | 
|  | StateType state = eStateInvalid; | 
|  | process_sp = target_sp->GetProcessSP(); | 
|  | if (process_sp) | 
|  | { | 
|  | state = process_sp->GetState(); | 
|  |  | 
|  | if (process_sp->IsAlive() && state != eStateConnected) | 
|  | { | 
|  | if (state == eStateAttaching) | 
|  | error.SetErrorString ("process attach is in progress"); | 
|  | else | 
|  | error.SetErrorString ("a process is already being debugged"); | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::Attach (...) => error %s", | 
|  | target_sp.get(), error.GetCString()); | 
|  | } | 
|  | return sb_process; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (state != eStateConnected) | 
|  | process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); | 
|  |  | 
|  | if (process_sp) | 
|  | { | 
|  | ProcessAttachInfo &attach_info = sb_attach_info.ref(); | 
|  | if (attach_info.ProcessIDIsValid() && !attach_info.UserIDIsValid()) | 
|  | { | 
|  | PlatformSP platform_sp = target_sp->GetPlatform(); | 
|  | // See if we can pre-verify if a process exists or not | 
|  | if (platform_sp && platform_sp->IsConnected()) | 
|  | { | 
|  | lldb::pid_t attach_pid = attach_info.GetProcessID(); | 
|  | ProcessInstanceInfo instance_info; | 
|  | if (platform_sp->GetProcessInfo(attach_pid, instance_info)) | 
|  | { | 
|  | attach_info.SetUserID(instance_info.GetEffectiveUserID()); | 
|  | } | 
|  | else | 
|  | { | 
|  | error.ref().SetErrorStringWithFormat("no process found with process ID %" PRIu64, attach_pid); | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::Attach (...) => error %s", | 
|  | target_sp.get(), error.GetCString()); | 
|  | } | 
|  | return sb_process; | 
|  | } | 
|  | } | 
|  | } | 
|  | error.SetError (process_sp->Attach (attach_info)); | 
|  | if (error.Success()) | 
|  | { | 
|  | sb_process.SetSP (process_sp); | 
|  | // If we are doing synchronous mode, then wait for the | 
|  | // process to stop! | 
|  | if (target_sp->GetDebugger().GetAsyncExecution () == false) | 
|  | process_sp->WaitForProcessToStop (NULL); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("unable to create lldb_private::Process"); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("SBTarget is invalid"); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::Attach (...) => SBProcess(%p)", | 
|  | target_sp.get(), process_sp.get()); | 
|  | } | 
|  |  | 
|  | return sb_process; | 
|  | } | 
|  |  | 
|  |  | 
|  | #if defined(__APPLE__) | 
|  |  | 
|  | lldb::SBProcess | 
|  | SBTarget::AttachToProcessWithID (SBListener &listener, | 
|  | ::pid_t pid, | 
|  | lldb::SBError& error) | 
|  | { | 
|  | return AttachToProcessWithID (listener, (lldb::pid_t)pid, error); | 
|  | } | 
|  |  | 
|  | #endif // #if defined(__APPLE__) | 
|  |  | 
|  | lldb::SBProcess | 
|  | SBTarget::AttachToProcessWithID | 
|  | ( | 
|  | SBListener &listener, | 
|  | lldb::pid_t pid,// The process ID to attach to | 
|  | SBError& error  // An error explaining what went wrong if attach fails | 
|  | ) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBProcess sb_process; | 
|  | ProcessSP process_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::AttachToProcessWithID (listener, pid=%" PRId64 ", error)...", target_sp.get(), pid); | 
|  | } | 
|  |  | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  |  | 
|  | StateType state = eStateInvalid; | 
|  | process_sp = target_sp->GetProcessSP(); | 
|  | if (process_sp) | 
|  | { | 
|  | state = process_sp->GetState(); | 
|  |  | 
|  | if (process_sp->IsAlive() && state != eStateConnected) | 
|  | { | 
|  | if (state == eStateAttaching) | 
|  | error.SetErrorString ("process attach is in progress"); | 
|  | else | 
|  | error.SetErrorString ("a process is already being debugged"); | 
|  | return sb_process; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (state == eStateConnected) | 
|  | { | 
|  | // If we are already connected, then we have already specified the | 
|  | // listener, so if a valid listener is supplied, we need to error out | 
|  | // to let the client know. | 
|  | if (listener.IsValid()) | 
|  | { | 
|  | error.SetErrorString ("process is connected and already has a listener, pass empty listener"); | 
|  | return sb_process; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if (listener.IsValid()) | 
|  | process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL); | 
|  | else | 
|  | process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); | 
|  | } | 
|  | if (process_sp) | 
|  | { | 
|  | sb_process.SetSP (process_sp); | 
|  |  | 
|  | ProcessAttachInfo attach_info; | 
|  | attach_info.SetProcessID (pid); | 
|  |  | 
|  | PlatformSP platform_sp = target_sp->GetPlatform(); | 
|  | ProcessInstanceInfo instance_info; | 
|  | if (platform_sp->GetProcessInfo(pid, instance_info)) | 
|  | { | 
|  | attach_info.SetUserID(instance_info.GetEffectiveUserID()); | 
|  | } | 
|  | error.SetError (process_sp->Attach (attach_info)); | 
|  | if (error.Success()) | 
|  | { | 
|  | // If we are doing synchronous mode, then wait for the | 
|  | // process to stop! | 
|  | if (target_sp->GetDebugger().GetAsyncExecution () == false) | 
|  | process_sp->WaitForProcessToStop (NULL); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("unable to create lldb_private::Process"); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("SBTarget is invalid"); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::AttachToProcessWithID (...) => SBProcess(%p)", | 
|  | target_sp.get(), process_sp.get()); | 
|  | } | 
|  | return sb_process; | 
|  | } | 
|  |  | 
|  | lldb::SBProcess | 
|  | SBTarget::AttachToProcessWithName | 
|  | ( | 
|  | SBListener &listener, | 
|  | const char *name,   // basename of process to attach to | 
|  | bool wait_for,      // if true wait for a new instance of "name" to be launched | 
|  | SBError& error      // An error explaining what went wrong if attach fails | 
|  | ) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBProcess sb_process; | 
|  | ProcessSP process_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::AttachToProcessWithName (listener, name=%s, wait_for=%s, error)...", target_sp.get(), name, wait_for ? "true" : "false"); | 
|  | } | 
|  |  | 
|  | if (name && target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  |  | 
|  | StateType state = eStateInvalid; | 
|  | process_sp = target_sp->GetProcessSP(); | 
|  | if (process_sp) | 
|  | { | 
|  | state = process_sp->GetState(); | 
|  |  | 
|  | if (process_sp->IsAlive() && state != eStateConnected) | 
|  | { | 
|  | if (state == eStateAttaching) | 
|  | error.SetErrorString ("process attach is in progress"); | 
|  | else | 
|  | error.SetErrorString ("a process is already being debugged"); | 
|  | return sb_process; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (state == eStateConnected) | 
|  | { | 
|  | // If we are already connected, then we have already specified the | 
|  | // listener, so if a valid listener is supplied, we need to error out | 
|  | // to let the client know. | 
|  | if (listener.IsValid()) | 
|  | { | 
|  | error.SetErrorString ("process is connected and already has a listener, pass empty listener"); | 
|  | return sb_process; | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if (listener.IsValid()) | 
|  | process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL); | 
|  | else | 
|  | process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL); | 
|  | } | 
|  |  | 
|  | if (process_sp) | 
|  | { | 
|  | sb_process.SetSP (process_sp); | 
|  | ProcessAttachInfo attach_info; | 
|  | attach_info.GetExecutableFile().SetFile(name, false); | 
|  | attach_info.SetWaitForLaunch(wait_for); | 
|  | error.SetError (process_sp->Attach (attach_info)); | 
|  | if (error.Success()) | 
|  | { | 
|  | // If we are doing synchronous mode, then wait for the | 
|  | // process to stop! | 
|  | if (target_sp->GetDebugger().GetAsyncExecution () == false) | 
|  | process_sp->WaitForProcessToStop (NULL); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("unable to create lldb_private::Process"); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("SBTarget is invalid"); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::AttachToPorcessWithName (...) => SBProcess(%p)", | 
|  | target_sp.get(), process_sp.get()); | 
|  | } | 
|  | return sb_process; | 
|  | } | 
|  |  | 
|  | lldb::SBProcess | 
|  | SBTarget::ConnectRemote | 
|  | ( | 
|  | SBListener &listener, | 
|  | const char *url, | 
|  | const char *plugin_name, | 
|  | SBError& error | 
|  | ) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBProcess sb_process; | 
|  | ProcessSP process_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::ConnectRemote (listener, url=%s, plugin_name=%s, error)...", target_sp.get(), url, plugin_name); | 
|  | } | 
|  |  | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | if (listener.IsValid()) | 
|  | process_sp = target_sp->CreateProcess (listener.ref(), plugin_name, NULL); | 
|  | else | 
|  | process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), plugin_name, NULL); | 
|  |  | 
|  |  | 
|  | if (process_sp) | 
|  | { | 
|  | sb_process.SetSP (process_sp); | 
|  | error.SetError (process_sp->ConnectRemote (NULL, url)); | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("unable to create lldb_private::Process"); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | error.SetErrorString ("SBTarget is invalid"); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::ConnectRemote (...) => SBProcess(%p)", | 
|  | target_sp.get(), process_sp.get()); | 
|  | } | 
|  | return sb_process; | 
|  | } | 
|  |  | 
|  | SBFileSpec | 
|  | SBTarget::GetExecutable () | 
|  | { | 
|  |  | 
|  | SBFileSpec exe_file_spec; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Module *exe_module = target_sp->GetExecutableModulePointer(); | 
|  | if (exe_module) | 
|  | exe_file_spec.SetFileSpec (exe_module->GetFileSpec()); | 
|  | } | 
|  |  | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)", | 
|  | target_sp.get(), exe_file_spec.get()); | 
|  | } | 
|  |  | 
|  | return exe_file_spec; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::operator == (const SBTarget &rhs) const | 
|  | { | 
|  | return m_opaque_sp.get() == rhs.m_opaque_sp.get(); | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::operator != (const SBTarget &rhs) const | 
|  | { | 
|  | return m_opaque_sp.get() != rhs.m_opaque_sp.get(); | 
|  | } | 
|  |  | 
|  | lldb::TargetSP | 
|  | SBTarget::GetSP () const | 
|  | { | 
|  | return m_opaque_sp; | 
|  | } | 
|  |  | 
|  | void | 
|  | SBTarget::SetSP (const lldb::TargetSP& target_sp) | 
|  | { | 
|  | m_opaque_sp = target_sp; | 
|  | } | 
|  |  | 
|  | lldb::SBAddress | 
|  | SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr) | 
|  | { | 
|  | lldb::SBAddress sb_addr; | 
|  | Address &addr = sb_addr.ref(); | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | if (target_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, addr)) | 
|  | return sb_addr; | 
|  | } | 
|  |  | 
|  | // We have a load address that isn't in a section, just return an address | 
|  | // with the offset filled in (the address) and the section set to NULL | 
|  | addr.SetRawAddress(vm_addr); | 
|  | return sb_addr; | 
|  | } | 
|  |  | 
|  | SBSymbolContext | 
|  | SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope) | 
|  | { | 
|  | SBSymbolContext sc; | 
|  | if (addr.IsValid()) | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | target_sp->GetImages().ResolveSymbolContextForAddress (addr.ref(), resolve_scope, sc.ref()); | 
|  | } | 
|  | return sc; | 
|  | } | 
|  |  | 
|  |  | 
|  | SBBreakpoint | 
|  | SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line) | 
|  | { | 
|  | return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file, false), line)); | 
|  | } | 
|  |  | 
|  | SBBreakpoint | 
|  | SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && line != 0) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  |  | 
|  | const LazyBool check_inlines = eLazyBoolCalculate; | 
|  | const LazyBool skip_prologue = eLazyBoolCalculate; | 
|  | const bool internal = false; | 
|  | *sb_bp = target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, check_inlines, skip_prologue, internal); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | SBStream sstr; | 
|  | sb_bp.GetDescription (sstr); | 
|  | char path[PATH_MAX]; | 
|  | sb_file_spec->GetPath (path, sizeof(path)); | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s", | 
|  | target_sp.get(), | 
|  | path, | 
|  | line, | 
|  | sb_bp.get(), | 
|  | sstr.GetData()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | SBBreakpoint | 
|  | SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp.get()) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  |  | 
|  | const bool internal = false; | 
|  | const LazyBool skip_prologue = eLazyBoolCalculate; | 
|  | if (module_name && module_name[0]) | 
|  | { | 
|  | FileSpecList module_spec_list; | 
|  | module_spec_list.Append (FileSpec (module_name, false)); | 
|  | *sb_bp = target_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal); | 
|  | } | 
|  | else | 
|  | { | 
|  | *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)", | 
|  | target_sp.get(), symbol_name, module_name, sb_bp.get()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | lldb::SBBreakpoint | 
|  | SBTarget::BreakpointCreateByName (const char *symbol_name, | 
|  | const SBFileSpecList &module_list, | 
|  | const SBFileSpecList &comp_unit_list) | 
|  | { | 
|  | uint32_t name_type_mask = eFunctionNameTypeAuto; | 
|  | return BreakpointCreateByName (symbol_name, name_type_mask, module_list, comp_unit_list); | 
|  | } | 
|  |  | 
|  | lldb::SBBreakpoint | 
|  | SBTarget::BreakpointCreateByName (const char *symbol_name, | 
|  | uint32_t name_type_mask, | 
|  | const SBFileSpecList &module_list, | 
|  | const SBFileSpecList &comp_unit_list) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && symbol_name && symbol_name[0]) | 
|  | { | 
|  | const bool internal = false; | 
|  | const LazyBool skip_prologue = eLazyBoolCalculate; | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | *sb_bp = target_sp->CreateBreakpoint (module_list.get(), | 
|  | comp_unit_list.get(), | 
|  | symbol_name, | 
|  | name_type_mask, | 
|  | skip_prologue, | 
|  | internal); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", name_type: %d) => SBBreakpoint(%p)", | 
|  | target_sp.get(), symbol_name, name_type_mask, sb_bp.get()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | lldb::SBBreakpoint | 
|  | SBTarget::BreakpointCreateByNames (const char *symbol_names[], | 
|  | uint32_t num_names, | 
|  | uint32_t name_type_mask, | 
|  | const SBFileSpecList &module_list, | 
|  | const SBFileSpecList &comp_unit_list) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && num_names > 0) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | const bool internal = false; | 
|  | const LazyBool skip_prologue = eLazyBoolCalculate; | 
|  | *sb_bp = target_sp->CreateBreakpoint (module_list.get(), | 
|  | comp_unit_list.get(), | 
|  | symbol_names, | 
|  | num_names, | 
|  | name_type_mask, | 
|  | skip_prologue, | 
|  | internal); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbols={", target_sp.get()); | 
|  | for (uint32_t i = 0 ; i < num_names; i++) | 
|  | { | 
|  | char sep; | 
|  | if (i < num_names - 1) | 
|  | sep = ','; | 
|  | else | 
|  | sep = '}'; | 
|  | if (symbol_names[i] != NULL) | 
|  | log->Printf ("\"%s\"%c ", symbol_names[i], sep); | 
|  | else | 
|  | log->Printf ("\"<NULL>\"%c ", sep); | 
|  |  | 
|  | } | 
|  | log->Printf ("name_type: %d) => SBBreakpoint(%p)", name_type_mask, sb_bp.get()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | SBBreakpoint | 
|  | SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && symbol_name_regex && symbol_name_regex[0]) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | RegularExpression regexp(symbol_name_regex); | 
|  | const bool internal = false; | 
|  | const LazyBool skip_prologue = eLazyBoolCalculate; | 
|  |  | 
|  | if (module_name && module_name[0]) | 
|  | { | 
|  | FileSpecList module_spec_list; | 
|  | module_spec_list.Append (FileSpec (module_name, false)); | 
|  |  | 
|  | *sb_bp = target_sp->CreateFuncRegexBreakpoint (&module_spec_list, NULL, regexp, skip_prologue, internal); | 
|  | } | 
|  | else | 
|  | { | 
|  | *sb_bp = target_sp->CreateFuncRegexBreakpoint (NULL, NULL, regexp, skip_prologue, internal); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", | 
|  | target_sp.get(), symbol_name_regex, module_name, sb_bp.get()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | lldb::SBBreakpoint | 
|  | SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, | 
|  | const SBFileSpecList &module_list, | 
|  | const SBFileSpecList &comp_unit_list) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && symbol_name_regex && symbol_name_regex[0]) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | RegularExpression regexp(symbol_name_regex); | 
|  | const bool internal = false; | 
|  | const LazyBool skip_prologue = eLazyBoolCalculate; | 
|  |  | 
|  | *sb_bp = target_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, skip_prologue, internal); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\") => SBBreakpoint(%p)", | 
|  | target_sp.get(), symbol_name_regex, sb_bp.get()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | SBBreakpoint | 
|  | SBTarget::BreakpointCreateByAddress (addr_t address) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | *sb_bp = target_sp->CreateBreakpoint (address, false); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%" PRIu64 ") => SBBreakpoint(%p)", target_sp.get(), (uint64_t) address, sb_bp.get()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | lldb::SBBreakpoint | 
|  | SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpec &source_file, const char *module_name) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && source_regex && source_regex[0]) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | RegularExpression regexp(source_regex); | 
|  | FileSpecList source_file_spec_list; | 
|  | source_file_spec_list.Append (source_file.ref()); | 
|  |  | 
|  | if (module_name && module_name[0]) | 
|  | { | 
|  | FileSpecList module_spec_list; | 
|  | module_spec_list.Append (FileSpec (module_name, false)); | 
|  |  | 
|  | *sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false); | 
|  | } | 
|  | else | 
|  | { | 
|  | *sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false); | 
|  | } | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | char path[PATH_MAX]; | 
|  | source_file->GetPath (path, sizeof(path)); | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", | 
|  | target_sp.get(), source_regex, path, module_name, sb_bp.get()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | lldb::SBBreakpoint | 
|  | SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, | 
|  | const SBFileSpecList &module_list, | 
|  | const lldb::SBFileSpecList &source_file_list) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && source_regex && source_regex[0]) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | RegularExpression regexp(source_regex); | 
|  | *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\") => SBBreakpoint(%p)", | 
|  | target_sp.get(), source_regex, sb_bp.get()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | lldb::SBBreakpoint | 
|  | SBTarget::BreakpointCreateForException  (lldb::LanguageType language, | 
|  | bool catch_bp, | 
|  | bool throw_bp) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_bp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | *sb_bp = target_sp->CreateExceptionBreakpoint (language, catch_bp, throw_bp); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: %s throw: %s) => SBBreakpoint(%p)", | 
|  | target_sp.get(), | 
|  | LanguageRuntime::GetNameForLanguageType(language), | 
|  | catch_bp ? "on" : "off", | 
|  | throw_bp ? "on" : "off", | 
|  | sb_bp.get()); | 
|  | } | 
|  |  | 
|  | return sb_bp; | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBTarget::GetNumBreakpoints () const | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | // The breakpoint list is thread safe, no need to lock | 
|  | return target_sp->GetBreakpointList().GetSize(); | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | SBBreakpoint | 
|  | SBTarget::GetBreakpointAtIndex (uint32_t idx) const | 
|  | { | 
|  | SBBreakpoint sb_breakpoint; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | // The breakpoint list is thread safe, no need to lock | 
|  | *sb_breakpoint = target_sp->GetBreakpointList().GetBreakpointAtIndex(idx); | 
|  | } | 
|  | return sb_breakpoint; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::BreakpointDelete (break_id_t bp_id) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | bool result = false; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | result = target_sp->RemoveBreakpointByID (bp_id); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i", target_sp.get(), (uint32_t) bp_id, result); | 
|  | } | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | SBBreakpoint | 
|  | SBTarget::FindBreakpointByID (break_id_t bp_id) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBBreakpoint sb_breakpoint; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && bp_id != LLDB_INVALID_BREAK_ID) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | *sb_breakpoint = target_sp->GetBreakpointByID (bp_id); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)", | 
|  | target_sp.get(), (uint32_t) bp_id, sb_breakpoint.get()); | 
|  | } | 
|  |  | 
|  | return sb_breakpoint; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::EnableAllBreakpoints () | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | target_sp->EnableAllBreakpoints (); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::DisableAllBreakpoints () | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | target_sp->DisableAllBreakpoints (); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::DeleteAllBreakpoints () | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | target_sp->RemoveAllBreakpoints (); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBTarget::GetNumWatchpoints () const | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | // The watchpoint list is thread safe, no need to lock | 
|  | return target_sp->GetWatchpointList().GetSize(); | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | SBWatchpoint | 
|  | SBTarget::GetWatchpointAtIndex (uint32_t idx) const | 
|  | { | 
|  | SBWatchpoint sb_watchpoint; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | // The watchpoint list is thread safe, no need to lock | 
|  | sb_watchpoint.SetSP (target_sp->GetWatchpointList().GetByIndex(idx)); | 
|  | } | 
|  | return sb_watchpoint; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::DeleteWatchpoint (watch_id_t wp_id) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | bool result = false; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | Mutex::Locker locker; | 
|  | target_sp->GetWatchpointList().GetListMutex(locker); | 
|  | result = target_sp->RemoveWatchpointByID (wp_id); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::WatchpointDelete (wp_id=%d) => %i", target_sp.get(), (uint32_t) wp_id, result); | 
|  | } | 
|  |  | 
|  | return result; | 
|  | } | 
|  |  | 
|  | SBWatchpoint | 
|  | SBTarget::FindWatchpointByID (lldb::watch_id_t wp_id) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBWatchpoint sb_watchpoint; | 
|  | lldb::WatchpointSP watchpoint_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && wp_id != LLDB_INVALID_WATCH_ID) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | Mutex::Locker locker; | 
|  | target_sp->GetWatchpointList().GetListMutex(locker); | 
|  | watchpoint_sp = target_sp->GetWatchpointList().FindByID(wp_id); | 
|  | sb_watchpoint.SetSP (watchpoint_sp); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::FindWatchpointByID (bp_id=%d) => SBWatchpoint(%p)", | 
|  | target_sp.get(), (uint32_t) wp_id, watchpoint_sp.get()); | 
|  | } | 
|  |  | 
|  | return sb_watchpoint; | 
|  | } | 
|  |  | 
|  | lldb::SBWatchpoint | 
|  | SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError &error) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBWatchpoint sb_watchpoint; | 
|  | lldb::WatchpointSP watchpoint_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && (read || write) && addr != LLDB_INVALID_ADDRESS && size > 0) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | uint32_t watch_type = 0; | 
|  | if (read) | 
|  | watch_type |= LLDB_WATCH_TYPE_READ; | 
|  | if (write) | 
|  | watch_type |= LLDB_WATCH_TYPE_WRITE; | 
|  | if (watch_type == 0) | 
|  | { | 
|  | error.SetErrorString("Can't create a watchpoint that is neither read nor write."); | 
|  | return sb_watchpoint; | 
|  | } | 
|  |  | 
|  | // Target::CreateWatchpoint() is thread safe. | 
|  | Error cw_error; | 
|  | // This API doesn't take in a type, so we can't figure out what it is. | 
|  | ClangASTType *type = NULL; | 
|  | watchpoint_sp = target_sp->CreateWatchpoint(addr, size, type, watch_type, cw_error); | 
|  | error.SetError(cw_error); | 
|  | sb_watchpoint.SetSP (watchpoint_sp); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::WatchAddress (addr=0x%" PRIx64 ", 0x%u) => SBWatchpoint(%p)", | 
|  | target_sp.get(), addr, (uint32_t) size, watchpoint_sp.get()); | 
|  | } | 
|  |  | 
|  | return sb_watchpoint; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::EnableAllWatchpoints () | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | Mutex::Locker locker; | 
|  | target_sp->GetWatchpointList().GetListMutex(locker); | 
|  | target_sp->EnableAllWatchpoints (); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::DisableAllWatchpoints () | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | Mutex::Locker locker; | 
|  | target_sp->GetWatchpointList().GetListMutex(locker); | 
|  | target_sp->DisableAllWatchpoints (); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::DeleteAllWatchpoints () | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | Mutex::Locker locker; | 
|  | target_sp->GetWatchpointList().GetListMutex(locker); | 
|  | target_sp->RemoveAllWatchpoints (); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  |  | 
|  | lldb::SBModule | 
|  | SBTarget::AddModule (const char *path, | 
|  | const char *triple, | 
|  | const char *uuid_cstr) | 
|  | { | 
|  | return AddModule (path, triple, uuid_cstr, NULL); | 
|  | } | 
|  |  | 
|  | lldb::SBModule | 
|  | SBTarget::AddModule (const char *path, | 
|  | const char *triple, | 
|  | const char *uuid_cstr, | 
|  | const char *symfile) | 
|  | { | 
|  | lldb::SBModule sb_module; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | ModuleSpec module_spec; | 
|  | if (path) | 
|  | module_spec.GetFileSpec().SetFile(path, false); | 
|  |  | 
|  | if (uuid_cstr) | 
|  | module_spec.GetUUID().SetFromCString(uuid_cstr); | 
|  |  | 
|  | if (triple) | 
|  | module_spec.GetArchitecture().SetTriple (triple, target_sp->GetPlatform ().get()); | 
|  |  | 
|  | if (symfile) | 
|  | module_spec.GetSymbolFileSpec ().SetFile(symfile, false); | 
|  |  | 
|  | sb_module.SetSP(target_sp->GetSharedModule (module_spec)); | 
|  | } | 
|  | return sb_module; | 
|  | } | 
|  |  | 
|  | lldb::SBModule | 
|  | SBTarget::AddModule (const SBModuleSpec &module_spec) | 
|  | { | 
|  | lldb::SBModule sb_module; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | sb_module.SetSP(target_sp->GetSharedModule (*module_spec.m_opaque_ap)); | 
|  | return sb_module; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::AddModule (lldb::SBModule &module) | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | target_sp->GetImages().AppendIfNeeded (module.GetSP()); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBTarget::GetNumModules () const | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | uint32_t num = 0; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | // The module list is thread safe, no need to lock | 
|  | num = target_sp->GetImages().GetSize(); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | log->Printf ("SBTarget(%p)::GetNumModules () => %d", target_sp.get(), num); | 
|  |  | 
|  | return num; | 
|  | } | 
|  |  | 
|  | void | 
|  | SBTarget::Clear () | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | if (log) | 
|  | log->Printf ("SBTarget(%p)::Clear ()", m_opaque_sp.get()); | 
|  |  | 
|  | m_opaque_sp.reset(); | 
|  | } | 
|  |  | 
|  |  | 
|  | SBModule | 
|  | SBTarget::FindModule (const SBFileSpec &sb_file_spec) | 
|  | { | 
|  | SBModule sb_module; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp && sb_file_spec.IsValid()) | 
|  | { | 
|  | ModuleSpec module_spec(*sb_file_spec); | 
|  | // The module list is thread safe, no need to lock | 
|  | sb_module.SetSP (target_sp->GetImages().FindFirstModule (module_spec)); | 
|  | } | 
|  | return sb_module; | 
|  | } | 
|  |  | 
|  | lldb::ByteOrder | 
|  | SBTarget::GetByteOrder () | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | return target_sp->GetArchitecture().GetByteOrder(); | 
|  | return eByteOrderInvalid; | 
|  | } | 
|  |  | 
|  | const char * | 
|  | SBTarget::GetTriple () | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | std::string triple (target_sp->GetArchitecture().GetTriple().str()); | 
|  | // Unique the string so we don't run into ownership issues since | 
|  | // the const strings put the string into the string pool once and | 
|  | // the strings never comes out | 
|  | ConstString const_triple (triple.c_str()); | 
|  | return const_triple.GetCString(); | 
|  | } | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | uint32_t | 
|  | SBTarget::GetAddressByteSize() | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | return target_sp->GetArchitecture().GetAddressByteSize(); | 
|  | return sizeof(void*); | 
|  | } | 
|  |  | 
|  |  | 
|  | SBModule | 
|  | SBTarget::GetModuleAtIndex (uint32_t idx) | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | SBModule sb_module; | 
|  | ModuleSP module_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | // The module list is thread safe, no need to lock | 
|  | module_sp = target_sp->GetImages().GetModuleAtIndex(idx); | 
|  | sb_module.SetSP (module_sp); | 
|  | } | 
|  |  | 
|  | if (log) | 
|  | { | 
|  | log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)", | 
|  | target_sp.get(), idx, module_sp.get()); | 
|  | } | 
|  |  | 
|  | return sb_module; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::RemoveModule (lldb::SBModule module) | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | return target_sp->GetImages().Remove(module.GetSP()); | 
|  | return false; | 
|  | } | 
|  |  | 
|  |  | 
|  | SBBroadcaster | 
|  | SBTarget::GetBroadcaster () const | 
|  | { | 
|  | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  |  | 
|  | TargetSP target_sp(GetSP()); | 
|  | SBBroadcaster broadcaster(target_sp.get(), false); | 
|  |  | 
|  | if (log) | 
|  | log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)", | 
|  | target_sp.get(), broadcaster.get()); | 
|  |  | 
|  | return broadcaster; | 
|  | } | 
|  |  | 
|  | bool | 
|  | SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level) | 
|  | { | 
|  | Stream &strm = description.ref(); | 
|  |  | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | target_sp->Dump (&strm, description_level); | 
|  | } | 
|  | else | 
|  | strm.PutCString ("No value"); | 
|  |  | 
|  | return true; | 
|  | } | 
|  |  | 
|  | lldb::SBSymbolContextList | 
|  | SBTarget::FindFunctions (const char *name, uint32_t name_type_mask) | 
|  | { | 
|  | lldb::SBSymbolContextList sb_sc_list; | 
|  | if (name && name[0]) | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | const bool symbols_ok = true; | 
|  | const bool inlines_ok = true; | 
|  | const bool append = true; | 
|  | target_sp->GetImages().FindFunctions (ConstString(name), | 
|  | name_type_mask, | 
|  | symbols_ok, | 
|  | inlines_ok, | 
|  | append, | 
|  | *sb_sc_list); | 
|  | } | 
|  | } | 
|  | return sb_sc_list; | 
|  | } | 
|  |  | 
|  | lldb::SBType | 
|  | SBTarget::FindFirstType (const char* typename_cstr) | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (typename_cstr && typename_cstr[0] && target_sp) | 
|  | { | 
|  | ConstString const_typename(typename_cstr); | 
|  | SymbolContext sc; | 
|  | const bool exact_match = false; | 
|  |  | 
|  | const ModuleList &module_list = target_sp->GetImages(); | 
|  | size_t count = module_list.GetSize(); | 
|  | for (size_t idx = 0; idx < count; idx++) | 
|  | { | 
|  | ModuleSP module_sp (module_list.GetModuleAtIndex(idx)); | 
|  | if (module_sp) | 
|  | { | 
|  | TypeSP type_sp (module_sp->FindFirstType(sc, const_typename, exact_match)); | 
|  | if (type_sp) | 
|  | return SBType(type_sp); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Didn't find the type in the symbols; try the Objective-C runtime | 
|  | // if one is installed | 
|  |  | 
|  | ProcessSP process_sp(target_sp->GetProcessSP()); | 
|  |  | 
|  | if (process_sp) | 
|  | { | 
|  | ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime(); | 
|  |  | 
|  | if (objc_language_runtime) | 
|  | { | 
|  | TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor(); | 
|  |  | 
|  | if (objc_type_vendor) | 
|  | { | 
|  | std::vector <ClangASTType> types; | 
|  |  | 
|  | if (objc_type_vendor->FindTypes(const_typename, true, 1, types) > 0) | 
|  | return SBType(types[0]); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // No matches, search for basic typename matches | 
|  | ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); | 
|  | if (clang_ast) | 
|  | return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename)); | 
|  | } | 
|  | return SBType(); | 
|  | } | 
|  |  | 
|  | SBType | 
|  | SBTarget::GetBasicType(lldb::BasicType type) | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); | 
|  | if (clang_ast) | 
|  | return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), type)); | 
|  | } | 
|  | return SBType(); | 
|  | } | 
|  |  | 
|  |  | 
|  | lldb::SBTypeList | 
|  | SBTarget::FindTypes (const char* typename_cstr) | 
|  | { | 
|  | SBTypeList sb_type_list; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (typename_cstr && typename_cstr[0] && target_sp) | 
|  | { | 
|  | ModuleList& images = target_sp->GetImages(); | 
|  | ConstString const_typename(typename_cstr); | 
|  | bool exact_match = false; | 
|  | SymbolContext sc; | 
|  | TypeList type_list; | 
|  |  | 
|  | uint32_t num_matches = images.FindTypes (sc, | 
|  | const_typename, | 
|  | exact_match, | 
|  | UINT32_MAX, | 
|  | type_list); | 
|  |  | 
|  | if (num_matches > 0) | 
|  | { | 
|  | for (size_t idx = 0; idx < num_matches; idx++) | 
|  | { | 
|  | TypeSP type_sp (type_list.GetTypeAtIndex(idx)); | 
|  | if (type_sp) | 
|  | sb_type_list.Append(SBType(type_sp)); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Try the Objective-C runtime if one is installed | 
|  |  | 
|  | ProcessSP process_sp(target_sp->GetProcessSP()); | 
|  |  | 
|  | if (process_sp) | 
|  | { | 
|  | ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime(); | 
|  |  | 
|  | if (objc_language_runtime) | 
|  | { | 
|  | TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor(); | 
|  |  | 
|  | if (objc_type_vendor) | 
|  | { | 
|  | std::vector <ClangASTType> types; | 
|  |  | 
|  | if (objc_type_vendor->FindTypes(const_typename, true, UINT32_MAX, types)) | 
|  | { | 
|  | for (ClangASTType &type : types) | 
|  | { | 
|  | sb_type_list.Append(SBType(type)); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | if (sb_type_list.GetSize() == 0) | 
|  | { | 
|  | // No matches, search for basic typename matches | 
|  | ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); | 
|  | if (clang_ast) | 
|  | sb_type_list.Append (SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename))); | 
|  | } | 
|  | } | 
|  | return sb_type_list; | 
|  | } | 
|  |  | 
|  | SBValueList | 
|  | SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches) | 
|  | { | 
|  | SBValueList sb_value_list; | 
|  |  | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (name && target_sp) | 
|  | { | 
|  | VariableList variable_list; | 
|  | const bool append = true; | 
|  | const uint32_t match_count = target_sp->GetImages().FindGlobalVariables (ConstString (name), | 
|  | append, | 
|  | max_matches, | 
|  | variable_list); | 
|  |  | 
|  | if (match_count > 0) | 
|  | { | 
|  | ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get(); | 
|  | if (exe_scope == NULL) | 
|  | exe_scope = target_sp.get(); | 
|  | for (uint32_t i=0; i<match_count; ++i) | 
|  | { | 
|  | lldb::ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_scope, variable_list.GetVariableAtIndex(i))); | 
|  | if (valobj_sp) | 
|  | sb_value_list.Append(SBValue(valobj_sp)); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | return sb_value_list; | 
|  | } | 
|  |  | 
|  | lldb::SBValue | 
|  | SBTarget::FindFirstGlobalVariable (const char* name) | 
|  | { | 
|  | SBValueList sb_value_list(FindGlobalVariables(name, 1)); | 
|  | if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0) | 
|  | return sb_value_list.GetValueAtIndex(0); | 
|  | return SBValue(); | 
|  | } | 
|  |  | 
|  | SBSourceManager | 
|  | SBTarget::GetSourceManager() | 
|  | { | 
|  | SBSourceManager source_manager (*this); | 
|  | return source_manager; | 
|  | } | 
|  |  | 
|  | lldb::SBInstructionList | 
|  | SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count) | 
|  | { | 
|  | return ReadInstructions (base_addr, count, NULL); | 
|  | } | 
|  |  | 
|  | lldb::SBInstructionList | 
|  | SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string) | 
|  | { | 
|  | SBInstructionList sb_instructions; | 
|  |  | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Address *addr_ptr = base_addr.get(); | 
|  |  | 
|  | if (addr_ptr) | 
|  | { | 
|  | DataBufferHeap data (target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0); | 
|  | bool prefer_file_cache = false; | 
|  | lldb_private::Error error; | 
|  | lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; | 
|  | const size_t bytes_read = target_sp->ReadMemory(*addr_ptr, | 
|  | prefer_file_cache, | 
|  | data.GetBytes(), | 
|  | data.GetByteSize(), | 
|  | error, | 
|  | &load_addr); | 
|  | const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; | 
|  | sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(), | 
|  | NULL, | 
|  | flavor_string, | 
|  | *addr_ptr, | 
|  | data.GetBytes(), | 
|  | bytes_read, | 
|  | count, | 
|  | data_from_file)); | 
|  | } | 
|  | } | 
|  |  | 
|  | return sb_instructions; | 
|  |  | 
|  | } | 
|  |  | 
|  | lldb::SBInstructionList | 
|  | SBTarget::GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size) | 
|  | { | 
|  | return GetInstructionsWithFlavor (base_addr, NULL, buf, size); | 
|  | } | 
|  |  | 
|  | lldb::SBInstructionList | 
|  | SBTarget::GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size) | 
|  | { | 
|  | SBInstructionList sb_instructions; | 
|  |  | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | Address addr; | 
|  |  | 
|  | if (base_addr.get()) | 
|  | addr = *base_addr.get(); | 
|  |  | 
|  | const bool data_from_file = true; | 
|  |  | 
|  | sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(), | 
|  | NULL, | 
|  | flavor_string, | 
|  | addr, | 
|  | buf, | 
|  | size, | 
|  | UINT32_MAX, | 
|  | data_from_file)); | 
|  | } | 
|  |  | 
|  | return sb_instructions; | 
|  | } | 
|  |  | 
|  | lldb::SBInstructionList | 
|  | SBTarget::GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size) | 
|  | { | 
|  | return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), NULL, buf, size); | 
|  | } | 
|  |  | 
|  | lldb::SBInstructionList | 
|  | SBTarget::GetInstructionsWithFlavor (lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size) | 
|  | { | 
|  | return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), flavor_string, buf, size); | 
|  | } | 
|  |  | 
|  | SBError | 
|  | SBTarget::SetSectionLoadAddress (lldb::SBSection section, | 
|  | lldb::addr_t section_base_addr) | 
|  | { | 
|  | SBError sb_error; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | if (!section.IsValid()) | 
|  | { | 
|  | sb_error.SetErrorStringWithFormat ("invalid section"); | 
|  | } | 
|  | else | 
|  | { | 
|  | SectionSP section_sp (section.GetSP()); | 
|  | if (section_sp) | 
|  | { | 
|  | if (section_sp->IsThreadSpecific()) | 
|  | { | 
|  | sb_error.SetErrorString ("thread specific sections are not yet supported"); | 
|  | } | 
|  | else | 
|  | { | 
|  | if (target_sp->GetSectionLoadList().SetSectionLoadAddress (section_sp, section_base_addr)) | 
|  | { | 
|  | // Flush info in the process (stack frames, etc) | 
|  | ProcessSP process_sp (target_sp->GetProcessSP()); | 
|  | if (process_sp) | 
|  | process_sp->Flush(); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | sb_error.SetErrorString ("invalid target"); | 
|  | } | 
|  | return sb_error; | 
|  | } | 
|  |  | 
|  | SBError | 
|  | SBTarget::ClearSectionLoadAddress (lldb::SBSection section) | 
|  | { | 
|  | SBError sb_error; | 
|  |  | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | if (!section.IsValid()) | 
|  | { | 
|  | sb_error.SetErrorStringWithFormat ("invalid section"); | 
|  | } | 
|  | else | 
|  | { | 
|  | if (target_sp->GetSectionLoadList().SetSectionUnloaded (section.GetSP())) | 
|  | { | 
|  | // Flush info in the process (stack frames, etc) | 
|  | ProcessSP process_sp (target_sp->GetProcessSP()); | 
|  | if (process_sp) | 
|  | process_sp->Flush(); | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | sb_error.SetErrorStringWithFormat ("invalid target"); | 
|  | } | 
|  | return sb_error; | 
|  | } | 
|  |  | 
|  | SBError | 
|  | SBTarget::SetModuleLoadAddress (lldb::SBModule module, int64_t slide_offset) | 
|  | { | 
|  | SBError sb_error; | 
|  |  | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | ModuleSP module_sp (module.GetSP()); | 
|  | if (module_sp) | 
|  | { | 
|  | bool changed = false; | 
|  | if (module_sp->SetLoadAddress (*target_sp, slide_offset, changed)) | 
|  | { | 
|  | // The load was successful, make sure that at least some sections | 
|  | // changed before we notify that our module was loaded. | 
|  | if (changed) | 
|  | { | 
|  | ModuleList module_list; | 
|  | module_list.Append(module_sp); | 
|  | target_sp->ModulesDidLoad (module_list); | 
|  | // Flush info in the process (stack frames, etc) | 
|  | ProcessSP process_sp (target_sp->GetProcessSP()); | 
|  | if (process_sp) | 
|  | process_sp->Flush(); | 
|  | } | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | sb_error.SetErrorStringWithFormat ("invalid module"); | 
|  | } | 
|  |  | 
|  | } | 
|  | else | 
|  | { | 
|  | sb_error.SetErrorStringWithFormat ("invalid target"); | 
|  | } | 
|  | return sb_error; | 
|  | } | 
|  |  | 
|  | SBError | 
|  | SBTarget::ClearModuleLoadAddress (lldb::SBModule module) | 
|  | { | 
|  | SBError sb_error; | 
|  |  | 
|  | char path[PATH_MAX]; | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | ModuleSP module_sp (module.GetSP()); | 
|  | if (module_sp) | 
|  | { | 
|  | ObjectFile *objfile = module_sp->GetObjectFile(); | 
|  | if (objfile) | 
|  | { | 
|  | SectionList *section_list = objfile->GetSectionList(); | 
|  | if (section_list) | 
|  | { | 
|  | bool changed = false; | 
|  | const size_t num_sections = section_list->GetSize(); | 
|  | for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) | 
|  | { | 
|  | SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx)); | 
|  | if (section_sp) | 
|  | changed |= target_sp->GetSectionLoadList().SetSectionUnloaded (section_sp) > 0; | 
|  | } | 
|  | if (changed) | 
|  | { | 
|  | // Flush info in the process (stack frames, etc) | 
|  | ProcessSP process_sp (target_sp->GetProcessSP()); | 
|  | if (process_sp) | 
|  | process_sp->Flush(); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | module_sp->GetFileSpec().GetPath (path, sizeof(path)); | 
|  | sb_error.SetErrorStringWithFormat ("no sections in object file '%s'", path); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | module_sp->GetFileSpec().GetPath (path, sizeof(path)); | 
|  | sb_error.SetErrorStringWithFormat ("no object file for module '%s'", path); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | sb_error.SetErrorStringWithFormat ("invalid module"); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | sb_error.SetErrorStringWithFormat ("invalid target"); | 
|  | } | 
|  | return sb_error; | 
|  | } | 
|  |  | 
|  |  | 
|  | lldb::SBSymbolContextList | 
|  | SBTarget::FindSymbols (const char *name, lldb::SymbolType symbol_type) | 
|  | { | 
|  | SBSymbolContextList sb_sc_list; | 
|  | if (name && name[0]) | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | bool append = true; | 
|  | target_sp->GetImages().FindSymbolsWithNameAndType (ConstString(name), | 
|  | symbol_type, | 
|  | *sb_sc_list, | 
|  | append); | 
|  | } | 
|  | } | 
|  | return sb_sc_list; | 
|  |  | 
|  | } | 
|  |  | 
|  |  | 
|  | lldb::SBValue | 
|  | SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &options) | 
|  | { | 
|  | Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); | 
|  | Log * expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); | 
|  | SBValue expr_result; | 
|  | ExecutionResults exe_results = eExecutionSetupError; | 
|  | ValueObjectSP expr_value_sp; | 
|  | TargetSP target_sp(GetSP()); | 
|  | StackFrame *frame = NULL; | 
|  | if (target_sp) | 
|  | { | 
|  | if (expr == NULL || expr[0] == '\0') | 
|  | { | 
|  | if (log) | 
|  | log->Printf ("SBTarget::EvaluateExpression called with an empty expression"); | 
|  | return expr_result; | 
|  | } | 
|  |  | 
|  | Mutex::Locker api_locker (target_sp->GetAPIMutex()); | 
|  | ExecutionContext exe_ctx (m_opaque_sp.get()); | 
|  |  | 
|  | if (log) | 
|  | log->Printf ("SBTarget()::EvaluateExpression (expr=\"%s\")...", expr); | 
|  |  | 
|  | frame = exe_ctx.GetFramePtr(); | 
|  | Target *target = exe_ctx.GetTargetPtr(); | 
|  |  | 
|  | if (target) | 
|  | { | 
|  | #ifdef LLDB_CONFIGURATION_DEBUG | 
|  | StreamString frame_description; | 
|  | if (frame) | 
|  | frame->DumpUsingSettingsFormat (&frame_description); | 
|  | Host::SetCrashDescriptionWithFormat ("SBTarget::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s", | 
|  | expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str()); | 
|  | #endif | 
|  | exe_results = target->EvaluateExpression (expr, | 
|  | frame, | 
|  | expr_value_sp, | 
|  | options.ref()); | 
|  |  | 
|  | expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue()); | 
|  | #ifdef LLDB_CONFIGURATION_DEBUG | 
|  | Host::SetCrashDescription (NULL); | 
|  | #endif | 
|  | } | 
|  | else | 
|  | { | 
|  | if (log) | 
|  | log->Printf ("SBTarget::EvaluateExpression () => error: could not reconstruct frame object for this SBTarget."); | 
|  | } | 
|  | } | 
|  | #ifndef LLDB_DISABLE_PYTHON | 
|  | if (expr_log) | 
|  | expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is %s, summary %s **", | 
|  | expr_result.GetValue(), | 
|  | expr_result.GetSummary()); | 
|  |  | 
|  | if (log) | 
|  | log->Printf ("SBTarget(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", | 
|  | frame, | 
|  | expr, | 
|  | expr_value_sp.get(), | 
|  | exe_results); | 
|  | #endif | 
|  |  | 
|  | return expr_result; | 
|  | } | 
|  |  | 
|  |  | 
|  | lldb::addr_t | 
|  | SBTarget::GetStackRedZoneSize() | 
|  | { | 
|  | TargetSP target_sp(GetSP()); | 
|  | if (target_sp) | 
|  | { | 
|  | ABISP abi_sp; | 
|  | ProcessSP process_sp (target_sp->GetProcessSP()); | 
|  | if (process_sp) | 
|  | abi_sp = process_sp->GetABI(); | 
|  | else | 
|  | abi_sp = ABI::FindPlugin(target_sp->GetArchitecture()); | 
|  | if (abi_sp) | 
|  | return abi_sp->GetRedZoneSize(); | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  |