130fdc8d8SChris Lattner //===-- TargetList.cpp ------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1630fdc8d8SChris Lattner #include "lldb/Core/Broadcaster.h"
17ded470d3SGreg Clayton #include "lldb/Core/Debugger.h"
1830fdc8d8SChris Lattner #include "lldb/Core/Event.h"
191f746071SGreg Clayton #include "lldb/Core/Module.h"
2030fdc8d8SChris Lattner #include "lldb/Core/State.h"
2130fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
2230fdc8d8SChris Lattner #include "lldb/Host/Host.h"
23b3a40ba8SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
24cac9c5f9SGreg Clayton #include "lldb/Interpreter/OptionGroupPlatform.h"
25e996fd30SGreg Clayton #include "lldb/Target/Platform.h"
2630fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2730fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
2830fdc8d8SChris Lattner 
2930fdc8d8SChris Lattner using namespace lldb;
3030fdc8d8SChris Lattner using namespace lldb_private;
3130fdc8d8SChris Lattner 
324bddaeb5SJim Ingham ConstString &
334bddaeb5SJim Ingham TargetList::GetStaticBroadcasterClass ()
344bddaeb5SJim Ingham {
354bddaeb5SJim Ingham     static ConstString class_name ("lldb.targetList");
364bddaeb5SJim Ingham     return class_name;
374bddaeb5SJim Ingham }
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner //----------------------------------------------------------------------
4030fdc8d8SChris Lattner // TargetList constructor
4130fdc8d8SChris Lattner //----------------------------------------------------------------------
424bddaeb5SJim Ingham TargetList::TargetList(Debugger &debugger) :
434f465cffSJim Ingham     Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
4430fdc8d8SChris Lattner     m_target_list(),
4530fdc8d8SChris Lattner     m_target_list_mutex (Mutex::eMutexTypeRecursive),
462976d00aSJim Ingham     m_selected_target_idx (0)
4730fdc8d8SChris Lattner {
484bddaeb5SJim Ingham     CheckInWithManager();
4930fdc8d8SChris Lattner }
5030fdc8d8SChris Lattner 
5130fdc8d8SChris Lattner //----------------------------------------------------------------------
5230fdc8d8SChris Lattner // Destructor
5330fdc8d8SChris Lattner //----------------------------------------------------------------------
5430fdc8d8SChris Lattner TargetList::~TargetList()
5530fdc8d8SChris Lattner {
5630fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
5730fdc8d8SChris Lattner     m_target_list.clear();
5830fdc8d8SChris Lattner }
5930fdc8d8SChris Lattner 
6030fdc8d8SChris Lattner Error
61cac9c5f9SGreg Clayton TargetList::CreateTarget (Debugger &debugger,
62a0ca6601SGreg Clayton                           const char *user_exe_path,
63cac9c5f9SGreg Clayton                           const char *triple_cstr,
64cac9c5f9SGreg Clayton                           bool get_dependent_files,
65cac9c5f9SGreg Clayton                           const OptionGroupPlatform *platform_options,
66cac9c5f9SGreg Clayton                           TargetSP &target_sp)
67cac9c5f9SGreg Clayton {
68cac9c5f9SGreg Clayton     Error error;
69cac9c5f9SGreg Clayton     PlatformSP platform_sp;
70cac9c5f9SGreg Clayton 
71cdc21d4cSJohnny Chen     // This is purposely left empty unless it is specified by triple_cstr.
72cdc21d4cSJohnny Chen     // If not initialized via triple_cstr, then the currently selected platform
73cdc21d4cSJohnny Chen     // will set the architecture correctly.
7470512317SGreg Clayton     const ArchSpec arch(triple_cstr);
7570512317SGreg Clayton     if (triple_cstr && triple_cstr[0])
76cac9c5f9SGreg Clayton     {
77cac9c5f9SGreg Clayton         if (!arch.IsValid())
78cac9c5f9SGreg Clayton         {
7986edbf41SGreg Clayton             error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
80cac9c5f9SGreg Clayton             return error;
81cac9c5f9SGreg Clayton         }
82cac9c5f9SGreg Clayton     }
83b3a40ba8SGreg Clayton 
8470512317SGreg Clayton     ArchSpec platform_arch(arch);
85b3a40ba8SGreg Clayton     CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
86b3a40ba8SGreg Clayton     if (platform_options)
87b3a40ba8SGreg Clayton     {
88b3a40ba8SGreg Clayton         if (platform_options->PlatformWasSpecified ())
89b3a40ba8SGreg Clayton         {
90b3a40ba8SGreg Clayton             const bool select_platform = true;
91b3a40ba8SGreg Clayton             platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
92b3a40ba8SGreg Clayton                                                                        arch,
93b3a40ba8SGreg Clayton                                                                        select_platform,
9470512317SGreg Clayton                                                                        error,
9570512317SGreg Clayton                                                                        platform_arch);
96b3a40ba8SGreg Clayton             if (!platform_sp)
97b3a40ba8SGreg Clayton                 return error;
98b3a40ba8SGreg Clayton         }
99b3a40ba8SGreg Clayton     }
100b3a40ba8SGreg Clayton 
101b3a40ba8SGreg Clayton     if (!platform_sp)
102b3a40ba8SGreg Clayton     {
103b3a40ba8SGreg Clayton         // Get the current platform and make sure it is compatible with the
104b3a40ba8SGreg Clayton         // current architecture if we have a valid architecture.
105b3a40ba8SGreg Clayton         platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
106b3a40ba8SGreg Clayton 
10770512317SGreg Clayton         if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, &platform_arch))
108b3a40ba8SGreg Clayton         {
10970512317SGreg Clayton             platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
110b3a40ba8SGreg Clayton         }
111b3a40ba8SGreg Clayton     }
112b3a40ba8SGreg Clayton 
11370512317SGreg Clayton     if (!platform_arch.IsValid())
11470512317SGreg Clayton         platform_arch = arch;
11570512317SGreg Clayton 
116cac9c5f9SGreg Clayton     error = TargetList::CreateTarget (debugger,
117a0ca6601SGreg Clayton                                       user_exe_path,
11870512317SGreg Clayton                                       platform_arch,
119cac9c5f9SGreg Clayton                                       get_dependent_files,
120cac9c5f9SGreg Clayton                                       platform_sp,
121cac9c5f9SGreg Clayton                                       target_sp);
122cac9c5f9SGreg Clayton     return error;
123cac9c5f9SGreg Clayton }
124cac9c5f9SGreg Clayton 
125cac9c5f9SGreg Clayton Error
126a0ca6601SGreg Clayton TargetList::CreateTarget (Debugger &debugger,
127a0ca6601SGreg Clayton                           const char *user_exe_path,
12870512317SGreg Clayton                           const ArchSpec& specified_arch,
12930fdc8d8SChris Lattner                           bool get_dependent_files,
130b3a40ba8SGreg Clayton                           PlatformSP &platform_sp,
131a0ca6601SGreg Clayton                           TargetSP &target_sp)
13230fdc8d8SChris Lattner {
13330fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
134a0ca6601SGreg Clayton                         "TargetList::CreateTarget (file = '%s', arch = '%s')",
135a0ca6601SGreg Clayton                         user_exe_path,
13670512317SGreg Clayton                         specified_arch.GetArchitectureName());
1375aee162fSJim Ingham     Error error;
1385aee162fSJim Ingham 
13970512317SGreg Clayton     ArchSpec arch(specified_arch);
14070512317SGreg Clayton 
14170512317SGreg Clayton     if (platform_sp)
14270512317SGreg Clayton     {
14370512317SGreg Clayton         if (arch.IsValid())
14470512317SGreg Clayton         {
14570512317SGreg Clayton             if (!platform_sp->IsCompatibleArchitecture(arch))
14670512317SGreg Clayton                 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
14770512317SGreg Clayton         }
14870512317SGreg Clayton     }
14970512317SGreg Clayton     else if (arch.IsValid())
15070512317SGreg Clayton     {
15170512317SGreg Clayton         platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
15270512317SGreg Clayton     }
15370512317SGreg Clayton 
15470512317SGreg Clayton     if (!platform_sp)
15570512317SGreg Clayton         platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
156ded470d3SGreg Clayton 
1578ae50eb4SGreg Clayton     if (!arch.IsValid())
1588ae50eb4SGreg Clayton         arch = specified_arch;
1598ae50eb4SGreg Clayton 
160a0ca6601SGreg Clayton     FileSpec file (user_exe_path, false);
16182d79295SGreg Clayton     bool user_exe_path_is_bundle = false;
16282d79295SGreg Clayton     char resolved_bundle_exe_path[PATH_MAX];
16382d79295SGreg Clayton     resolved_bundle_exe_path[0] = '\0';
164e996fd30SGreg Clayton     if (file)
1655aee162fSJim Ingham     {
16682d79295SGreg Clayton         if (file.GetFileType() == FileSpec::eFileTypeDirectory)
16782d79295SGreg Clayton             user_exe_path_is_bundle = true;
16882d79295SGreg Clayton 
169a0ca6601SGreg Clayton         if (file.IsRelativeToCurrentWorkingDirectory())
170a0ca6601SGreg Clayton         {
171a0ca6601SGreg Clayton             // Ignore paths that start with "./" and "../"
172a0ca6601SGreg Clayton             if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
173a0ca6601SGreg Clayton                   (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/')))
174a0ca6601SGreg Clayton             {
175a0ca6601SGreg Clayton                 char cwd[PATH_MAX];
176a0ca6601SGreg Clayton                 if (getcwd (cwd, sizeof(cwd)))
177a0ca6601SGreg Clayton                 {
178a0ca6601SGreg Clayton                     std::string cwd_user_exe_path (cwd);
179a0ca6601SGreg Clayton                     cwd_user_exe_path += '/';
180a0ca6601SGreg Clayton                     cwd_user_exe_path += user_exe_path;
181a0ca6601SGreg Clayton                     file.SetFile(cwd_user_exe_path.c_str(), false);
182a0ca6601SGreg Clayton                 }
183a0ca6601SGreg Clayton             }
184a0ca6601SGreg Clayton         }
185a0ca6601SGreg Clayton 
18630fdc8d8SChris Lattner         ModuleSP exe_module_sp;
187e996fd30SGreg Clayton         if (platform_sp)
188c859e2d5SGreg Clayton         {
189c859e2d5SGreg Clayton             FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
19070512317SGreg Clayton             error = platform_sp->ResolveExecutable (file,
19170512317SGreg Clayton                                                     arch,
192c859e2d5SGreg Clayton                                                     exe_module_sp,
193c859e2d5SGreg Clayton                                                     executable_search_paths.GetSize() ? &executable_search_paths : NULL);
194c859e2d5SGreg Clayton         }
195428a9a58SCaroline Tice 
196e996fd30SGreg Clayton         if (error.Success() && exe_module_sp)
19730fdc8d8SChris Lattner         {
1985aee162fSJim Ingham             if (exe_module_sp->GetObjectFile() == NULL)
1995aee162fSJim Ingham             {
200bc5cad6cSGreg Clayton                 if (arch.IsValid())
201bc5cad6cSGreg Clayton                 {
202bc5cad6cSGreg Clayton                     error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
2035aee162fSJim Ingham                                                    file.GetDirectory().AsCString(),
2045aee162fSJim Ingham                                                    file.GetDirectory() ? "/" : "",
2055aee162fSJim Ingham                                                    file.GetFilename().AsCString(),
20664195a2cSGreg Clayton                                                    arch.GetArchitectureName());
207bc5cad6cSGreg Clayton                 }
208bc5cad6cSGreg Clayton                 else
209bc5cad6cSGreg Clayton                 {
210bc5cad6cSGreg Clayton                     error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
211bc5cad6cSGreg Clayton                                                    file.GetDirectory().AsCString(),
212bc5cad6cSGreg Clayton                                                    file.GetDirectory() ? "/" : "",
213bc5cad6cSGreg Clayton                                                    file.GetFilename().AsCString());
214bc5cad6cSGreg Clayton                 }
2155aee162fSJim Ingham                 return error;
2165aee162fSJim Ingham             }
21732e0a750SGreg Clayton             target_sp.reset(new Target(debugger, arch, platform_sp));
21830fdc8d8SChris Lattner             target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
21982d79295SGreg Clayton             if (user_exe_path_is_bundle)
22082d79295SGreg Clayton                 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
2215aee162fSJim Ingham         }
2225aee162fSJim Ingham     }
223e996fd30SGreg Clayton     else
224e996fd30SGreg Clayton     {
225e996fd30SGreg Clayton         // No file was specified, just create an empty target with any arch
226e996fd30SGreg Clayton         // if a valid arch was specified
22732e0a750SGreg Clayton         target_sp.reset(new Target(debugger, arch, platform_sp));
228e996fd30SGreg Clayton     }
2291559a46bSCaroline Tice 
230e996fd30SGreg Clayton     if (target_sp)
231e996fd30SGreg Clayton     {
23282d79295SGreg Clayton         // Set argv0 with what the user typed, unless the user specified a
23382d79295SGreg Clayton         // directory. If the user specified a directory, then it is probably a
23482d79295SGreg Clayton         // bundle that was resolved and we need to use the resolved bundle path
235a0ca6601SGreg Clayton         if (user_exe_path)
236a0ca6601SGreg Clayton         {
237a0ca6601SGreg Clayton             // Use exactly what the user typed as the first argument when we exec or posix_spawn
23882d79295SGreg Clayton             if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
23982d79295SGreg Clayton             {
24082d79295SGreg Clayton                 target_sp->SetArg0 (resolved_bundle_exe_path);
24182d79295SGreg Clayton             }
24282d79295SGreg Clayton             else
24382d79295SGreg Clayton             {
24482d79295SGreg Clayton                 // Just use what the user typed
245a0ca6601SGreg Clayton                 target_sp->SetArg0 (user_exe_path);
246a0ca6601SGreg Clayton             }
24782d79295SGreg Clayton         }
248a0ca6601SGreg Clayton         if (file.GetDirectory())
249a0ca6601SGreg Clayton         {
250a0ca6601SGreg Clayton             FileSpec file_dir;
251a0ca6601SGreg Clayton             file_dir.GetDirectory() = file.GetDirectory();
252a0ca6601SGreg Clayton             target_sp->GetExecutableSearchPaths ().Append (file_dir);
253a0ca6601SGreg Clayton         }
25430fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
2552976d00aSJim Ingham         m_selected_target_idx = m_target_list.size();
25630fdc8d8SChris Lattner         m_target_list.push_back(target_sp);
257a0ca6601SGreg Clayton 
258a0ca6601SGreg Clayton 
25930fdc8d8SChris Lattner     }
26030fdc8d8SChris Lattner 
26130fdc8d8SChris Lattner     return error;
26230fdc8d8SChris Lattner }
26330fdc8d8SChris Lattner 
26430fdc8d8SChris Lattner bool
26530fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp)
26630fdc8d8SChris Lattner {
26730fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
26830fdc8d8SChris Lattner     collection::iterator pos, end = m_target_list.end();
26930fdc8d8SChris Lattner 
27030fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
27130fdc8d8SChris Lattner     {
27230fdc8d8SChris Lattner         if (pos->get() == target_sp.get())
27330fdc8d8SChris Lattner         {
27430fdc8d8SChris Lattner             m_target_list.erase(pos);
27530fdc8d8SChris Lattner             return true;
27630fdc8d8SChris Lattner         }
27730fdc8d8SChris Lattner     }
27830fdc8d8SChris Lattner     return false;
27930fdc8d8SChris Lattner }
28030fdc8d8SChris Lattner 
28130fdc8d8SChris Lattner 
28230fdc8d8SChris Lattner TargetSP
28330fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture
28430fdc8d8SChris Lattner (
28530fdc8d8SChris Lattner     const FileSpec &exe_file_spec,
28630fdc8d8SChris Lattner     const ArchSpec *exe_arch_ptr
28730fdc8d8SChris Lattner ) const
28830fdc8d8SChris Lattner {
28930fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
29030fdc8d8SChris Lattner     TargetSP target_sp;
29130fdc8d8SChris Lattner     bool full_match = exe_file_spec.GetDirectory();
29230fdc8d8SChris Lattner 
29330fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
29430fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
29530fdc8d8SChris Lattner     {
296aa149cbdSGreg Clayton         Module *exe_module = (*pos)->GetExecutableModulePointer();
29730fdc8d8SChris Lattner 
298aa149cbdSGreg Clayton         if (exe_module)
29930fdc8d8SChris Lattner         {
300aa149cbdSGreg Clayton             if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
30130fdc8d8SChris Lattner             {
30230fdc8d8SChris Lattner                 if (exe_arch_ptr)
30330fdc8d8SChris Lattner                 {
304*bf4b7be6SSean Callanan                     if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
30530fdc8d8SChris Lattner                         continue;
30630fdc8d8SChris Lattner                 }
30730fdc8d8SChris Lattner                 target_sp = *pos;
30830fdc8d8SChris Lattner                 break;
30930fdc8d8SChris Lattner             }
31030fdc8d8SChris Lattner         }
31130fdc8d8SChris Lattner     }
31230fdc8d8SChris Lattner     return target_sp;
31330fdc8d8SChris Lattner }
31430fdc8d8SChris Lattner 
31530fdc8d8SChris Lattner TargetSP
31630fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
31730fdc8d8SChris Lattner {
31830fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
31930fdc8d8SChris Lattner     TargetSP target_sp;
32030fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
32130fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
32230fdc8d8SChris Lattner     {
32330fdc8d8SChris Lattner         Process* process = (*pos)->GetProcessSP().get();
32430fdc8d8SChris Lattner         if (process && process->GetID() == pid)
32530fdc8d8SChris Lattner         {
32630fdc8d8SChris Lattner             target_sp = *pos;
32730fdc8d8SChris Lattner             break;
32830fdc8d8SChris Lattner         }
32930fdc8d8SChris Lattner     }
33030fdc8d8SChris Lattner     return target_sp;
33130fdc8d8SChris Lattner }
33230fdc8d8SChris Lattner 
33330fdc8d8SChris Lattner 
33430fdc8d8SChris Lattner TargetSP
33530fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const
33630fdc8d8SChris Lattner {
33730fdc8d8SChris Lattner     TargetSP target_sp;
33830fdc8d8SChris Lattner     if (process)
33930fdc8d8SChris Lattner     {
34030fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
34130fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
34230fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
34330fdc8d8SChris Lattner         {
34430fdc8d8SChris Lattner             if (process == (*pos)->GetProcessSP().get())
34530fdc8d8SChris Lattner             {
34630fdc8d8SChris Lattner                 target_sp = *pos;
34730fdc8d8SChris Lattner                 break;
34830fdc8d8SChris Lattner             }
34930fdc8d8SChris Lattner         }
35030fdc8d8SChris Lattner     }
35130fdc8d8SChris Lattner     return target_sp;
35230fdc8d8SChris Lattner }
35330fdc8d8SChris Lattner 
35430fdc8d8SChris Lattner TargetSP
35530fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const
35630fdc8d8SChris Lattner {
35730fdc8d8SChris Lattner     TargetSP target_sp;
35830fdc8d8SChris Lattner     if (target)
35930fdc8d8SChris Lattner     {
36030fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
36130fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
36230fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
36330fdc8d8SChris Lattner         {
36430fdc8d8SChris Lattner             if (target == (*pos).get())
36530fdc8d8SChris Lattner             {
36630fdc8d8SChris Lattner                 target_sp = *pos;
36730fdc8d8SChris Lattner                 break;
36830fdc8d8SChris Lattner             }
36930fdc8d8SChris Lattner         }
37030fdc8d8SChris Lattner     }
37130fdc8d8SChris Lattner     return target_sp;
37230fdc8d8SChris Lattner }
37330fdc8d8SChris Lattner 
37430fdc8d8SChris Lattner uint32_t
37530fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid)
37630fdc8d8SChris Lattner {
37730fdc8d8SChris Lattner     uint32_t num_async_interrupts_sent = 0;
37830fdc8d8SChris Lattner 
37930fdc8d8SChris Lattner     if (pid != LLDB_INVALID_PROCESS_ID)
38030fdc8d8SChris Lattner     {
38130fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
38230fdc8d8SChris Lattner         if (target_sp.get())
38330fdc8d8SChris Lattner         {
38430fdc8d8SChris Lattner             Process* process = target_sp->GetProcessSP().get();
38530fdc8d8SChris Lattner             if (process)
38630fdc8d8SChris Lattner             {
387cfc0935eSJim Ingham                 process->SendAsyncInterrupt();
38830fdc8d8SChris Lattner                 ++num_async_interrupts_sent;
38930fdc8d8SChris Lattner             }
39030fdc8d8SChris Lattner         }
39130fdc8d8SChris Lattner     }
39230fdc8d8SChris Lattner     else
39330fdc8d8SChris Lattner     {
39430fdc8d8SChris Lattner         // We don't have a valid pid to broadcast to, so broadcast to the target
39530fdc8d8SChris Lattner         // list's async broadcaster...
39630fdc8d8SChris Lattner         BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
39730fdc8d8SChris Lattner     }
39830fdc8d8SChris Lattner 
39930fdc8d8SChris Lattner     return num_async_interrupts_sent;
40030fdc8d8SChris Lattner }
40130fdc8d8SChris Lattner 
40230fdc8d8SChris Lattner uint32_t
40330fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
40430fdc8d8SChris Lattner {
40530fdc8d8SChris Lattner     uint32_t num_signals_sent = 0;
40630fdc8d8SChris Lattner     Process *process = NULL;
40730fdc8d8SChris Lattner     if (pid == LLDB_INVALID_PROCESS_ID)
40830fdc8d8SChris Lattner     {
40930fdc8d8SChris Lattner         // Signal all processes with signal
41030fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
41130fdc8d8SChris Lattner         collection::iterator pos, end = m_target_list.end();
41230fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
41330fdc8d8SChris Lattner         {
41430fdc8d8SChris Lattner             process = (*pos)->GetProcessSP().get();
41530fdc8d8SChris Lattner             if (process)
41630fdc8d8SChris Lattner             {
41730fdc8d8SChris Lattner                 if (process->IsAlive())
41830fdc8d8SChris Lattner                 {
41930fdc8d8SChris Lattner                     ++num_signals_sent;
42030fdc8d8SChris Lattner                     process->Signal (signo);
42130fdc8d8SChris Lattner                 }
42230fdc8d8SChris Lattner             }
42330fdc8d8SChris Lattner         }
42430fdc8d8SChris Lattner     }
42530fdc8d8SChris Lattner     else
42630fdc8d8SChris Lattner     {
42730fdc8d8SChris Lattner         // Signal a specific process with signal
42830fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
42930fdc8d8SChris Lattner         if (target_sp.get())
43030fdc8d8SChris Lattner         {
43130fdc8d8SChris Lattner             process = target_sp->GetProcessSP().get();
43230fdc8d8SChris Lattner             if (process)
43330fdc8d8SChris Lattner             {
43430fdc8d8SChris Lattner                 if (process->IsAlive())
43530fdc8d8SChris Lattner                 {
43630fdc8d8SChris Lattner                     ++num_signals_sent;
43730fdc8d8SChris Lattner                     process->Signal (signo);
43830fdc8d8SChris Lattner                 }
43930fdc8d8SChris Lattner             }
44030fdc8d8SChris Lattner         }
44130fdc8d8SChris Lattner     }
44230fdc8d8SChris Lattner     return num_signals_sent;
44330fdc8d8SChris Lattner }
44430fdc8d8SChris Lattner 
44530fdc8d8SChris Lattner int
44630fdc8d8SChris Lattner TargetList::GetNumTargets () const
44730fdc8d8SChris Lattner {
44830fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
44930fdc8d8SChris Lattner     return m_target_list.size();
45030fdc8d8SChris Lattner }
45130fdc8d8SChris Lattner 
45230fdc8d8SChris Lattner lldb::TargetSP
45330fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const
45430fdc8d8SChris Lattner {
45530fdc8d8SChris Lattner     TargetSP target_sp;
45630fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
45730fdc8d8SChris Lattner     if (idx < m_target_list.size())
45830fdc8d8SChris Lattner         target_sp = m_target_list[idx];
45930fdc8d8SChris Lattner     return target_sp;
46030fdc8d8SChris Lattner }
46130fdc8d8SChris Lattner 
46230fdc8d8SChris Lattner uint32_t
4638499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
4648499e1a4SJim Ingham {
4658499e1a4SJim Ingham     Mutex::Locker locker (m_target_list_mutex);
4668499e1a4SJim Ingham     size_t num_targets = m_target_list.size();
4678499e1a4SJim Ingham     for (size_t idx = 0; idx < num_targets; idx++)
4688499e1a4SJim Ingham     {
4698499e1a4SJim Ingham         if (target_sp == m_target_list[idx])
4708499e1a4SJim Ingham             return idx;
4718499e1a4SJim Ingham     }
4728499e1a4SJim Ingham     return UINT32_MAX;
4738499e1a4SJim Ingham }
4748499e1a4SJim Ingham 
4758499e1a4SJim Ingham uint32_t
4762976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target)
47730fdc8d8SChris Lattner {
47830fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
47930fdc8d8SChris Lattner     collection::const_iterator pos,
48030fdc8d8SChris Lattner         begin = m_target_list.begin(),
48130fdc8d8SChris Lattner         end = m_target_list.end();
48230fdc8d8SChris Lattner     for (pos = begin; pos != end; ++pos)
48330fdc8d8SChris Lattner     {
48430fdc8d8SChris Lattner         if (pos->get() == target)
48530fdc8d8SChris Lattner         {
4862976d00aSJim Ingham             m_selected_target_idx = std::distance (begin, pos);
4872976d00aSJim Ingham             return m_selected_target_idx;
48830fdc8d8SChris Lattner         }
48930fdc8d8SChris Lattner     }
4902976d00aSJim Ingham     m_selected_target_idx = 0;
4912976d00aSJim Ingham     return m_selected_target_idx;
49230fdc8d8SChris Lattner }
49330fdc8d8SChris Lattner 
49430fdc8d8SChris Lattner lldb::TargetSP
4952976d00aSJim Ingham TargetList::GetSelectedTarget ()
49630fdc8d8SChris Lattner {
49730fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
4982976d00aSJim Ingham     if (m_selected_target_idx >= m_target_list.size())
4992976d00aSJim Ingham         m_selected_target_idx = 0;
5002976d00aSJim Ingham     return GetTargetAtIndex (m_selected_target_idx);
50130fdc8d8SChris Lattner }
502