blob: 091211d9cb8abaad8588a3d4ab6c78d70693fbe5 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- TargetList.cpp ------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Broadcaster.h"
Greg Claytonded470d2011-03-19 01:12:21 +000017#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/Event.h"
Greg Clayton1f746072012-08-29 21:13:06 +000019#include "lldb/Core/Module.h"
Greg Claytonf4d6de62013-04-24 22:29:28 +000020#include "lldb/Core/ModuleSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Core/State.h"
22#include "lldb/Core/Timer.h"
23#include "lldb/Host/Host.h"
Greg Claytonb3a40ba2012-03-20 18:34:04 +000024#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytoncac9c5f2011-09-24 00:52:29 +000025#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytonf4d6de62013-04-24 22:29:28 +000026#include "lldb/Symbol/ObjectFile.h"
Greg Claytone996fd32011-03-08 22:40:15 +000027#include "lldb/Target/Platform.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Target/Process.h"
29#include "lldb/Target/TargetList.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
Jim Ingham4bddaeb2012-02-16 06:50:00 +000034ConstString &
35TargetList::GetStaticBroadcasterClass ()
36{
37 static ConstString class_name ("lldb.targetList");
38 return class_name;
39}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040
41//----------------------------------------------------------------------
42// TargetList constructor
43//----------------------------------------------------------------------
Jim Ingham4bddaeb2012-02-16 06:50:00 +000044TargetList::TargetList(Debugger &debugger) :
Jim Ingham4f465cf2012-10-10 18:32:14 +000045 Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046 m_target_list(),
47 m_target_list_mutex (Mutex::eMutexTypeRecursive),
Jim Ingham2976d002010-08-26 21:32:51 +000048 m_selected_target_idx (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049{
Jim Ingham4bddaeb2012-02-16 06:50:00 +000050 CheckInWithManager();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051}
52
53//----------------------------------------------------------------------
54// Destructor
55//----------------------------------------------------------------------
56TargetList::~TargetList()
57{
58 Mutex::Locker locker(m_target_list_mutex);
59 m_target_list.clear();
60}
61
62Error
Greg Claytoncac9c5f2011-09-24 00:52:29 +000063TargetList::CreateTarget (Debugger &debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +000064 const char *user_exe_path,
Greg Claytoncac9c5f2011-09-24 00:52:29 +000065 const char *triple_cstr,
66 bool get_dependent_files,
67 const OptionGroupPlatform *platform_options,
68 TargetSP &target_sp)
69{
70 Error error;
71 PlatformSP platform_sp;
Greg Claytoncac9c5f2011-09-24 00:52:29 +000072
Johnny Chencdc21d42012-01-05 01:26:01 +000073 // This is purposely left empty unless it is specified by triple_cstr.
74 // If not initialized via triple_cstr, then the currently selected platform
75 // will set the architecture correctly.
Greg Clayton70512312012-05-08 01:45:38 +000076 const ArchSpec arch(triple_cstr);
77 if (triple_cstr && triple_cstr[0])
Greg Claytoncac9c5f2011-09-24 00:52:29 +000078 {
Greg Claytoncac9c5f2011-09-24 00:52:29 +000079 if (!arch.IsValid())
80 {
Greg Clayton86edbf42011-10-26 00:56:27 +000081 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
Greg Claytoncac9c5f2011-09-24 00:52:29 +000082 return error;
83 }
84 }
Greg Claytonf4d6de62013-04-24 22:29:28 +000085
Greg Clayton70512312012-05-08 01:45:38 +000086 ArchSpec platform_arch(arch);
Greg Claytonf4d6de62013-04-24 22:29:28 +000087
Greg Clayton3f19ada2014-07-10 23:33:37 +000088 bool prefer_platform_arch = false;
Greg Claytonf4d6de62013-04-24 22:29:28 +000089
90 if (user_exe_path && user_exe_path[0])
91 {
92 ModuleSpecList module_specs;
93 ModuleSpec module_spec;
94 module_spec.GetFileSpec().SetFile(user_exe_path, true);
Greg Claytonc76fa8a2014-07-29 21:27:21 +000095
96 // Resolve the executable in case we are given a path to a application bundle
97 // like a .app bundle on MacOSX
98 Host::ResolveExecutableInBundle (module_spec.GetFileSpec());
99
Greg Claytonf4d6de62013-04-24 22:29:28 +0000100 lldb::offset_t file_offset = 0;
Greg Clayton2540a8a2013-07-12 22:07:46 +0000101 lldb::offset_t file_size = 0;
102 const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs);
Greg Claytonf4d6de62013-04-24 22:29:28 +0000103 if (num_specs > 0)
104 {
105 ModuleSpec matching_module_spec;
106
107 if (num_specs == 1)
108 {
109 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
110 {
111 if (platform_arch.IsValid())
112 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000113 if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture()))
114 {
115 // If the OS or vendor weren't specified, then adopt the module's
116 // architecture so that the platform matching can be more accurate
117 if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified())
118 {
119 prefer_platform_arch = true;
120 platform_arch = matching_module_spec.GetArchitecture();
121 }
122 }
123 else
Greg Claytonf4d6de62013-04-24 22:29:28 +0000124 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000125 error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'",
Greg Claytonf4d6de62013-04-24 22:29:28 +0000126 platform_arch.GetTriple().str().c_str(),
127 matching_module_spec.GetArchitecture().GetTriple().str().c_str(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000128 module_spec.GetFileSpec().GetPath().c_str());
Greg Claytonf4d6de62013-04-24 22:29:28 +0000129 return error;
130 }
131 }
132 else
133 {
134 // Only one arch and none was specified
Greg Clayton3f19ada2014-07-10 23:33:37 +0000135 prefer_platform_arch = true;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000136 platform_arch = matching_module_spec.GetArchitecture();
137 }
138 }
139 }
140 else
141 {
142 if (arch.IsValid())
143 {
144 module_spec.GetArchitecture() = arch;
145 if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec))
146 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000147 prefer_platform_arch = true;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000148 platform_arch = matching_module_spec.GetArchitecture();
149 }
150 }
Greg Claytonf4d6de62013-04-24 22:29:28 +0000151 }
152 }
153 }
154
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000155 CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
156 if (platform_options)
157 {
158 if (platform_options->PlatformWasSpecified ())
159 {
160 const bool select_platform = true;
161 platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
162 arch,
163 select_platform,
Greg Clayton70512312012-05-08 01:45:38 +0000164 error,
165 platform_arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000166 if (!platform_sp)
167 return error;
168 }
169 }
170
171 if (!platform_sp)
172 {
173 // Get the current platform and make sure it is compatible with the
174 // current architecture if we have a valid architecture.
175 platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
176
Greg Clayton3f19ada2014-07-10 23:33:37 +0000177 if (!prefer_platform_arch && arch.IsValid())
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000178 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000179 if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
180 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
181 }
182 else if (platform_arch.IsValid())
183 {
184 // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with
185 // a single architecture which should be used
186 ArchSpec fixed_platform_arch;
187 if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch))
188 platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000189 }
190 }
Greg Clayton70512312012-05-08 01:45:38 +0000191
192 if (!platform_arch.IsValid())
193 platform_arch = arch;
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000194
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000195 error = TargetList::CreateTarget (debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +0000196 user_exe_path,
Greg Clayton70512312012-05-08 01:45:38 +0000197 platform_arch,
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000198 get_dependent_files,
199 platform_sp,
200 target_sp);
201 return error;
202}
203
204Error
Greg Claytona0ca6602012-10-18 16:33:33 +0000205TargetList::CreateTarget (Debugger &debugger,
206 const char *user_exe_path,
207 const ArchSpec& specified_arch,
208 bool get_dependent_files,
209 PlatformSP &platform_sp,
210 TargetSP &target_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211{
212 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytona0ca6602012-10-18 16:33:33 +0000213 "TargetList::CreateTarget (file = '%s', arch = '%s')",
214 user_exe_path,
Greg Clayton70512312012-05-08 01:45:38 +0000215 specified_arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000216 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000217
Greg Clayton70512312012-05-08 01:45:38 +0000218 ArchSpec arch(specified_arch);
219
220 if (platform_sp)
221 {
222 if (arch.IsValid())
223 {
Greg Clayton1e0c8842013-01-11 20:49:54 +0000224 if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL))
Greg Clayton70512312012-05-08 01:45:38 +0000225 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
226 }
227 }
228 else if (arch.IsValid())
229 {
230 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
231 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000232
Greg Clayton70512312012-05-08 01:45:38 +0000233 if (!platform_sp)
234 platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
235
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000236 if (!arch.IsValid())
237 arch = specified_arch;
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000238
Jason Molendad26206b52013-04-19 22:38:50 +0000239 FileSpec file (user_exe_path, false);
240 if (!file.Exists() && user_exe_path && user_exe_path[0] == '~')
241 {
Michael Sartain9f822cd2013-07-31 23:27:46 +0000242 // we want to expand the tilde but we don't want to resolve any symbolic links
243 // so we can't use the FileSpec constructor's resolve flag
244 char unglobbed_path[PATH_MAX];
245 unglobbed_path[0] = '\0';
246
247 size_t return_count = FileSpec::ResolveUsername(user_exe_path, unglobbed_path, sizeof(unglobbed_path));
248
249 if (return_count == 0 || return_count >= sizeof(unglobbed_path))
250 ::snprintf (unglobbed_path, sizeof(unglobbed_path), "%s", user_exe_path);
251
252 file = FileSpec(unglobbed_path, false);
Jason Molendad26206b52013-04-19 22:38:50 +0000253 }
Michael Sartain9f822cd2013-07-31 23:27:46 +0000254
Greg Clayton82d79292012-10-25 22:45:35 +0000255 bool user_exe_path_is_bundle = false;
256 char resolved_bundle_exe_path[PATH_MAX];
257 resolved_bundle_exe_path[0] = '\0';
Greg Claytone996fd32011-03-08 22:40:15 +0000258 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000259 {
Greg Clayton82d79292012-10-25 22:45:35 +0000260 if (file.GetFileType() == FileSpec::eFileTypeDirectory)
261 user_exe_path_is_bundle = true;
262
Greg Claytona0ca6602012-10-18 16:33:33 +0000263 if (file.IsRelativeToCurrentWorkingDirectory())
264 {
265 // Ignore paths that start with "./" and "../"
266 if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
267 (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/')))
268 {
269 char cwd[PATH_MAX];
270 if (getcwd (cwd, sizeof(cwd)))
271 {
272 std::string cwd_user_exe_path (cwd);
273 cwd_user_exe_path += '/';
274 cwd_user_exe_path += user_exe_path;
Greg Clayton9ff5aae2013-04-04 00:15:09 +0000275 FileSpec cwd_file (cwd_user_exe_path.c_str(), false);
276 if (cwd_file.Exists())
277 file = cwd_file;
Greg Claytona0ca6602012-10-18 16:33:33 +0000278 }
279 }
280 }
281
Jim Ingham5aee1622010-08-09 23:31:02 +0000282 ModuleSP exe_module_sp;
Greg Claytone996fd32011-03-08 22:40:15 +0000283 if (platform_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000284 {
285 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
Greg Clayton70512312012-05-08 01:45:38 +0000286 error = platform_sp->ResolveExecutable (file,
287 arch,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000288 exe_module_sp,
289 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
290 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000291
Greg Claytone996fd32011-03-08 22:40:15 +0000292 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000293 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000294 if (exe_module_sp->GetObjectFile() == NULL)
295 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000296 if (arch.IsValid())
297 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000298 error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s",
299 file.GetPath().c_str(),
Greg Clayton64195a22011-02-23 00:35:02 +0000300 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000301 }
302 else
303 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000304 error.SetErrorStringWithFormat("unsupported file type \"%s\"",
305 file.GetPath().c_str());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000306 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000307 return error;
308 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000309 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +0000310 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Greg Clayton82d79292012-10-25 22:45:35 +0000311 if (user_exe_path_is_bundle)
312 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000313 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000314 }
Greg Claytone996fd32011-03-08 22:40:15 +0000315 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000316 {
Greg Claytone996fd32011-03-08 22:40:15 +0000317 // No file was specified, just create an empty target with any arch
318 // if a valid arch was specified
Greg Clayton32e0a752011-03-30 18:16:51 +0000319 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000320 }
321
322 if (target_sp)
323 {
Greg Clayton82d79292012-10-25 22:45:35 +0000324 // Set argv0 with what the user typed, unless the user specified a
325 // directory. If the user specified a directory, then it is probably a
326 // bundle that was resolved and we need to use the resolved bundle path
Greg Claytona0ca6602012-10-18 16:33:33 +0000327 if (user_exe_path)
328 {
329 // Use exactly what the user typed as the first argument when we exec or posix_spawn
Greg Clayton82d79292012-10-25 22:45:35 +0000330 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
331 {
332 target_sp->SetArg0 (resolved_bundle_exe_path);
333 }
334 else
335 {
Michael Sartain9f822cd2013-07-31 23:27:46 +0000336 // Use resolved path
337 target_sp->SetArg0 (file.GetPath().c_str());
Greg Clayton82d79292012-10-25 22:45:35 +0000338 }
Greg Claytona0ca6602012-10-18 16:33:33 +0000339 }
340 if (file.GetDirectory())
341 {
342 FileSpec file_dir;
343 file_dir.GetDirectory() = file.GetDirectory();
344 target_sp->GetExecutableSearchPaths ().Append (file_dir);
345 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000346 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000347 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000348 m_target_list.push_back(target_sp);
Greg Claytona0ca6602012-10-18 16:33:33 +0000349
350
Jim Ingham5aee1622010-08-09 23:31:02 +0000351 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353 return error;
354}
355
356bool
357TargetList::DeleteTarget (TargetSP &target_sp)
358{
359 Mutex::Locker locker(m_target_list_mutex);
360 collection::iterator pos, end = m_target_list.end();
361
362 for (pos = m_target_list.begin(); pos != end; ++pos)
363 {
364 if (pos->get() == target_sp.get())
365 {
366 m_target_list.erase(pos);
367 return true;
368 }
369 }
370 return false;
371}
372
373
374TargetSP
375TargetList::FindTargetWithExecutableAndArchitecture
376(
377 const FileSpec &exe_file_spec,
378 const ArchSpec *exe_arch_ptr
379) const
380{
381 Mutex::Locker locker (m_target_list_mutex);
382 TargetSP target_sp;
Sean Callananddd7a2a2013-10-03 22:27:29 +0000383 bool full_match = (bool)exe_file_spec.GetDirectory();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384
385 collection::const_iterator pos, end = m_target_list.end();
386 for (pos = m_target_list.begin(); pos != end; ++pos)
387 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000388 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389
Greg Claytonaa149cb2011-08-11 02:48:45 +0000390 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000392 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000393 {
394 if (exe_arch_ptr)
395 {
Sean Callananbf4b7be2012-12-13 22:07:14 +0000396 if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397 continue;
398 }
399 target_sp = *pos;
400 break;
401 }
402 }
403 }
404 return target_sp;
405}
406
407TargetSP
408TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
409{
410 Mutex::Locker locker(m_target_list_mutex);
411 TargetSP target_sp;
412 collection::const_iterator pos, end = m_target_list.end();
413 for (pos = m_target_list.begin(); pos != end; ++pos)
414 {
415 Process* process = (*pos)->GetProcessSP().get();
416 if (process && process->GetID() == pid)
417 {
418 target_sp = *pos;
419 break;
420 }
421 }
422 return target_sp;
423}
424
425
426TargetSP
427TargetList::FindTargetWithProcess (Process *process) const
428{
429 TargetSP target_sp;
430 if (process)
431 {
432 Mutex::Locker locker(m_target_list_mutex);
433 collection::const_iterator pos, end = m_target_list.end();
434 for (pos = m_target_list.begin(); pos != end; ++pos)
435 {
436 if (process == (*pos)->GetProcessSP().get())
437 {
438 target_sp = *pos;
439 break;
440 }
441 }
442 }
443 return target_sp;
444}
445
446TargetSP
447TargetList::GetTargetSP (Target *target) const
448{
449 TargetSP target_sp;
450 if (target)
451 {
452 Mutex::Locker locker(m_target_list_mutex);
453 collection::const_iterator pos, end = m_target_list.end();
454 for (pos = m_target_list.begin(); pos != end; ++pos)
455 {
456 if (target == (*pos).get())
457 {
458 target_sp = *pos;
459 break;
460 }
461 }
462 }
463 return target_sp;
464}
465
466uint32_t
467TargetList::SendAsyncInterrupt (lldb::pid_t pid)
468{
469 uint32_t num_async_interrupts_sent = 0;
470
471 if (pid != LLDB_INVALID_PROCESS_ID)
472 {
473 TargetSP target_sp(FindTargetWithProcessID (pid));
474 if (target_sp.get())
475 {
476 Process* process = target_sp->GetProcessSP().get();
477 if (process)
478 {
Jim Inghamcfc09352012-07-27 23:57:19 +0000479 process->SendAsyncInterrupt();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480 ++num_async_interrupts_sent;
481 }
482 }
483 }
484 else
485 {
486 // We don't have a valid pid to broadcast to, so broadcast to the target
487 // list's async broadcaster...
488 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
489 }
490
491 return num_async_interrupts_sent;
492}
493
494uint32_t
495TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
496{
497 uint32_t num_signals_sent = 0;
498 Process *process = NULL;
499 if (pid == LLDB_INVALID_PROCESS_ID)
500 {
501 // Signal all processes with signal
502 Mutex::Locker locker(m_target_list_mutex);
503 collection::iterator pos, end = m_target_list.end();
504 for (pos = m_target_list.begin(); pos != end; ++pos)
505 {
506 process = (*pos)->GetProcessSP().get();
507 if (process)
508 {
509 if (process->IsAlive())
510 {
511 ++num_signals_sent;
512 process->Signal (signo);
513 }
514 }
515 }
516 }
517 else
518 {
519 // Signal a specific process with signal
520 TargetSP target_sp(FindTargetWithProcessID (pid));
521 if (target_sp.get())
522 {
523 process = target_sp->GetProcessSP().get();
524 if (process)
525 {
526 if (process->IsAlive())
527 {
528 ++num_signals_sent;
529 process->Signal (signo);
530 }
531 }
532 }
533 }
534 return num_signals_sent;
535}
536
537int
538TargetList::GetNumTargets () const
539{
540 Mutex::Locker locker (m_target_list_mutex);
541 return m_target_list.size();
542}
543
544lldb::TargetSP
545TargetList::GetTargetAtIndex (uint32_t idx) const
546{
547 TargetSP target_sp;
548 Mutex::Locker locker (m_target_list_mutex);
549 if (idx < m_target_list.size())
550 target_sp = m_target_list[idx];
551 return target_sp;
552}
553
554uint32_t
Jim Ingham8499e1a2012-05-08 23:06:07 +0000555TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
556{
557 Mutex::Locker locker (m_target_list_mutex);
558 size_t num_targets = m_target_list.size();
559 for (size_t idx = 0; idx < num_targets; idx++)
560 {
561 if (target_sp == m_target_list[idx])
562 return idx;
563 }
564 return UINT32_MAX;
565}
566
567uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000568TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000569{
570 Mutex::Locker locker (m_target_list_mutex);
571 collection::const_iterator pos,
572 begin = m_target_list.begin(),
573 end = m_target_list.end();
574 for (pos = begin; pos != end; ++pos)
575 {
576 if (pos->get() == target)
577 {
Jim Ingham2976d002010-08-26 21:32:51 +0000578 m_selected_target_idx = std::distance (begin, pos);
579 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580 }
581 }
Jim Ingham2976d002010-08-26 21:32:51 +0000582 m_selected_target_idx = 0;
583 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584}
585
586lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000587TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000588{
589 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000590 if (m_selected_target_idx >= m_target_list.size())
591 m_selected_target_idx = 0;
592 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000593}