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 
88f4d6de6aSGreg Clayton 
89f4d6de6aSGreg Clayton     if (user_exe_path && user_exe_path[0])
90f4d6de6aSGreg Clayton     {
91f4d6de6aSGreg Clayton         ModuleSpecList module_specs;
92f4d6de6aSGreg Clayton         ModuleSpec module_spec;
93f4d6de6aSGreg Clayton         module_spec.GetFileSpec().SetFile(user_exe_path, true);
94f4d6de6aSGreg Clayton         lldb::offset_t file_offset = 0;
952540a8a7SGreg Clayton         lldb::offset_t file_size = 0;
962540a8a7SGreg Clayton         const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs);
97f4d6de6aSGreg Clayton         if (num_specs > 0)
98f4d6de6aSGreg Clayton         {
99f4d6de6aSGreg Clayton             ModuleSpec matching_module_spec;
100f4d6de6aSGreg Clayton 
101f4d6de6aSGreg Clayton             if (num_specs == 1)
102f4d6de6aSGreg Clayton             {
103f4d6de6aSGreg Clayton                 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
104f4d6de6aSGreg Clayton                 {
105f4d6de6aSGreg Clayton                     if (platform_arch.IsValid())
106f4d6de6aSGreg Clayton                     {
107f4d6de6aSGreg Clayton                         if (!platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture()))
108f4d6de6aSGreg Clayton                         {
109b5ad4ec7SGreg Clayton                             error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'",
110f4d6de6aSGreg Clayton                                                            platform_arch.GetTriple().str().c_str(),
111f4d6de6aSGreg Clayton                                                            matching_module_spec.GetArchitecture().GetTriple().str().c_str(),
112b5ad4ec7SGreg Clayton                                                            module_spec.GetFileSpec().GetPath().c_str());
113f4d6de6aSGreg Clayton                             return error;
114f4d6de6aSGreg Clayton                         }
115f4d6de6aSGreg Clayton                     }
116f4d6de6aSGreg Clayton                     else
117f4d6de6aSGreg Clayton                     {
118f4d6de6aSGreg Clayton                         // Only one arch and none was specified
119f4d6de6aSGreg Clayton                         platform_arch = matching_module_spec.GetArchitecture();
120f4d6de6aSGreg Clayton                     }
121f4d6de6aSGreg Clayton                 }
122f4d6de6aSGreg Clayton             }
123f4d6de6aSGreg Clayton             else
124f4d6de6aSGreg Clayton             {
125f4d6de6aSGreg Clayton                 if (arch.IsValid())
126f4d6de6aSGreg Clayton                 {
127f4d6de6aSGreg Clayton                     module_spec.GetArchitecture() = arch;
128f4d6de6aSGreg Clayton                     if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec))
129f4d6de6aSGreg Clayton                     {
130f4d6de6aSGreg Clayton                         platform_arch = matching_module_spec.GetArchitecture();
131f4d6de6aSGreg Clayton                     }
132f4d6de6aSGreg Clayton                 }
133b23b1130SGreg Clayton                 // Don't just select the first architecture, we want to let the platform select
134b23b1130SGreg Clayton                 // the best architecture first when there are multiple archs.
135b23b1130SGreg Clayton //                else
136b23b1130SGreg Clayton //                {
137b23b1130SGreg Clayton //                    // No arch specified, select the first arch
138b23b1130SGreg Clayton //                    if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
139b23b1130SGreg Clayton //                    {
140b23b1130SGreg Clayton //                        platform_arch = matching_module_spec.GetArchitecture();
141b23b1130SGreg Clayton //                    }
142b23b1130SGreg Clayton //                }
143f4d6de6aSGreg Clayton             }
144f4d6de6aSGreg Clayton         }
145f4d6de6aSGreg Clayton     }
146f4d6de6aSGreg Clayton 
147b3a40ba8SGreg Clayton     CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
148b3a40ba8SGreg Clayton     if (platform_options)
149b3a40ba8SGreg Clayton     {
150b3a40ba8SGreg Clayton         if (platform_options->PlatformWasSpecified ())
151b3a40ba8SGreg Clayton         {
152b3a40ba8SGreg Clayton             const bool select_platform = true;
153b3a40ba8SGreg Clayton             platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
154b3a40ba8SGreg Clayton                                                                        arch,
155b3a40ba8SGreg Clayton                                                                        select_platform,
15670512317SGreg Clayton                                                                        error,
15770512317SGreg Clayton                                                                        platform_arch);
158b3a40ba8SGreg Clayton             if (!platform_sp)
159b3a40ba8SGreg Clayton                 return error;
160b3a40ba8SGreg Clayton         }
161b3a40ba8SGreg Clayton     }
162b3a40ba8SGreg Clayton 
163b3a40ba8SGreg Clayton     if (!platform_sp)
164b3a40ba8SGreg Clayton     {
165b3a40ba8SGreg Clayton         // Get the current platform and make sure it is compatible with the
166b3a40ba8SGreg Clayton         // current architecture if we have a valid architecture.
167b3a40ba8SGreg Clayton         platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
168b3a40ba8SGreg Clayton 
1691e0c8840SGreg Clayton         if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
170b3a40ba8SGreg Clayton         {
17170512317SGreg Clayton             platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
172b3a40ba8SGreg Clayton         }
173b3a40ba8SGreg Clayton     }
174b3a40ba8SGreg Clayton 
17570512317SGreg Clayton     if (!platform_arch.IsValid())
17670512317SGreg Clayton         platform_arch = arch;
17770512317SGreg Clayton 
178cac9c5f9SGreg Clayton     error = TargetList::CreateTarget (debugger,
179a0ca6601SGreg Clayton                                       user_exe_path,
18070512317SGreg Clayton                                       platform_arch,
181cac9c5f9SGreg Clayton                                       get_dependent_files,
182cac9c5f9SGreg Clayton                                       platform_sp,
183cac9c5f9SGreg Clayton                                       target_sp);
184cac9c5f9SGreg Clayton     return error;
185cac9c5f9SGreg Clayton }
186cac9c5f9SGreg Clayton 
187cac9c5f9SGreg Clayton Error
188a0ca6601SGreg Clayton TargetList::CreateTarget (Debugger &debugger,
189a0ca6601SGreg Clayton                           const char *user_exe_path,
19070512317SGreg Clayton                           const ArchSpec& specified_arch,
19130fdc8d8SChris Lattner                           bool get_dependent_files,
192b3a40ba8SGreg Clayton                           PlatformSP &platform_sp,
193a0ca6601SGreg Clayton                           TargetSP &target_sp)
19430fdc8d8SChris Lattner {
19530fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
196a0ca6601SGreg Clayton                         "TargetList::CreateTarget (file = '%s', arch = '%s')",
197a0ca6601SGreg Clayton                         user_exe_path,
19870512317SGreg Clayton                         specified_arch.GetArchitectureName());
1995aee162fSJim Ingham     Error error;
2005aee162fSJim Ingham 
20170512317SGreg Clayton     ArchSpec arch(specified_arch);
20270512317SGreg Clayton 
20370512317SGreg Clayton     if (platform_sp)
20470512317SGreg Clayton     {
20570512317SGreg Clayton         if (arch.IsValid())
20670512317SGreg Clayton         {
2071e0c8840SGreg Clayton             if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL))
20870512317SGreg Clayton                 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
20970512317SGreg Clayton         }
21070512317SGreg Clayton     }
21170512317SGreg Clayton     else if (arch.IsValid())
21270512317SGreg Clayton     {
21370512317SGreg Clayton         platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
21470512317SGreg Clayton     }
21570512317SGreg Clayton 
21670512317SGreg Clayton     if (!platform_sp)
21770512317SGreg Clayton         platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
218ded470d3SGreg Clayton 
2198ae50eb4SGreg Clayton     if (!arch.IsValid())
2208ae50eb4SGreg Clayton         arch = specified_arch;
2218ae50eb4SGreg Clayton 
222d26206b5SJason Molenda     FileSpec file (user_exe_path, false);
223d26206b5SJason Molenda     if (!file.Exists() && user_exe_path && user_exe_path[0] == '~')
224d26206b5SJason Molenda     {
2259f822cd1SMichael Sartain         // we want to expand the tilde but we don't want to resolve any symbolic links
2269f822cd1SMichael Sartain         // so we can't use the FileSpec constructor's resolve flag
2279f822cd1SMichael Sartain         char unglobbed_path[PATH_MAX];
2289f822cd1SMichael Sartain         unglobbed_path[0] = '\0';
2299f822cd1SMichael Sartain 
2309f822cd1SMichael Sartain         size_t return_count = FileSpec::ResolveUsername(user_exe_path, unglobbed_path, sizeof(unglobbed_path));
2319f822cd1SMichael Sartain 
2329f822cd1SMichael Sartain         if (return_count == 0 || return_count >= sizeof(unglobbed_path))
2339f822cd1SMichael Sartain             ::snprintf (unglobbed_path, sizeof(unglobbed_path), "%s", user_exe_path);
2349f822cd1SMichael Sartain 
2359f822cd1SMichael Sartain         file = FileSpec(unglobbed_path, false);
236d26206b5SJason Molenda     }
2379f822cd1SMichael Sartain 
23882d79295SGreg Clayton     bool user_exe_path_is_bundle = false;
23982d79295SGreg Clayton     char resolved_bundle_exe_path[PATH_MAX];
24082d79295SGreg Clayton     resolved_bundle_exe_path[0] = '\0';
241e996fd30SGreg Clayton     if (file)
2425aee162fSJim Ingham     {
24382d79295SGreg Clayton         if (file.GetFileType() == FileSpec::eFileTypeDirectory)
24482d79295SGreg Clayton             user_exe_path_is_bundle = true;
24582d79295SGreg Clayton 
246a0ca6601SGreg Clayton         if (file.IsRelativeToCurrentWorkingDirectory())
247a0ca6601SGreg Clayton         {
248a0ca6601SGreg Clayton             // Ignore paths that start with "./" and "../"
249a0ca6601SGreg Clayton             if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
250a0ca6601SGreg Clayton                   (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/')))
251a0ca6601SGreg Clayton             {
252a0ca6601SGreg Clayton                 char cwd[PATH_MAX];
253a0ca6601SGreg Clayton                 if (getcwd (cwd, sizeof(cwd)))
254a0ca6601SGreg Clayton                 {
255a0ca6601SGreg Clayton                     std::string cwd_user_exe_path (cwd);
256a0ca6601SGreg Clayton                     cwd_user_exe_path += '/';
257a0ca6601SGreg Clayton                     cwd_user_exe_path += user_exe_path;
2589ff5aae5SGreg Clayton                     FileSpec cwd_file (cwd_user_exe_path.c_str(), false);
2599ff5aae5SGreg Clayton                     if (cwd_file.Exists())
2609ff5aae5SGreg Clayton                         file = cwd_file;
261a0ca6601SGreg Clayton                 }
262a0ca6601SGreg Clayton             }
263a0ca6601SGreg Clayton         }
264a0ca6601SGreg Clayton 
26530fdc8d8SChris Lattner         ModuleSP exe_module_sp;
266e996fd30SGreg Clayton         if (platform_sp)
267c859e2d5SGreg Clayton         {
268c859e2d5SGreg Clayton             FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
26970512317SGreg Clayton             error = platform_sp->ResolveExecutable (file,
27070512317SGreg Clayton                                                     arch,
271c859e2d5SGreg Clayton                                                     exe_module_sp,
272c859e2d5SGreg Clayton                                                     executable_search_paths.GetSize() ? &executable_search_paths : NULL);
273c859e2d5SGreg Clayton         }
274428a9a58SCaroline Tice 
275e996fd30SGreg Clayton         if (error.Success() && exe_module_sp)
27630fdc8d8SChris Lattner         {
2775aee162fSJim Ingham             if (exe_module_sp->GetObjectFile() == NULL)
2785aee162fSJim Ingham             {
279bc5cad6cSGreg Clayton                 if (arch.IsValid())
280bc5cad6cSGreg Clayton                 {
281b5ad4ec7SGreg Clayton                     error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s",
282b5ad4ec7SGreg Clayton                                                    file.GetPath().c_str(),
28364195a2cSGreg Clayton                                                    arch.GetArchitectureName());
284bc5cad6cSGreg Clayton                 }
285bc5cad6cSGreg Clayton                 else
286bc5cad6cSGreg Clayton                 {
287b5ad4ec7SGreg Clayton                     error.SetErrorStringWithFormat("unsupported file type \"%s\"",
288b5ad4ec7SGreg Clayton                                                    file.GetPath().c_str());
289bc5cad6cSGreg Clayton                 }
2905aee162fSJim Ingham                 return error;
2915aee162fSJim Ingham             }
29232e0a750SGreg Clayton             target_sp.reset(new Target(debugger, arch, platform_sp));
29330fdc8d8SChris Lattner             target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
29482d79295SGreg Clayton             if (user_exe_path_is_bundle)
29582d79295SGreg Clayton                 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
2965aee162fSJim Ingham         }
2975aee162fSJim Ingham     }
298e996fd30SGreg Clayton     else
299e996fd30SGreg Clayton     {
300e996fd30SGreg Clayton         // No file was specified, just create an empty target with any arch
301e996fd30SGreg Clayton         // if a valid arch was specified
30232e0a750SGreg Clayton         target_sp.reset(new Target(debugger, arch, platform_sp));
303e996fd30SGreg Clayton     }
3041559a46bSCaroline Tice 
305e996fd30SGreg Clayton     if (target_sp)
306e996fd30SGreg Clayton     {
30782d79295SGreg Clayton         // Set argv0 with what the user typed, unless the user specified a
30882d79295SGreg Clayton         // directory. If the user specified a directory, then it is probably a
30982d79295SGreg Clayton         // bundle that was resolved and we need to use the resolved bundle path
310a0ca6601SGreg Clayton         if (user_exe_path)
311a0ca6601SGreg Clayton         {
312a0ca6601SGreg Clayton             // Use exactly what the user typed as the first argument when we exec or posix_spawn
31382d79295SGreg Clayton             if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
31482d79295SGreg Clayton             {
31582d79295SGreg Clayton                 target_sp->SetArg0 (resolved_bundle_exe_path);
31682d79295SGreg Clayton             }
31782d79295SGreg Clayton             else
31882d79295SGreg Clayton             {
3199f822cd1SMichael Sartain                 // Use resolved path
3209f822cd1SMichael Sartain                 target_sp->SetArg0 (file.GetPath().c_str());
321a0ca6601SGreg Clayton             }
32282d79295SGreg Clayton         }
323a0ca6601SGreg Clayton         if (file.GetDirectory())
324a0ca6601SGreg Clayton         {
325a0ca6601SGreg Clayton             FileSpec file_dir;
326a0ca6601SGreg Clayton             file_dir.GetDirectory() = file.GetDirectory();
327a0ca6601SGreg Clayton             target_sp->GetExecutableSearchPaths ().Append (file_dir);
328a0ca6601SGreg Clayton         }
32930fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
3302976d00aSJim Ingham         m_selected_target_idx = m_target_list.size();
33130fdc8d8SChris Lattner         m_target_list.push_back(target_sp);
332a0ca6601SGreg Clayton 
333a0ca6601SGreg Clayton 
33430fdc8d8SChris Lattner     }
33530fdc8d8SChris Lattner 
33630fdc8d8SChris Lattner     return error;
33730fdc8d8SChris Lattner }
33830fdc8d8SChris Lattner 
33930fdc8d8SChris Lattner bool
34030fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp)
34130fdc8d8SChris Lattner {
34230fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
34330fdc8d8SChris Lattner     collection::iterator pos, end = m_target_list.end();
34430fdc8d8SChris Lattner 
34530fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
34630fdc8d8SChris Lattner     {
34730fdc8d8SChris Lattner         if (pos->get() == target_sp.get())
34830fdc8d8SChris Lattner         {
34930fdc8d8SChris Lattner             m_target_list.erase(pos);
35030fdc8d8SChris Lattner             return true;
35130fdc8d8SChris Lattner         }
35230fdc8d8SChris Lattner     }
35330fdc8d8SChris Lattner     return false;
35430fdc8d8SChris Lattner }
35530fdc8d8SChris Lattner 
35630fdc8d8SChris Lattner 
35730fdc8d8SChris Lattner TargetSP
35830fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture
35930fdc8d8SChris Lattner (
36030fdc8d8SChris Lattner     const FileSpec &exe_file_spec,
36130fdc8d8SChris Lattner     const ArchSpec *exe_arch_ptr
36230fdc8d8SChris Lattner ) const
36330fdc8d8SChris Lattner {
36430fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
36530fdc8d8SChris Lattner     TargetSP target_sp;
366*ddd7a2a6SSean Callanan     bool full_match = (bool)exe_file_spec.GetDirectory();
36730fdc8d8SChris Lattner 
36830fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
36930fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
37030fdc8d8SChris Lattner     {
371aa149cbdSGreg Clayton         Module *exe_module = (*pos)->GetExecutableModulePointer();
37230fdc8d8SChris Lattner 
373aa149cbdSGreg Clayton         if (exe_module)
37430fdc8d8SChris Lattner         {
375aa149cbdSGreg Clayton             if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
37630fdc8d8SChris Lattner             {
37730fdc8d8SChris Lattner                 if (exe_arch_ptr)
37830fdc8d8SChris Lattner                 {
379bf4b7be6SSean Callanan                     if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
38030fdc8d8SChris Lattner                         continue;
38130fdc8d8SChris Lattner                 }
38230fdc8d8SChris Lattner                 target_sp = *pos;
38330fdc8d8SChris Lattner                 break;
38430fdc8d8SChris Lattner             }
38530fdc8d8SChris Lattner         }
38630fdc8d8SChris Lattner     }
38730fdc8d8SChris Lattner     return target_sp;
38830fdc8d8SChris Lattner }
38930fdc8d8SChris Lattner 
39030fdc8d8SChris Lattner TargetSP
39130fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
39230fdc8d8SChris Lattner {
39330fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
39430fdc8d8SChris Lattner     TargetSP target_sp;
39530fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
39630fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
39730fdc8d8SChris Lattner     {
39830fdc8d8SChris Lattner         Process* process = (*pos)->GetProcessSP().get();
39930fdc8d8SChris Lattner         if (process && process->GetID() == pid)
40030fdc8d8SChris Lattner         {
40130fdc8d8SChris Lattner             target_sp = *pos;
40230fdc8d8SChris Lattner             break;
40330fdc8d8SChris Lattner         }
40430fdc8d8SChris Lattner     }
40530fdc8d8SChris Lattner     return target_sp;
40630fdc8d8SChris Lattner }
40730fdc8d8SChris Lattner 
40830fdc8d8SChris Lattner 
40930fdc8d8SChris Lattner TargetSP
41030fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const
41130fdc8d8SChris Lattner {
41230fdc8d8SChris Lattner     TargetSP target_sp;
41330fdc8d8SChris Lattner     if (process)
41430fdc8d8SChris Lattner     {
41530fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
41630fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
41730fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
41830fdc8d8SChris Lattner         {
41930fdc8d8SChris Lattner             if (process == (*pos)->GetProcessSP().get())
42030fdc8d8SChris Lattner             {
42130fdc8d8SChris Lattner                 target_sp = *pos;
42230fdc8d8SChris Lattner                 break;
42330fdc8d8SChris Lattner             }
42430fdc8d8SChris Lattner         }
42530fdc8d8SChris Lattner     }
42630fdc8d8SChris Lattner     return target_sp;
42730fdc8d8SChris Lattner }
42830fdc8d8SChris Lattner 
42930fdc8d8SChris Lattner TargetSP
43030fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const
43130fdc8d8SChris Lattner {
43230fdc8d8SChris Lattner     TargetSP target_sp;
43330fdc8d8SChris Lattner     if (target)
43430fdc8d8SChris Lattner     {
43530fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
43630fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
43730fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
43830fdc8d8SChris Lattner         {
43930fdc8d8SChris Lattner             if (target == (*pos).get())
44030fdc8d8SChris Lattner             {
44130fdc8d8SChris Lattner                 target_sp = *pos;
44230fdc8d8SChris Lattner                 break;
44330fdc8d8SChris Lattner             }
44430fdc8d8SChris Lattner         }
44530fdc8d8SChris Lattner     }
44630fdc8d8SChris Lattner     return target_sp;
44730fdc8d8SChris Lattner }
44830fdc8d8SChris Lattner 
44930fdc8d8SChris Lattner uint32_t
45030fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid)
45130fdc8d8SChris Lattner {
45230fdc8d8SChris Lattner     uint32_t num_async_interrupts_sent = 0;
45330fdc8d8SChris Lattner 
45430fdc8d8SChris Lattner     if (pid != LLDB_INVALID_PROCESS_ID)
45530fdc8d8SChris Lattner     {
45630fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
45730fdc8d8SChris Lattner         if (target_sp.get())
45830fdc8d8SChris Lattner         {
45930fdc8d8SChris Lattner             Process* process = target_sp->GetProcessSP().get();
46030fdc8d8SChris Lattner             if (process)
46130fdc8d8SChris Lattner             {
462cfc0935eSJim Ingham                 process->SendAsyncInterrupt();
46330fdc8d8SChris Lattner                 ++num_async_interrupts_sent;
46430fdc8d8SChris Lattner             }
46530fdc8d8SChris Lattner         }
46630fdc8d8SChris Lattner     }
46730fdc8d8SChris Lattner     else
46830fdc8d8SChris Lattner     {
46930fdc8d8SChris Lattner         // We don't have a valid pid to broadcast to, so broadcast to the target
47030fdc8d8SChris Lattner         // list's async broadcaster...
47130fdc8d8SChris Lattner         BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
47230fdc8d8SChris Lattner     }
47330fdc8d8SChris Lattner 
47430fdc8d8SChris Lattner     return num_async_interrupts_sent;
47530fdc8d8SChris Lattner }
47630fdc8d8SChris Lattner 
47730fdc8d8SChris Lattner uint32_t
47830fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
47930fdc8d8SChris Lattner {
48030fdc8d8SChris Lattner     uint32_t num_signals_sent = 0;
48130fdc8d8SChris Lattner     Process *process = NULL;
48230fdc8d8SChris Lattner     if (pid == LLDB_INVALID_PROCESS_ID)
48330fdc8d8SChris Lattner     {
48430fdc8d8SChris Lattner         // Signal all processes with signal
48530fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
48630fdc8d8SChris Lattner         collection::iterator pos, end = m_target_list.end();
48730fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
48830fdc8d8SChris Lattner         {
48930fdc8d8SChris Lattner             process = (*pos)->GetProcessSP().get();
49030fdc8d8SChris Lattner             if (process)
49130fdc8d8SChris Lattner             {
49230fdc8d8SChris Lattner                 if (process->IsAlive())
49330fdc8d8SChris Lattner                 {
49430fdc8d8SChris Lattner                     ++num_signals_sent;
49530fdc8d8SChris Lattner                     process->Signal (signo);
49630fdc8d8SChris Lattner                 }
49730fdc8d8SChris Lattner             }
49830fdc8d8SChris Lattner         }
49930fdc8d8SChris Lattner     }
50030fdc8d8SChris Lattner     else
50130fdc8d8SChris Lattner     {
50230fdc8d8SChris Lattner         // Signal a specific process with signal
50330fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
50430fdc8d8SChris Lattner         if (target_sp.get())
50530fdc8d8SChris Lattner         {
50630fdc8d8SChris Lattner             process = target_sp->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     return num_signals_sent;
51830fdc8d8SChris Lattner }
51930fdc8d8SChris Lattner 
52030fdc8d8SChris Lattner int
52130fdc8d8SChris Lattner TargetList::GetNumTargets () const
52230fdc8d8SChris Lattner {
52330fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
52430fdc8d8SChris Lattner     return m_target_list.size();
52530fdc8d8SChris Lattner }
52630fdc8d8SChris Lattner 
52730fdc8d8SChris Lattner lldb::TargetSP
52830fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const
52930fdc8d8SChris Lattner {
53030fdc8d8SChris Lattner     TargetSP target_sp;
53130fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
53230fdc8d8SChris Lattner     if (idx < m_target_list.size())
53330fdc8d8SChris Lattner         target_sp = m_target_list[idx];
53430fdc8d8SChris Lattner     return target_sp;
53530fdc8d8SChris Lattner }
53630fdc8d8SChris Lattner 
53730fdc8d8SChris Lattner uint32_t
5388499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
5398499e1a4SJim Ingham {
5408499e1a4SJim Ingham     Mutex::Locker locker (m_target_list_mutex);
5418499e1a4SJim Ingham     size_t num_targets = m_target_list.size();
5428499e1a4SJim Ingham     for (size_t idx = 0; idx < num_targets; idx++)
5438499e1a4SJim Ingham     {
5448499e1a4SJim Ingham         if (target_sp == m_target_list[idx])
5458499e1a4SJim Ingham             return idx;
5468499e1a4SJim Ingham     }
5478499e1a4SJim Ingham     return UINT32_MAX;
5488499e1a4SJim Ingham }
5498499e1a4SJim Ingham 
5508499e1a4SJim Ingham uint32_t
5512976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target)
55230fdc8d8SChris Lattner {
55330fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
55430fdc8d8SChris Lattner     collection::const_iterator pos,
55530fdc8d8SChris Lattner         begin = m_target_list.begin(),
55630fdc8d8SChris Lattner         end = m_target_list.end();
55730fdc8d8SChris Lattner     for (pos = begin; pos != end; ++pos)
55830fdc8d8SChris Lattner     {
55930fdc8d8SChris Lattner         if (pos->get() == target)
56030fdc8d8SChris Lattner         {
5612976d00aSJim Ingham             m_selected_target_idx = std::distance (begin, pos);
5622976d00aSJim Ingham             return m_selected_target_idx;
56330fdc8d8SChris Lattner         }
56430fdc8d8SChris Lattner     }
5652976d00aSJim Ingham     m_selected_target_idx = 0;
5662976d00aSJim Ingham     return m_selected_target_idx;
56730fdc8d8SChris Lattner }
56830fdc8d8SChris Lattner 
56930fdc8d8SChris Lattner lldb::TargetSP
5702976d00aSJim Ingham TargetList::GetSelectedTarget ()
57130fdc8d8SChris Lattner {
57230fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
5732976d00aSJim Ingham     if (m_selected_target_idx >= m_target_list.size())
5742976d00aSJim Ingham         m_selected_target_idx = 0;
5752976d00aSJim Ingham     return GetTargetAtIndex (m_selected_target_idx);
57630fdc8d8SChris Lattner }
577