blob: 5ee75ff744493f77b6fa0299079d327c62e3f656 [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
Greg Claytonb0cc53c2014-08-20 18:13:03 +000092 CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
93 if (platform_options && platform_options->PlatformWasSpecified ())
94 {
95 const bool select_platform = true;
96 platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
97 arch,
98 select_platform,
99 error,
100 platform_arch);
101 if (!platform_sp)
102 return error;
103 }
104
Greg Claytonf4d6de62013-04-24 22:29:28 +0000105 if (user_exe_path && user_exe_path[0])
106 {
107 ModuleSpecList module_specs;
108 ModuleSpec module_spec;
109 module_spec.GetFileSpec().SetFile(user_exe_path, true);
Greg Claytonc76fa8a2014-07-29 21:27:21 +0000110
111 // Resolve the executable in case we are given a path to a application bundle
112 // like a .app bundle on MacOSX
113 Host::ResolveExecutableInBundle (module_spec.GetFileSpec());
114
Greg Claytonf4d6de62013-04-24 22:29:28 +0000115 lldb::offset_t file_offset = 0;
Greg Clayton2540a8a2013-07-12 22:07:46 +0000116 lldb::offset_t file_size = 0;
117 const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs);
Greg Claytonf4d6de62013-04-24 22:29:28 +0000118 if (num_specs > 0)
119 {
120 ModuleSpec matching_module_spec;
121
122 if (num_specs == 1)
123 {
124 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
125 {
126 if (platform_arch.IsValid())
127 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000128 if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture()))
129 {
130 // If the OS or vendor weren't specified, then adopt the module's
131 // architecture so that the platform matching can be more accurate
132 if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified())
133 {
134 prefer_platform_arch = true;
135 platform_arch = matching_module_spec.GetArchitecture();
136 }
137 }
138 else
Greg Claytonf4d6de62013-04-24 22:29:28 +0000139 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000140 error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'",
Greg Claytonf4d6de62013-04-24 22:29:28 +0000141 platform_arch.GetTriple().str().c_str(),
142 matching_module_spec.GetArchitecture().GetTriple().str().c_str(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000143 module_spec.GetFileSpec().GetPath().c_str());
Greg Claytonf4d6de62013-04-24 22:29:28 +0000144 return error;
145 }
146 }
147 else
148 {
149 // Only one arch and none was specified
Greg Clayton3f19ada2014-07-10 23:33:37 +0000150 prefer_platform_arch = true;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000151 platform_arch = matching_module_spec.GetArchitecture();
152 }
153 }
154 }
155 else
156 {
157 if (arch.IsValid())
158 {
159 module_spec.GetArchitecture() = arch;
160 if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec))
161 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000162 prefer_platform_arch = true;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000163 platform_arch = matching_module_spec.GetArchitecture();
164 }
165 }
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000166 else
167 {
168 // No architecture specified, check if there is only one platform for
169 // all of the architectures.
170
171 typedef std::vector<PlatformSP> PlatformList;
172 PlatformList platforms;
173 PlatformSP host_platform_sp = Platform::GetDefaultPlatform();
174 for (size_t i=0; i<num_specs; ++i)
175 {
176 ModuleSpec module_spec;
177 if (module_specs.GetModuleSpecAtIndex(i, module_spec))
178 {
179 // See if there was a selected platform and check that first
180 // since the user may have specified it.
181 if (platform_sp)
182 {
183 if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL))
184 {
185 platforms.push_back(platform_sp);
186 continue;
187 }
188 }
189
190 // Next check the host platform it if wasn't already checked above
191 if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName()))
192 {
193 if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL))
194 {
195 platforms.push_back(host_platform_sp);
196 continue;
197 }
198 }
199
200 // Just find a platform that matches the architecture in the executable file
201 platforms.push_back(Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr));
202 }
203 }
204
205 Platform *platform_ptr = NULL;
206 for (const auto &the_platform_sp : platforms)
207 {
208 if (platform_ptr)
209 {
210 if (platform_ptr->GetName() != the_platform_sp->GetName())
211 {
212 platform_ptr = NULL;
213 break;
214 }
215 }
216 else
217 {
218 platform_ptr = the_platform_sp.get();
219 }
220 }
221
222 if (platform_ptr)
223 {
224 // All platforms for all modules in the exectuable match, so we can select this platform
225 platform_sp = platforms.front();
226 }
227 else
228 {
229 // More than one platform claims to support this file, so the --platform option must be specified
230 StreamString error_strm;
231 std::set<Platform *> platform_set;
232 error_strm.Printf ("more than one platform supports this executable (");
233 for (const auto &the_platform_sp : platforms)
234 {
235 if (platform_set.find(the_platform_sp.get()) == platform_set.end())
236 {
237 if (!platform_set.empty())
238 error_strm.PutCString(", ");
239 error_strm.PutCString(the_platform_sp->GetName().GetCString());
240 platform_set.insert(the_platform_sp.get());
241 }
242 }
243 error_strm.Printf("), use the --platform option to specify a platform");
244 error.SetErrorString(error_strm.GetString().c_str());
245 return error;
246 }
247 }
Greg Claytonf4d6de62013-04-24 22:29:28 +0000248 }
249 }
250 }
251
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000252 if (!platform_sp)
253 {
254 // Get the current platform and make sure it is compatible with the
255 // current architecture if we have a valid architecture.
256 platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
257
Greg Clayton3f19ada2014-07-10 23:33:37 +0000258 if (!prefer_platform_arch && arch.IsValid())
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000259 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000260 if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
261 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
262 }
263 else if (platform_arch.IsValid())
264 {
265 // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with
266 // a single architecture which should be used
267 ArchSpec fixed_platform_arch;
268 if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch))
269 platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000270 }
271 }
Greg Clayton70512312012-05-08 01:45:38 +0000272
273 if (!platform_arch.IsValid())
274 platform_arch = arch;
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000275
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000276 error = TargetList::CreateTarget (debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +0000277 user_exe_path,
Greg Clayton70512312012-05-08 01:45:38 +0000278 platform_arch,
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000279 get_dependent_files,
280 platform_sp,
281 target_sp);
282 return error;
283}
284
285Error
Greg Claytona0ca6602012-10-18 16:33:33 +0000286TargetList::CreateTarget (Debugger &debugger,
287 const char *user_exe_path,
288 const ArchSpec& specified_arch,
289 bool get_dependent_files,
290 PlatformSP &platform_sp,
291 TargetSP &target_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000292{
293 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytona0ca6602012-10-18 16:33:33 +0000294 "TargetList::CreateTarget (file = '%s', arch = '%s')",
295 user_exe_path,
Greg Clayton70512312012-05-08 01:45:38 +0000296 specified_arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000297 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000298
Greg Clayton70512312012-05-08 01:45:38 +0000299 ArchSpec arch(specified_arch);
300
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000301 if (arch.IsValid())
Greg Clayton70512312012-05-08 01:45:38 +0000302 {
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000303 if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL))
304 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
Greg Clayton70512312012-05-08 01:45:38 +0000305 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000306
Greg Clayton70512312012-05-08 01:45:38 +0000307 if (!platform_sp)
308 platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
309
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000310 if (!arch.IsValid())
311 arch = specified_arch;
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000312
Jason Molendad26206b52013-04-19 22:38:50 +0000313 FileSpec file (user_exe_path, false);
314 if (!file.Exists() && user_exe_path && user_exe_path[0] == '~')
315 {
Michael Sartain9f822cd2013-07-31 23:27:46 +0000316 // we want to expand the tilde but we don't want to resolve any symbolic links
317 // so we can't use the FileSpec constructor's resolve flag
Zachary Turner3f559742014-08-07 17:33:36 +0000318 llvm::SmallString<64> unglobbed_path(user_exe_path);
319 FileSpec::ResolveUsername(unglobbed_path);
Michael Sartain9f822cd2013-07-31 23:27:46 +0000320
Zachary Turner3f559742014-08-07 17:33:36 +0000321 if (unglobbed_path.empty())
322 file = FileSpec(user_exe_path, false);
323 else
324 file = FileSpec(unglobbed_path.c_str(), false);
Jason Molendad26206b52013-04-19 22:38:50 +0000325 }
Michael Sartain9f822cd2013-07-31 23:27:46 +0000326
Greg Clayton82d79292012-10-25 22:45:35 +0000327 bool user_exe_path_is_bundle = false;
328 char resolved_bundle_exe_path[PATH_MAX];
329 resolved_bundle_exe_path[0] = '\0';
Greg Claytone996fd32011-03-08 22:40:15 +0000330 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000331 {
Greg Clayton82d79292012-10-25 22:45:35 +0000332 if (file.GetFileType() == FileSpec::eFileTypeDirectory)
333 user_exe_path_is_bundle = true;
334
Greg Claytona0ca6602012-10-18 16:33:33 +0000335 if (file.IsRelativeToCurrentWorkingDirectory())
336 {
337 // Ignore paths that start with "./" and "../"
338 if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
339 (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/')))
340 {
341 char cwd[PATH_MAX];
342 if (getcwd (cwd, sizeof(cwd)))
343 {
344 std::string cwd_user_exe_path (cwd);
345 cwd_user_exe_path += '/';
346 cwd_user_exe_path += user_exe_path;
Greg Clayton9ff5aae2013-04-04 00:15:09 +0000347 FileSpec cwd_file (cwd_user_exe_path.c_str(), false);
348 if (cwd_file.Exists())
349 file = cwd_file;
Greg Claytona0ca6602012-10-18 16:33:33 +0000350 }
351 }
352 }
353
Jim Ingham5aee1622010-08-09 23:31:02 +0000354 ModuleSP exe_module_sp;
Greg Claytone996fd32011-03-08 22:40:15 +0000355 if (platform_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000356 {
357 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
Greg Clayton70512312012-05-08 01:45:38 +0000358 error = platform_sp->ResolveExecutable (file,
359 arch,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000360 exe_module_sp,
361 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
362 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363
Greg Claytone996fd32011-03-08 22:40:15 +0000364 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000366 if (exe_module_sp->GetObjectFile() == NULL)
367 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000368 if (arch.IsValid())
369 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000370 error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s",
371 file.GetPath().c_str(),
Greg Clayton64195a22011-02-23 00:35:02 +0000372 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000373 }
374 else
375 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000376 error.SetErrorStringWithFormat("unsupported file type \"%s\"",
377 file.GetPath().c_str());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000378 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000379 return error;
380 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000381 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +0000382 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Greg Clayton82d79292012-10-25 22:45:35 +0000383 if (user_exe_path_is_bundle)
384 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000386 }
Greg Claytone996fd32011-03-08 22:40:15 +0000387 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000388 {
Greg Claytone996fd32011-03-08 22:40:15 +0000389 // No file was specified, just create an empty target with any arch
390 // if a valid arch was specified
Greg Clayton32e0a752011-03-30 18:16:51 +0000391 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000392 }
393
394 if (target_sp)
395 {
Greg Clayton82d79292012-10-25 22:45:35 +0000396 // Set argv0 with what the user typed, unless the user specified a
397 // directory. If the user specified a directory, then it is probably a
398 // bundle that was resolved and we need to use the resolved bundle path
Greg Claytona0ca6602012-10-18 16:33:33 +0000399 if (user_exe_path)
400 {
401 // Use exactly what the user typed as the first argument when we exec or posix_spawn
Greg Clayton82d79292012-10-25 22:45:35 +0000402 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
403 {
404 target_sp->SetArg0 (resolved_bundle_exe_path);
405 }
406 else
407 {
Michael Sartain9f822cd2013-07-31 23:27:46 +0000408 // Use resolved path
409 target_sp->SetArg0 (file.GetPath().c_str());
Greg Clayton82d79292012-10-25 22:45:35 +0000410 }
Greg Claytona0ca6602012-10-18 16:33:33 +0000411 }
412 if (file.GetDirectory())
413 {
414 FileSpec file_dir;
415 file_dir.GetDirectory() = file.GetDirectory();
416 target_sp->GetExecutableSearchPaths ().Append (file_dir);
417 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000418 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000419 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000420 m_target_list.push_back(target_sp);
Greg Claytona0ca6602012-10-18 16:33:33 +0000421
422
Jim Ingham5aee1622010-08-09 23:31:02 +0000423 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000424
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425 return error;
426}
427
428bool
429TargetList::DeleteTarget (TargetSP &target_sp)
430{
431 Mutex::Locker locker(m_target_list_mutex);
432 collection::iterator pos, end = m_target_list.end();
433
434 for (pos = m_target_list.begin(); pos != end; ++pos)
435 {
436 if (pos->get() == target_sp.get())
437 {
438 m_target_list.erase(pos);
439 return true;
440 }
441 }
442 return false;
443}
444
445
446TargetSP
447TargetList::FindTargetWithExecutableAndArchitecture
448(
449 const FileSpec &exe_file_spec,
450 const ArchSpec *exe_arch_ptr
451) const
452{
453 Mutex::Locker locker (m_target_list_mutex);
454 TargetSP target_sp;
Sean Callananddd7a2a2013-10-03 22:27:29 +0000455 bool full_match = (bool)exe_file_spec.GetDirectory();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456
457 collection::const_iterator pos, end = m_target_list.end();
458 for (pos = m_target_list.begin(); pos != end; ++pos)
459 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000460 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461
Greg Claytonaa149cb2011-08-11 02:48:45 +0000462 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000464 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465 {
466 if (exe_arch_ptr)
467 {
Sean Callananbf4b7be2012-12-13 22:07:14 +0000468 if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469 continue;
470 }
471 target_sp = *pos;
472 break;
473 }
474 }
475 }
476 return target_sp;
477}
478
479TargetSP
480TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
481{
482 Mutex::Locker locker(m_target_list_mutex);
483 TargetSP target_sp;
484 collection::const_iterator pos, end = m_target_list.end();
485 for (pos = m_target_list.begin(); pos != end; ++pos)
486 {
487 Process* process = (*pos)->GetProcessSP().get();
488 if (process && process->GetID() == pid)
489 {
490 target_sp = *pos;
491 break;
492 }
493 }
494 return target_sp;
495}
496
497
498TargetSP
499TargetList::FindTargetWithProcess (Process *process) const
500{
501 TargetSP target_sp;
502 if (process)
503 {
504 Mutex::Locker locker(m_target_list_mutex);
505 collection::const_iterator pos, end = m_target_list.end();
506 for (pos = m_target_list.begin(); pos != end; ++pos)
507 {
508 if (process == (*pos)->GetProcessSP().get())
509 {
510 target_sp = *pos;
511 break;
512 }
513 }
514 }
515 return target_sp;
516}
517
518TargetSP
519TargetList::GetTargetSP (Target *target) const
520{
521 TargetSP target_sp;
522 if (target)
523 {
524 Mutex::Locker locker(m_target_list_mutex);
525 collection::const_iterator pos, end = m_target_list.end();
526 for (pos = m_target_list.begin(); pos != end; ++pos)
527 {
528 if (target == (*pos).get())
529 {
530 target_sp = *pos;
531 break;
532 }
533 }
534 }
535 return target_sp;
536}
537
538uint32_t
539TargetList::SendAsyncInterrupt (lldb::pid_t pid)
540{
541 uint32_t num_async_interrupts_sent = 0;
542
543 if (pid != LLDB_INVALID_PROCESS_ID)
544 {
545 TargetSP target_sp(FindTargetWithProcessID (pid));
546 if (target_sp.get())
547 {
548 Process* process = target_sp->GetProcessSP().get();
549 if (process)
550 {
Jim Inghamcfc09352012-07-27 23:57:19 +0000551 process->SendAsyncInterrupt();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000552 ++num_async_interrupts_sent;
553 }
554 }
555 }
556 else
557 {
558 // We don't have a valid pid to broadcast to, so broadcast to the target
559 // list's async broadcaster...
560 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
561 }
562
563 return num_async_interrupts_sent;
564}
565
566uint32_t
567TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
568{
569 uint32_t num_signals_sent = 0;
570 Process *process = NULL;
571 if (pid == LLDB_INVALID_PROCESS_ID)
572 {
573 // Signal all processes with signal
574 Mutex::Locker locker(m_target_list_mutex);
575 collection::iterator pos, end = m_target_list.end();
576 for (pos = m_target_list.begin(); pos != end; ++pos)
577 {
578 process = (*pos)->GetProcessSP().get();
579 if (process)
580 {
581 if (process->IsAlive())
582 {
583 ++num_signals_sent;
584 process->Signal (signo);
585 }
586 }
587 }
588 }
589 else
590 {
591 // Signal a specific process with signal
592 TargetSP target_sp(FindTargetWithProcessID (pid));
593 if (target_sp.get())
594 {
595 process = target_sp->GetProcessSP().get();
596 if (process)
597 {
598 if (process->IsAlive())
599 {
600 ++num_signals_sent;
601 process->Signal (signo);
602 }
603 }
604 }
605 }
606 return num_signals_sent;
607}
608
609int
610TargetList::GetNumTargets () const
611{
612 Mutex::Locker locker (m_target_list_mutex);
613 return m_target_list.size();
614}
615
616lldb::TargetSP
617TargetList::GetTargetAtIndex (uint32_t idx) const
618{
619 TargetSP target_sp;
620 Mutex::Locker locker (m_target_list_mutex);
621 if (idx < m_target_list.size())
622 target_sp = m_target_list[idx];
623 return target_sp;
624}
625
626uint32_t
Jim Ingham8499e1a2012-05-08 23:06:07 +0000627TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
628{
629 Mutex::Locker locker (m_target_list_mutex);
630 size_t num_targets = m_target_list.size();
631 for (size_t idx = 0; idx < num_targets; idx++)
632 {
633 if (target_sp == m_target_list[idx])
634 return idx;
635 }
636 return UINT32_MAX;
637}
638
639uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000640TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641{
642 Mutex::Locker locker (m_target_list_mutex);
643 collection::const_iterator pos,
644 begin = m_target_list.begin(),
645 end = m_target_list.end();
646 for (pos = begin; pos != end; ++pos)
647 {
648 if (pos->get() == target)
649 {
Jim Ingham2976d002010-08-26 21:32:51 +0000650 m_selected_target_idx = std::distance (begin, pos);
651 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 }
653 }
Jim Ingham2976d002010-08-26 21:32:51 +0000654 m_selected_target_idx = 0;
655 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000656}
657
658lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000659TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000660{
661 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000662 if (m_selected_target_idx >= m_target_list.size())
663 m_selected_target_idx = 0;
664 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000665}