blob: d1775213d605657d02b7711b5c3af6ea902ad527 [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
Zachary Turner3f559742014-08-07 17:33:36 +000031#include "llvm/ADT/SmallString.h"
32
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033using namespace lldb;
34using namespace lldb_private;
35
Jim Ingham4bddaeb2012-02-16 06:50:00 +000036ConstString &
37TargetList::GetStaticBroadcasterClass ()
38{
39 static ConstString class_name ("lldb.targetList");
40 return class_name;
41}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042
43//----------------------------------------------------------------------
44// TargetList constructor
45//----------------------------------------------------------------------
Jim Ingham4bddaeb2012-02-16 06:50:00 +000046TargetList::TargetList(Debugger &debugger) :
Jim Ingham4f465cf2012-10-10 18:32:14 +000047 Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048 m_target_list(),
49 m_target_list_mutex (Mutex::eMutexTypeRecursive),
Jim Ingham2976d002010-08-26 21:32:51 +000050 m_selected_target_idx (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051{
Jim Ingham4bddaeb2012-02-16 06:50:00 +000052 CheckInWithManager();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053}
54
55//----------------------------------------------------------------------
56// Destructor
57//----------------------------------------------------------------------
58TargetList::~TargetList()
59{
60 Mutex::Locker locker(m_target_list_mutex);
61 m_target_list.clear();
62}
63
64Error
Greg Claytoncac9c5f2011-09-24 00:52:29 +000065TargetList::CreateTarget (Debugger &debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +000066 const char *user_exe_path,
Greg Claytoncac9c5f2011-09-24 00:52:29 +000067 const char *triple_cstr,
68 bool get_dependent_files,
69 const OptionGroupPlatform *platform_options,
70 TargetSP &target_sp)
71{
72 Error error;
73 PlatformSP platform_sp;
Greg Claytoncac9c5f2011-09-24 00:52:29 +000074
Johnny Chencdc21d42012-01-05 01:26:01 +000075 // This is purposely left empty unless it is specified by triple_cstr.
76 // If not initialized via triple_cstr, then the currently selected platform
77 // will set the architecture correctly.
Greg Clayton70512312012-05-08 01:45:38 +000078 const ArchSpec arch(triple_cstr);
79 if (triple_cstr && triple_cstr[0])
Greg Claytoncac9c5f2011-09-24 00:52:29 +000080 {
Greg Claytoncac9c5f2011-09-24 00:52:29 +000081 if (!arch.IsValid())
82 {
Greg Clayton86edbf42011-10-26 00:56:27 +000083 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
Greg Claytoncac9c5f2011-09-24 00:52:29 +000084 return error;
85 }
86 }
Greg Claytonf4d6de62013-04-24 22:29:28 +000087
Greg Clayton70512312012-05-08 01:45:38 +000088 ArchSpec platform_arch(arch);
Greg Claytonf4d6de62013-04-24 22:29:28 +000089
Greg Clayton3f19ada2014-07-10 23:33:37 +000090 bool prefer_platform_arch = false;
Greg Claytonf4d6de62013-04-24 22:29:28 +000091
92 if (user_exe_path && user_exe_path[0])
93 {
94 ModuleSpecList module_specs;
95 ModuleSpec module_spec;
96 module_spec.GetFileSpec().SetFile(user_exe_path, true);
Greg Claytonc76fa8a2014-07-29 21:27:21 +000097
98 // Resolve the executable in case we are given a path to a application bundle
99 // like a .app bundle on MacOSX
100 Host::ResolveExecutableInBundle (module_spec.GetFileSpec());
101
Greg Claytonf4d6de62013-04-24 22:29:28 +0000102 lldb::offset_t file_offset = 0;
Greg Clayton2540a8a2013-07-12 22:07:46 +0000103 lldb::offset_t file_size = 0;
104 const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs);
Greg Claytonf4d6de62013-04-24 22:29:28 +0000105 if (num_specs > 0)
106 {
107 ModuleSpec matching_module_spec;
108
109 if (num_specs == 1)
110 {
111 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
112 {
113 if (platform_arch.IsValid())
114 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000115 if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture()))
116 {
117 // If the OS or vendor weren't specified, then adopt the module's
118 // architecture so that the platform matching can be more accurate
119 if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified())
120 {
121 prefer_platform_arch = true;
122 platform_arch = matching_module_spec.GetArchitecture();
123 }
124 }
125 else
Greg Claytonf4d6de62013-04-24 22:29:28 +0000126 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000127 error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'",
Greg Claytonf4d6de62013-04-24 22:29:28 +0000128 platform_arch.GetTriple().str().c_str(),
129 matching_module_spec.GetArchitecture().GetTriple().str().c_str(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000130 module_spec.GetFileSpec().GetPath().c_str());
Greg Claytonf4d6de62013-04-24 22:29:28 +0000131 return error;
132 }
133 }
134 else
135 {
136 // Only one arch and none was specified
Greg Clayton3f19ada2014-07-10 23:33:37 +0000137 prefer_platform_arch = true;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000138 platform_arch = matching_module_spec.GetArchitecture();
139 }
140 }
141 }
142 else
143 {
144 if (arch.IsValid())
145 {
146 module_spec.GetArchitecture() = arch;
147 if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec))
148 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000149 prefer_platform_arch = true;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000150 platform_arch = matching_module_spec.GetArchitecture();
151 }
152 }
Greg Claytonf4d6de62013-04-24 22:29:28 +0000153 }
154 }
155 }
156
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000157 CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
158 if (platform_options)
159 {
160 if (platform_options->PlatformWasSpecified ())
161 {
162 const bool select_platform = true;
163 platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
164 arch,
165 select_platform,
Greg Clayton70512312012-05-08 01:45:38 +0000166 error,
167 platform_arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000168 if (!platform_sp)
169 return error;
170 }
171 }
172
173 if (!platform_sp)
174 {
175 // Get the current platform and make sure it is compatible with the
176 // current architecture if we have a valid architecture.
177 platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
178
Greg Clayton3f19ada2014-07-10 23:33:37 +0000179 if (!prefer_platform_arch && arch.IsValid())
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000180 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000181 if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
182 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
183 }
184 else if (platform_arch.IsValid())
185 {
186 // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with
187 // a single architecture which should be used
188 ArchSpec fixed_platform_arch;
189 if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch))
190 platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000191 }
192 }
Greg Clayton70512312012-05-08 01:45:38 +0000193
194 if (!platform_arch.IsValid())
195 platform_arch = arch;
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000196
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000197 error = TargetList::CreateTarget (debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +0000198 user_exe_path,
Greg Clayton70512312012-05-08 01:45:38 +0000199 platform_arch,
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000200 get_dependent_files,
201 platform_sp,
202 target_sp);
203 return error;
204}
205
206Error
Greg Claytona0ca6602012-10-18 16:33:33 +0000207TargetList::CreateTarget (Debugger &debugger,
208 const char *user_exe_path,
209 const ArchSpec& specified_arch,
210 bool get_dependent_files,
211 PlatformSP &platform_sp,
212 TargetSP &target_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213{
214 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytona0ca6602012-10-18 16:33:33 +0000215 "TargetList::CreateTarget (file = '%s', arch = '%s')",
216 user_exe_path,
Greg Clayton70512312012-05-08 01:45:38 +0000217 specified_arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000218 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000219
Greg Clayton70512312012-05-08 01:45:38 +0000220 ArchSpec arch(specified_arch);
221
222 if (platform_sp)
223 {
224 if (arch.IsValid())
225 {
Greg Clayton1e0c8842013-01-11 20:49:54 +0000226 if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL))
Greg Clayton70512312012-05-08 01:45:38 +0000227 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
228 }
229 }
230 else if (arch.IsValid())
231 {
232 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
233 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000234
Greg Clayton70512312012-05-08 01:45:38 +0000235 if (!platform_sp)
236 platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
237
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000238 if (!arch.IsValid())
239 arch = specified_arch;
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000240
Jason Molendad26206b52013-04-19 22:38:50 +0000241 FileSpec file (user_exe_path, false);
242 if (!file.Exists() && user_exe_path && user_exe_path[0] == '~')
243 {
Michael Sartain9f822cd2013-07-31 23:27:46 +0000244 // we want to expand the tilde but we don't want to resolve any symbolic links
245 // so we can't use the FileSpec constructor's resolve flag
Zachary Turner3f559742014-08-07 17:33:36 +0000246 llvm::SmallString<64> unglobbed_path(user_exe_path);
247 FileSpec::ResolveUsername(unglobbed_path);
Michael Sartain9f822cd2013-07-31 23:27:46 +0000248
Zachary Turner3f559742014-08-07 17:33:36 +0000249 if (unglobbed_path.empty())
250 file = FileSpec(user_exe_path, false);
251 else
252 file = FileSpec(unglobbed_path.c_str(), 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}