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"
20f4d6de6aSGreg Clayton #include "lldb/Core/ModuleSpec.h"
2130fdc8d8SChris Lattner #include "lldb/Core/State.h"
2230fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
2330fdc8d8SChris Lattner #include "lldb/Host/Host.h"
24b3a40ba8SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
25cac9c5f9SGreg Clayton #include "lldb/Interpreter/OptionGroupPlatform.h"
26f4d6de6aSGreg Clayton #include "lldb/Symbol/ObjectFile.h"
27e996fd30SGreg Clayton #include "lldb/Target/Platform.h"
2830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2930fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
3030fdc8d8SChris Lattner 
3130fdc8d8SChris Lattner using namespace lldb;
3230fdc8d8SChris Lattner using namespace lldb_private;
3330fdc8d8SChris Lattner 
344bddaeb5SJim Ingham ConstString &
354bddaeb5SJim Ingham TargetList::GetStaticBroadcasterClass ()
364bddaeb5SJim Ingham {
374bddaeb5SJim Ingham     static ConstString class_name ("lldb.targetList");
384bddaeb5SJim Ingham     return class_name;
394bddaeb5SJim Ingham }
4030fdc8d8SChris Lattner 
4130fdc8d8SChris Lattner //----------------------------------------------------------------------
4230fdc8d8SChris Lattner // TargetList constructor
4330fdc8d8SChris Lattner //----------------------------------------------------------------------
444bddaeb5SJim Ingham TargetList::TargetList(Debugger &debugger) :
454f465cffSJim Ingham     Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
4630fdc8d8SChris Lattner     m_target_list(),
4730fdc8d8SChris Lattner     m_target_list_mutex (Mutex::eMutexTypeRecursive),
482976d00aSJim Ingham     m_selected_target_idx (0)
4930fdc8d8SChris Lattner {
504bddaeb5SJim Ingham     CheckInWithManager();
5130fdc8d8SChris Lattner }
5230fdc8d8SChris Lattner 
5330fdc8d8SChris Lattner //----------------------------------------------------------------------
5430fdc8d8SChris Lattner // Destructor
5530fdc8d8SChris Lattner //----------------------------------------------------------------------
5630fdc8d8SChris Lattner TargetList::~TargetList()
5730fdc8d8SChris Lattner {
5830fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
5930fdc8d8SChris Lattner     m_target_list.clear();
6030fdc8d8SChris Lattner }
6130fdc8d8SChris Lattner 
6230fdc8d8SChris Lattner Error
63cac9c5f9SGreg Clayton TargetList::CreateTarget (Debugger &debugger,
64a0ca6601SGreg Clayton                           const char *user_exe_path,
65cac9c5f9SGreg Clayton                           const char *triple_cstr,
66cac9c5f9SGreg Clayton                           bool get_dependent_files,
67cac9c5f9SGreg Clayton                           const OptionGroupPlatform *platform_options,
68cac9c5f9SGreg Clayton                           TargetSP &target_sp)
69cac9c5f9SGreg Clayton {
70cac9c5f9SGreg Clayton     Error error;
71cac9c5f9SGreg Clayton     PlatformSP platform_sp;
72cac9c5f9SGreg Clayton 
73cdc21d4cSJohnny Chen     // This is purposely left empty unless it is specified by triple_cstr.
74cdc21d4cSJohnny Chen     // If not initialized via triple_cstr, then the currently selected platform
75cdc21d4cSJohnny Chen     // will set the architecture correctly.
7670512317SGreg Clayton     const ArchSpec arch(triple_cstr);
7770512317SGreg Clayton     if (triple_cstr && triple_cstr[0])
78cac9c5f9SGreg Clayton     {
79cac9c5f9SGreg Clayton         if (!arch.IsValid())
80cac9c5f9SGreg Clayton         {
8186edbf41SGreg Clayton             error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
82cac9c5f9SGreg Clayton             return error;
83cac9c5f9SGreg Clayton         }
84cac9c5f9SGreg Clayton     }
85b3a40ba8SGreg Clayton 
8670512317SGreg Clayton     ArchSpec platform_arch(arch);
87f4d6de6aSGreg Clayton 
883f19ada8SGreg Clayton     bool prefer_platform_arch = false;
89f4d6de6aSGreg Clayton 
90f4d6de6aSGreg Clayton     if (user_exe_path && user_exe_path[0])
91f4d6de6aSGreg Clayton     {
92f4d6de6aSGreg Clayton         ModuleSpecList module_specs;
93f4d6de6aSGreg Clayton         ModuleSpec module_spec;
94f4d6de6aSGreg Clayton         module_spec.GetFileSpec().SetFile(user_exe_path, true);
95*c76fa8a3SGreg Clayton 
96*c76fa8a3SGreg Clayton         // Resolve the executable in case we are given a path to a application bundle
97*c76fa8a3SGreg Clayton         // like a .app bundle on MacOSX
98*c76fa8a3SGreg Clayton         Host::ResolveExecutableInBundle (module_spec.GetFileSpec());
99*c76fa8a3SGreg Clayton 
100f4d6de6aSGreg Clayton         lldb::offset_t file_offset = 0;
1012540a8a7SGreg Clayton         lldb::offset_t file_size = 0;
1022540a8a7SGreg Clayton         const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs);
103f4d6de6aSGreg Clayton         if (num_specs > 0)
104f4d6de6aSGreg Clayton         {
105f4d6de6aSGreg Clayton             ModuleSpec matching_module_spec;
106f4d6de6aSGreg Clayton 
107f4d6de6aSGreg Clayton             if (num_specs == 1)
108f4d6de6aSGreg Clayton             {
109f4d6de6aSGreg Clayton                 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
110f4d6de6aSGreg Clayton                 {
111f4d6de6aSGreg Clayton                     if (platform_arch.IsValid())
112f4d6de6aSGreg Clayton                     {
1133f19ada8SGreg Clayton                         if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture()))
1143f19ada8SGreg Clayton                         {
1153f19ada8SGreg Clayton                             // If the OS or vendor weren't specified, then adopt the module's
1163f19ada8SGreg Clayton                             // architecture so that the platform matching can be more accurate
1173f19ada8SGreg Clayton                             if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified())
1183f19ada8SGreg Clayton                             {
1193f19ada8SGreg Clayton                                 prefer_platform_arch = true;
1203f19ada8SGreg Clayton                                 platform_arch = matching_module_spec.GetArchitecture();
1213f19ada8SGreg Clayton                             }
1223f19ada8SGreg Clayton                         }
1233f19ada8SGreg Clayton                         else
124f4d6de6aSGreg Clayton                         {
125b5ad4ec7SGreg Clayton                             error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'",
126f4d6de6aSGreg Clayton                                                            platform_arch.GetTriple().str().c_str(),
127f4d6de6aSGreg Clayton                                                            matching_module_spec.GetArchitecture().GetTriple().str().c_str(),
128b5ad4ec7SGreg Clayton                                                            module_spec.GetFileSpec().GetPath().c_str());
129f4d6de6aSGreg Clayton                             return error;
130f4d6de6aSGreg Clayton                         }
131f4d6de6aSGreg Clayton                     }
132f4d6de6aSGreg Clayton                     else
133f4d6de6aSGreg Clayton                     {
134f4d6de6aSGreg Clayton                         // Only one arch and none was specified
1353f19ada8SGreg Clayton                         prefer_platform_arch = true;
136f4d6de6aSGreg Clayton                         platform_arch = matching_module_spec.GetArchitecture();
137f4d6de6aSGreg Clayton                     }
138f4d6de6aSGreg Clayton                 }
139f4d6de6aSGreg Clayton             }
140f4d6de6aSGreg Clayton             else
141f4d6de6aSGreg Clayton             {
142f4d6de6aSGreg Clayton                 if (arch.IsValid())
143f4d6de6aSGreg Clayton                 {
144f4d6de6aSGreg Clayton                     module_spec.GetArchitecture() = arch;
145f4d6de6aSGreg Clayton                     if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec))
146f4d6de6aSGreg Clayton                     {
1473f19ada8SGreg Clayton                         prefer_platform_arch = true;
148f4d6de6aSGreg Clayton                         platform_arch = matching_module_spec.GetArchitecture();
149f4d6de6aSGreg Clayton                     }
150f4d6de6aSGreg Clayton                 }
151f4d6de6aSGreg Clayton             }
152f4d6de6aSGreg Clayton         }
153f4d6de6aSGreg Clayton     }
154f4d6de6aSGreg Clayton 
155b3a40ba8SGreg Clayton     CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
156b3a40ba8SGreg Clayton     if (platform_options)
157b3a40ba8SGreg Clayton     {
158b3a40ba8SGreg Clayton         if (platform_options->PlatformWasSpecified ())
159b3a40ba8SGreg Clayton         {
160b3a40ba8SGreg Clayton             const bool select_platform = true;
161b3a40ba8SGreg Clayton             platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
162b3a40ba8SGreg Clayton                                                                        arch,
163b3a40ba8SGreg Clayton                                                                        select_platform,
16470512317SGreg Clayton                                                                        error,
16570512317SGreg Clayton                                                                        platform_arch);
166b3a40ba8SGreg Clayton             if (!platform_sp)
167b3a40ba8SGreg Clayton                 return error;
168b3a40ba8SGreg Clayton         }
169b3a40ba8SGreg Clayton     }
170b3a40ba8SGreg Clayton 
171b3a40ba8SGreg Clayton     if (!platform_sp)
172b3a40ba8SGreg Clayton     {
173b3a40ba8SGreg Clayton         // Get the current platform and make sure it is compatible with the
174b3a40ba8SGreg Clayton         // current architecture if we have a valid architecture.
175b3a40ba8SGreg Clayton         platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
176b3a40ba8SGreg Clayton 
1773f19ada8SGreg Clayton         if (!prefer_platform_arch && arch.IsValid())
178b3a40ba8SGreg Clayton         {
1793f19ada8SGreg Clayton             if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
18070512317SGreg Clayton                 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
181b3a40ba8SGreg Clayton         }
1823f19ada8SGreg Clayton         else if (platform_arch.IsValid())
1833f19ada8SGreg Clayton         {
1843f19ada8SGreg Clayton             // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with
1853f19ada8SGreg Clayton             // a single architecture which should be used
1863f19ada8SGreg Clayton             ArchSpec fixed_platform_arch;
1873f19ada8SGreg Clayton             if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch))
1883f19ada8SGreg Clayton                 platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch);
1893f19ada8SGreg Clayton         }
190b3a40ba8SGreg Clayton     }
191b3a40ba8SGreg Clayton 
19270512317SGreg Clayton     if (!platform_arch.IsValid())
19370512317SGreg Clayton         platform_arch = arch;
19470512317SGreg Clayton 
195cac9c5f9SGreg Clayton     error = TargetList::CreateTarget (debugger,
196a0ca6601SGreg Clayton                                       user_exe_path,
19770512317SGreg Clayton                                       platform_arch,
198cac9c5f9SGreg Clayton                                       get_dependent_files,
199cac9c5f9SGreg Clayton                                       platform_sp,
200cac9c5f9SGreg Clayton                                       target_sp);
201cac9c5f9SGreg Clayton     return error;
202cac9c5f9SGreg Clayton }
203cac9c5f9SGreg Clayton 
204cac9c5f9SGreg Clayton Error
205a0ca6601SGreg Clayton TargetList::CreateTarget (Debugger &debugger,
206a0ca6601SGreg Clayton                           const char *user_exe_path,
20770512317SGreg Clayton                           const ArchSpec& specified_arch,
20830fdc8d8SChris Lattner                           bool get_dependent_files,
209b3a40ba8SGreg Clayton                           PlatformSP &platform_sp,
210a0ca6601SGreg Clayton                           TargetSP &target_sp)
21130fdc8d8SChris Lattner {
21230fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
213a0ca6601SGreg Clayton                         "TargetList::CreateTarget (file = '%s', arch = '%s')",
214a0ca6601SGreg Clayton                         user_exe_path,
21570512317SGreg Clayton                         specified_arch.GetArchitectureName());
2165aee162fSJim Ingham     Error error;
2175aee162fSJim Ingham 
21870512317SGreg Clayton     ArchSpec arch(specified_arch);
21970512317SGreg Clayton 
22070512317SGreg Clayton     if (platform_sp)
22170512317SGreg Clayton     {
22270512317SGreg Clayton         if (arch.IsValid())
22370512317SGreg Clayton         {
2241e0c8840SGreg Clayton             if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL))
22570512317SGreg Clayton                 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
22670512317SGreg Clayton         }
22770512317SGreg Clayton     }
22870512317SGreg Clayton     else if (arch.IsValid())
22970512317SGreg Clayton     {
23070512317SGreg Clayton         platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
23170512317SGreg Clayton     }
23270512317SGreg Clayton 
23370512317SGreg Clayton     if (!platform_sp)
23470512317SGreg Clayton         platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
235ded470d3SGreg Clayton 
2368ae50eb4SGreg Clayton     if (!arch.IsValid())
2378ae50eb4SGreg Clayton         arch = specified_arch;
2388ae50eb4SGreg Clayton 
239d26206b5SJason Molenda     FileSpec file (user_exe_path, false);
240d26206b5SJason Molenda     if (!file.Exists() && user_exe_path && user_exe_path[0] == '~')
241d26206b5SJason Molenda     {
2429f822cd1SMichael Sartain         // we want to expand the tilde but we don't want to resolve any symbolic links
2439f822cd1SMichael Sartain         // so we can't use the FileSpec constructor's resolve flag
2449f822cd1SMichael Sartain         char unglobbed_path[PATH_MAX];
2459f822cd1SMichael Sartain         unglobbed_path[0] = '\0';
2469f822cd1SMichael Sartain 
2479f822cd1SMichael Sartain         size_t return_count = FileSpec::ResolveUsername(user_exe_path, unglobbed_path, sizeof(unglobbed_path));
2489f822cd1SMichael Sartain 
2499f822cd1SMichael Sartain         if (return_count == 0 || return_count >= sizeof(unglobbed_path))
2509f822cd1SMichael Sartain             ::snprintf (unglobbed_path, sizeof(unglobbed_path), "%s", user_exe_path);
2519f822cd1SMichael Sartain 
2529f822cd1SMichael Sartain         file = FileSpec(unglobbed_path, false);
253d26206b5SJason Molenda     }
2549f822cd1SMichael Sartain 
25582d79295SGreg Clayton     bool user_exe_path_is_bundle = false;
25682d79295SGreg Clayton     char resolved_bundle_exe_path[PATH_MAX];
25782d79295SGreg Clayton     resolved_bundle_exe_path[0] = '\0';
258e996fd30SGreg Clayton     if (file)
2595aee162fSJim Ingham     {
26082d79295SGreg Clayton         if (file.GetFileType() == FileSpec::eFileTypeDirectory)
26182d79295SGreg Clayton             user_exe_path_is_bundle = true;
26282d79295SGreg Clayton 
263a0ca6601SGreg Clayton         if (file.IsRelativeToCurrentWorkingDirectory())
264a0ca6601SGreg Clayton         {
265a0ca6601SGreg Clayton             // Ignore paths that start with "./" and "../"
266a0ca6601SGreg Clayton             if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
267a0ca6601SGreg Clayton                   (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/')))
268a0ca6601SGreg Clayton             {
269a0ca6601SGreg Clayton                 char cwd[PATH_MAX];
270a0ca6601SGreg Clayton                 if (getcwd (cwd, sizeof(cwd)))
271a0ca6601SGreg Clayton                 {
272a0ca6601SGreg Clayton                     std::string cwd_user_exe_path (cwd);
273a0ca6601SGreg Clayton                     cwd_user_exe_path += '/';
274a0ca6601SGreg Clayton                     cwd_user_exe_path += user_exe_path;
2759ff5aae5SGreg Clayton                     FileSpec cwd_file (cwd_user_exe_path.c_str(), false);
2769ff5aae5SGreg Clayton                     if (cwd_file.Exists())
2779ff5aae5SGreg Clayton                         file = cwd_file;
278a0ca6601SGreg Clayton                 }
279a0ca6601SGreg Clayton             }
280a0ca6601SGreg Clayton         }
281a0ca6601SGreg Clayton 
28230fdc8d8SChris Lattner         ModuleSP exe_module_sp;
283e996fd30SGreg Clayton         if (platform_sp)
284c859e2d5SGreg Clayton         {
285c859e2d5SGreg Clayton             FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
28670512317SGreg Clayton             error = platform_sp->ResolveExecutable (file,
28770512317SGreg Clayton                                                     arch,
288c859e2d5SGreg Clayton                                                     exe_module_sp,
289c859e2d5SGreg Clayton                                                     executable_search_paths.GetSize() ? &executable_search_paths : NULL);
290c859e2d5SGreg Clayton         }
291428a9a58SCaroline Tice 
292e996fd30SGreg Clayton         if (error.Success() && exe_module_sp)
29330fdc8d8SChris Lattner         {
2945aee162fSJim Ingham             if (exe_module_sp->GetObjectFile() == NULL)
2955aee162fSJim Ingham             {
296bc5cad6cSGreg Clayton                 if (arch.IsValid())
297bc5cad6cSGreg Clayton                 {
298b5ad4ec7SGreg Clayton                     error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s",
299b5ad4ec7SGreg Clayton                                                    file.GetPath().c_str(),
30064195a2cSGreg Clayton                                                    arch.GetArchitectureName());
301bc5cad6cSGreg Clayton                 }
302bc5cad6cSGreg Clayton                 else
303bc5cad6cSGreg Clayton                 {
304b5ad4ec7SGreg Clayton                     error.SetErrorStringWithFormat("unsupported file type \"%s\"",
305b5ad4ec7SGreg Clayton                                                    file.GetPath().c_str());
306bc5cad6cSGreg Clayton                 }
3075aee162fSJim Ingham                 return error;
3085aee162fSJim Ingham             }
30932e0a750SGreg Clayton             target_sp.reset(new Target(debugger, arch, platform_sp));
31030fdc8d8SChris Lattner             target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
31182d79295SGreg Clayton             if (user_exe_path_is_bundle)
31282d79295SGreg Clayton                 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
3135aee162fSJim Ingham         }
3145aee162fSJim Ingham     }
315e996fd30SGreg Clayton     else
316e996fd30SGreg Clayton     {
317e996fd30SGreg Clayton         // No file was specified, just create an empty target with any arch
318e996fd30SGreg Clayton         // if a valid arch was specified
31932e0a750SGreg Clayton         target_sp.reset(new Target(debugger, arch, platform_sp));
320e996fd30SGreg Clayton     }
3211559a46bSCaroline Tice 
322e996fd30SGreg Clayton     if (target_sp)
323e996fd30SGreg Clayton     {
32482d79295SGreg Clayton         // Set argv0 with what the user typed, unless the user specified a
32582d79295SGreg Clayton         // directory. If the user specified a directory, then it is probably a
32682d79295SGreg Clayton         // bundle that was resolved and we need to use the resolved bundle path
327a0ca6601SGreg Clayton         if (user_exe_path)
328a0ca6601SGreg Clayton         {
329a0ca6601SGreg Clayton             // Use exactly what the user typed as the first argument when we exec or posix_spawn
33082d79295SGreg Clayton             if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
33182d79295SGreg Clayton             {
33282d79295SGreg Clayton                 target_sp->SetArg0 (resolved_bundle_exe_path);
33382d79295SGreg Clayton             }
33482d79295SGreg Clayton             else
33582d79295SGreg Clayton             {
3369f822cd1SMichael Sartain                 // Use resolved path
3379f822cd1SMichael Sartain                 target_sp->SetArg0 (file.GetPath().c_str());
338a0ca6601SGreg Clayton             }
33982d79295SGreg Clayton         }
340a0ca6601SGreg Clayton         if (file.GetDirectory())
341a0ca6601SGreg Clayton         {
342a0ca6601SGreg Clayton             FileSpec file_dir;
343a0ca6601SGreg Clayton             file_dir.GetDirectory() = file.GetDirectory();
344a0ca6601SGreg Clayton             target_sp->GetExecutableSearchPaths ().Append (file_dir);
345a0ca6601SGreg Clayton         }
34630fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
3472976d00aSJim Ingham         m_selected_target_idx = m_target_list.size();
34830fdc8d8SChris Lattner         m_target_list.push_back(target_sp);
349a0ca6601SGreg Clayton 
350a0ca6601SGreg Clayton 
35130fdc8d8SChris Lattner     }
35230fdc8d8SChris Lattner 
35330fdc8d8SChris Lattner     return error;
35430fdc8d8SChris Lattner }
35530fdc8d8SChris Lattner 
35630fdc8d8SChris Lattner bool
35730fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp)
35830fdc8d8SChris Lattner {
35930fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
36030fdc8d8SChris Lattner     collection::iterator pos, end = m_target_list.end();
36130fdc8d8SChris Lattner 
36230fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
36330fdc8d8SChris Lattner     {
36430fdc8d8SChris Lattner         if (pos->get() == target_sp.get())
36530fdc8d8SChris Lattner         {
36630fdc8d8SChris Lattner             m_target_list.erase(pos);
36730fdc8d8SChris Lattner             return true;
36830fdc8d8SChris Lattner         }
36930fdc8d8SChris Lattner     }
37030fdc8d8SChris Lattner     return false;
37130fdc8d8SChris Lattner }
37230fdc8d8SChris Lattner 
37330fdc8d8SChris Lattner 
37430fdc8d8SChris Lattner TargetSP
37530fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture
37630fdc8d8SChris Lattner (
37730fdc8d8SChris Lattner     const FileSpec &exe_file_spec,
37830fdc8d8SChris Lattner     const ArchSpec *exe_arch_ptr
37930fdc8d8SChris Lattner ) const
38030fdc8d8SChris Lattner {
38130fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
38230fdc8d8SChris Lattner     TargetSP target_sp;
383ddd7a2a6SSean Callanan     bool full_match = (bool)exe_file_spec.GetDirectory();
38430fdc8d8SChris Lattner 
38530fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
38630fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
38730fdc8d8SChris Lattner     {
388aa149cbdSGreg Clayton         Module *exe_module = (*pos)->GetExecutableModulePointer();
38930fdc8d8SChris Lattner 
390aa149cbdSGreg Clayton         if (exe_module)
39130fdc8d8SChris Lattner         {
392aa149cbdSGreg Clayton             if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
39330fdc8d8SChris Lattner             {
39430fdc8d8SChris Lattner                 if (exe_arch_ptr)
39530fdc8d8SChris Lattner                 {
396bf4b7be6SSean Callanan                     if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
39730fdc8d8SChris Lattner                         continue;
39830fdc8d8SChris Lattner                 }
39930fdc8d8SChris Lattner                 target_sp = *pos;
40030fdc8d8SChris Lattner                 break;
40130fdc8d8SChris Lattner             }
40230fdc8d8SChris Lattner         }
40330fdc8d8SChris Lattner     }
40430fdc8d8SChris Lattner     return target_sp;
40530fdc8d8SChris Lattner }
40630fdc8d8SChris Lattner 
40730fdc8d8SChris Lattner TargetSP
40830fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
40930fdc8d8SChris Lattner {
41030fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
41130fdc8d8SChris Lattner     TargetSP target_sp;
41230fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
41330fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
41430fdc8d8SChris Lattner     {
41530fdc8d8SChris Lattner         Process* process = (*pos)->GetProcessSP().get();
41630fdc8d8SChris Lattner         if (process && process->GetID() == pid)
41730fdc8d8SChris Lattner         {
41830fdc8d8SChris Lattner             target_sp = *pos;
41930fdc8d8SChris Lattner             break;
42030fdc8d8SChris Lattner         }
42130fdc8d8SChris Lattner     }
42230fdc8d8SChris Lattner     return target_sp;
42330fdc8d8SChris Lattner }
42430fdc8d8SChris Lattner 
42530fdc8d8SChris Lattner 
42630fdc8d8SChris Lattner TargetSP
42730fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const
42830fdc8d8SChris Lattner {
42930fdc8d8SChris Lattner     TargetSP target_sp;
43030fdc8d8SChris Lattner     if (process)
43130fdc8d8SChris Lattner     {
43230fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
43330fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
43430fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
43530fdc8d8SChris Lattner         {
43630fdc8d8SChris Lattner             if (process == (*pos)->GetProcessSP().get())
43730fdc8d8SChris Lattner             {
43830fdc8d8SChris Lattner                 target_sp = *pos;
43930fdc8d8SChris Lattner                 break;
44030fdc8d8SChris Lattner             }
44130fdc8d8SChris Lattner         }
44230fdc8d8SChris Lattner     }
44330fdc8d8SChris Lattner     return target_sp;
44430fdc8d8SChris Lattner }
44530fdc8d8SChris Lattner 
44630fdc8d8SChris Lattner TargetSP
44730fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const
44830fdc8d8SChris Lattner {
44930fdc8d8SChris Lattner     TargetSP target_sp;
45030fdc8d8SChris Lattner     if (target)
45130fdc8d8SChris Lattner     {
45230fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
45330fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
45430fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
45530fdc8d8SChris Lattner         {
45630fdc8d8SChris Lattner             if (target == (*pos).get())
45730fdc8d8SChris Lattner             {
45830fdc8d8SChris Lattner                 target_sp = *pos;
45930fdc8d8SChris Lattner                 break;
46030fdc8d8SChris Lattner             }
46130fdc8d8SChris Lattner         }
46230fdc8d8SChris Lattner     }
46330fdc8d8SChris Lattner     return target_sp;
46430fdc8d8SChris Lattner }
46530fdc8d8SChris Lattner 
46630fdc8d8SChris Lattner uint32_t
46730fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid)
46830fdc8d8SChris Lattner {
46930fdc8d8SChris Lattner     uint32_t num_async_interrupts_sent = 0;
47030fdc8d8SChris Lattner 
47130fdc8d8SChris Lattner     if (pid != LLDB_INVALID_PROCESS_ID)
47230fdc8d8SChris Lattner     {
47330fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
47430fdc8d8SChris Lattner         if (target_sp.get())
47530fdc8d8SChris Lattner         {
47630fdc8d8SChris Lattner             Process* process = target_sp->GetProcessSP().get();
47730fdc8d8SChris Lattner             if (process)
47830fdc8d8SChris Lattner             {
479cfc0935eSJim Ingham                 process->SendAsyncInterrupt();
48030fdc8d8SChris Lattner                 ++num_async_interrupts_sent;
48130fdc8d8SChris Lattner             }
48230fdc8d8SChris Lattner         }
48330fdc8d8SChris Lattner     }
48430fdc8d8SChris Lattner     else
48530fdc8d8SChris Lattner     {
48630fdc8d8SChris Lattner         // We don't have a valid pid to broadcast to, so broadcast to the target
48730fdc8d8SChris Lattner         // list's async broadcaster...
48830fdc8d8SChris Lattner         BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
48930fdc8d8SChris Lattner     }
49030fdc8d8SChris Lattner 
49130fdc8d8SChris Lattner     return num_async_interrupts_sent;
49230fdc8d8SChris Lattner }
49330fdc8d8SChris Lattner 
49430fdc8d8SChris Lattner uint32_t
49530fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
49630fdc8d8SChris Lattner {
49730fdc8d8SChris Lattner     uint32_t num_signals_sent = 0;
49830fdc8d8SChris Lattner     Process *process = NULL;
49930fdc8d8SChris Lattner     if (pid == LLDB_INVALID_PROCESS_ID)
50030fdc8d8SChris Lattner     {
50130fdc8d8SChris Lattner         // Signal all processes with signal
50230fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
50330fdc8d8SChris Lattner         collection::iterator pos, end = m_target_list.end();
50430fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
50530fdc8d8SChris Lattner         {
50630fdc8d8SChris Lattner             process = (*pos)->GetProcessSP().get();
50730fdc8d8SChris Lattner             if (process)
50830fdc8d8SChris Lattner             {
50930fdc8d8SChris Lattner                 if (process->IsAlive())
51030fdc8d8SChris Lattner                 {
51130fdc8d8SChris Lattner                     ++num_signals_sent;
51230fdc8d8SChris Lattner                     process->Signal (signo);
51330fdc8d8SChris Lattner                 }
51430fdc8d8SChris Lattner             }
51530fdc8d8SChris Lattner         }
51630fdc8d8SChris Lattner     }
51730fdc8d8SChris Lattner     else
51830fdc8d8SChris Lattner     {
51930fdc8d8SChris Lattner         // Signal a specific process with signal
52030fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
52130fdc8d8SChris Lattner         if (target_sp.get())
52230fdc8d8SChris Lattner         {
52330fdc8d8SChris Lattner             process = target_sp->GetProcessSP().get();
52430fdc8d8SChris Lattner             if (process)
52530fdc8d8SChris Lattner             {
52630fdc8d8SChris Lattner                 if (process->IsAlive())
52730fdc8d8SChris Lattner                 {
52830fdc8d8SChris Lattner                     ++num_signals_sent;
52930fdc8d8SChris Lattner                     process->Signal (signo);
53030fdc8d8SChris Lattner                 }
53130fdc8d8SChris Lattner             }
53230fdc8d8SChris Lattner         }
53330fdc8d8SChris Lattner     }
53430fdc8d8SChris Lattner     return num_signals_sent;
53530fdc8d8SChris Lattner }
53630fdc8d8SChris Lattner 
53730fdc8d8SChris Lattner int
53830fdc8d8SChris Lattner TargetList::GetNumTargets () const
53930fdc8d8SChris Lattner {
54030fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
54130fdc8d8SChris Lattner     return m_target_list.size();
54230fdc8d8SChris Lattner }
54330fdc8d8SChris Lattner 
54430fdc8d8SChris Lattner lldb::TargetSP
54530fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const
54630fdc8d8SChris Lattner {
54730fdc8d8SChris Lattner     TargetSP target_sp;
54830fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
54930fdc8d8SChris Lattner     if (idx < m_target_list.size())
55030fdc8d8SChris Lattner         target_sp = m_target_list[idx];
55130fdc8d8SChris Lattner     return target_sp;
55230fdc8d8SChris Lattner }
55330fdc8d8SChris Lattner 
55430fdc8d8SChris Lattner uint32_t
5558499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
5568499e1a4SJim Ingham {
5578499e1a4SJim Ingham     Mutex::Locker locker (m_target_list_mutex);
5588499e1a4SJim Ingham     size_t num_targets = m_target_list.size();
5598499e1a4SJim Ingham     for (size_t idx = 0; idx < num_targets; idx++)
5608499e1a4SJim Ingham     {
5618499e1a4SJim Ingham         if (target_sp == m_target_list[idx])
5628499e1a4SJim Ingham             return idx;
5638499e1a4SJim Ingham     }
5648499e1a4SJim Ingham     return UINT32_MAX;
5658499e1a4SJim Ingham }
5668499e1a4SJim Ingham 
5678499e1a4SJim Ingham uint32_t
5682976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target)
56930fdc8d8SChris Lattner {
57030fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
57130fdc8d8SChris Lattner     collection::const_iterator pos,
57230fdc8d8SChris Lattner         begin = m_target_list.begin(),
57330fdc8d8SChris Lattner         end = m_target_list.end();
57430fdc8d8SChris Lattner     for (pos = begin; pos != end; ++pos)
57530fdc8d8SChris Lattner     {
57630fdc8d8SChris Lattner         if (pos->get() == target)
57730fdc8d8SChris Lattner         {
5782976d00aSJim Ingham             m_selected_target_idx = std::distance (begin, pos);
5792976d00aSJim Ingham             return m_selected_target_idx;
58030fdc8d8SChris Lattner         }
58130fdc8d8SChris Lattner     }
5822976d00aSJim Ingham     m_selected_target_idx = 0;
5832976d00aSJim Ingham     return m_selected_target_idx;
58430fdc8d8SChris Lattner }
58530fdc8d8SChris Lattner 
58630fdc8d8SChris Lattner lldb::TargetSP
5872976d00aSJim Ingham TargetList::GetSelectedTarget ()
58830fdc8d8SChris Lattner {
58930fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
5902976d00aSJim Ingham     if (m_selected_target_idx >= m_target_list.size())
5912976d00aSJim Ingham         m_selected_target_idx = 0;
5922976d00aSJim Ingham     return GetTargetAtIndex (m_selected_target_idx);
59330fdc8d8SChris Lattner }
594