blob: 6e7577206aff472f5e62db3a8bfa5aedd038a8ee [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
10// C Includes
11// C++ Includes
12// Other libraries and framework includes
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +000013#include "llvm/ADT/SmallString.h"
14
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015// 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"
Jim Ingham893c9322014-11-22 01:42:44 +000024#include "lldb/Host/HostInfo.h"
Greg Claytonb3a40ba2012-03-20 18:34:04 +000025#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytoncac9c5f2011-09-24 00:52:29 +000026#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytonf4d6de62013-04-24 22:29:28 +000027#include "lldb/Symbol/ObjectFile.h"
Greg Claytone996fd32011-03-08 22:40:15 +000028#include "lldb/Target/Platform.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/Process.h"
30#include "lldb/Target/TargetList.h"
31
32using namespace lldb;
33using namespace lldb_private;
34
Jim Ingham4bddaeb2012-02-16 06:50:00 +000035ConstString &
36TargetList::GetStaticBroadcasterClass ()
37{
38 static ConstString class_name ("lldb.targetList");
39 return class_name;
40}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041
42//----------------------------------------------------------------------
43// TargetList constructor
44//----------------------------------------------------------------------
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000045TargetList::TargetList(Debugger &debugger)
46 : Broadcaster(debugger.GetBroadcasterManager(), TargetList::GetStaticBroadcasterClass().AsCString()),
47 m_target_list(),
48 m_target_list_mutex(),
49 m_selected_target_idx(0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050{
Jim Ingham4bddaeb2012-02-16 06:50:00 +000051 CheckInWithManager();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052}
53
54//----------------------------------------------------------------------
55// Destructor
56//----------------------------------------------------------------------
57TargetList::~TargetList()
58{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +000059 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060 m_target_list.clear();
61}
62
63Error
Greg Claytoncac9c5f2011-09-24 00:52:29 +000064TargetList::CreateTarget (Debugger &debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +000065 const char *user_exe_path,
Greg Claytoncac9c5f2011-09-24 00:52:29 +000066 const char *triple_cstr,
67 bool get_dependent_files,
68 const OptionGroupPlatform *platform_options,
69 TargetSP &target_sp)
70{
Jim Ingham893c9322014-11-22 01:42:44 +000071 return CreateTargetInternal (debugger,
72 user_exe_path,
73 triple_cstr,
74 get_dependent_files,
75 platform_options,
76 target_sp,
77 false);
78}
79
80Error
81TargetList::CreateTarget (Debugger &debugger,
82 const char *user_exe_path,
83 const ArchSpec& specified_arch,
84 bool get_dependent_files,
85 PlatformSP &platform_sp,
86 TargetSP &target_sp)
87{
88 return CreateTargetInternal (debugger,
89 user_exe_path,
90 specified_arch,
91 get_dependent_files,
92 platform_sp,
93 target_sp,
94 false);
95}
96
97Error
98TargetList::CreateTargetInternal (Debugger &debugger,
Greg Claytond26a1e52015-01-28 22:08:17 +000099 const char *user_exe_path,
100 const char *triple_cstr,
101 bool get_dependent_files,
102 const OptionGroupPlatform *platform_options,
103 TargetSP &target_sp,
104 bool is_dummy_target)
Jim Ingham893c9322014-11-22 01:42:44 +0000105{
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000106 Error error;
107 PlatformSP platform_sp;
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000108
Johnny Chencdc21d42012-01-05 01:26:01 +0000109 // This is purposely left empty unless it is specified by triple_cstr.
110 // If not initialized via triple_cstr, then the currently selected platform
111 // will set the architecture correctly.
Greg Clayton70512312012-05-08 01:45:38 +0000112 const ArchSpec arch(triple_cstr);
113 if (triple_cstr && triple_cstr[0])
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000114 {
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000115 if (!arch.IsValid())
116 {
Greg Clayton86edbf42011-10-26 00:56:27 +0000117 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000118 return error;
119 }
120 }
Greg Claytonf4d6de62013-04-24 22:29:28 +0000121
Greg Clayton70512312012-05-08 01:45:38 +0000122 ArchSpec platform_arch(arch);
Greg Claytonf4d6de62013-04-24 22:29:28 +0000123
Greg Clayton3f19ada2014-07-10 23:33:37 +0000124 bool prefer_platform_arch = false;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000125
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000126 CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
Vince Harron1b5a74e2015-01-21 22:42:49 +0000127
128 // let's see if there is already an existing plaform before we go creating another...
129 platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
130
Greg Claytonccd2a6d2015-01-28 01:33:37 +0000131 if (platform_options && platform_options->PlatformWasSpecified ())
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000132 {
Greg Claytonccd2a6d2015-01-28 01:33:37 +0000133 // Create a new platform if it doesn't match the selected platform
134 if (!platform_options->PlatformMatches(platform_sp))
135 {
136 const bool select_platform = true;
137 platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
138 arch,
139 select_platform,
140 error,
141 platform_arch);
142 if (!platform_sp)
143 return error;
144 }
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000145 }
146
Greg Claytonf4d6de62013-04-24 22:29:28 +0000147 if (user_exe_path && user_exe_path[0])
148 {
149 ModuleSpecList module_specs;
150 ModuleSpec module_spec;
151 module_spec.GetFileSpec().SetFile(user_exe_path, true);
Greg Claytonc76fa8a2014-07-29 21:27:21 +0000152
153 // Resolve the executable in case we are given a path to a application bundle
154 // like a .app bundle on MacOSX
155 Host::ResolveExecutableInBundle (module_spec.GetFileSpec());
156
Greg Claytonf4d6de62013-04-24 22:29:28 +0000157 lldb::offset_t file_offset = 0;
Greg Clayton2540a8a2013-07-12 22:07:46 +0000158 lldb::offset_t file_size = 0;
159 const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs);
Greg Claytonf4d6de62013-04-24 22:29:28 +0000160 if (num_specs > 0)
161 {
162 ModuleSpec matching_module_spec;
163
164 if (num_specs == 1)
165 {
166 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec))
167 {
168 if (platform_arch.IsValid())
169 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000170 if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture()))
171 {
172 // If the OS or vendor weren't specified, then adopt the module's
173 // architecture so that the platform matching can be more accurate
174 if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified())
175 {
176 prefer_platform_arch = true;
177 platform_arch = matching_module_spec.GetArchitecture();
178 }
179 }
180 else
Greg Claytonf4d6de62013-04-24 22:29:28 +0000181 {
Todd Fiala7df337f2015-10-13 23:41:19 +0000182 StreamString platform_arch_strm;
183 StreamString module_arch_strm;
184
185 platform_arch.DumpTriple(platform_arch_strm);
186 matching_module_spec.GetArchitecture().DumpTriple(module_arch_strm);
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000187 error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'",
Todd Fiala7df337f2015-10-13 23:41:19 +0000188 platform_arch_strm.GetString().c_str(),
189 module_arch_strm.GetString().c_str(),
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000190 module_spec.GetFileSpec().GetPath().c_str());
Greg Claytonf4d6de62013-04-24 22:29:28 +0000191 return error;
192 }
193 }
194 else
195 {
196 // Only one arch and none was specified
Greg Clayton3f19ada2014-07-10 23:33:37 +0000197 prefer_platform_arch = true;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000198 platform_arch = matching_module_spec.GetArchitecture();
199 }
200 }
201 }
202 else
203 {
204 if (arch.IsValid())
205 {
206 module_spec.GetArchitecture() = arch;
207 if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec))
208 {
Greg Clayton3f19ada2014-07-10 23:33:37 +0000209 prefer_platform_arch = true;
Greg Claytonf4d6de62013-04-24 22:29:28 +0000210 platform_arch = matching_module_spec.GetArchitecture();
211 }
212 }
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000213 else
214 {
215 // No architecture specified, check if there is only one platform for
216 // all of the architectures.
217
218 typedef std::vector<PlatformSP> PlatformList;
219 PlatformList platforms;
Greg Clayton615eb7e2014-09-19 20:11:50 +0000220 PlatformSP host_platform_sp = Platform::GetHostPlatform();
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000221 for (size_t i=0; i<num_specs; ++i)
222 {
223 ModuleSpec module_spec;
224 if (module_specs.GetModuleSpecAtIndex(i, module_spec))
225 {
226 // See if there was a selected platform and check that first
227 // since the user may have specified it.
228 if (platform_sp)
229 {
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000230 if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, nullptr))
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000231 {
232 platforms.push_back(platform_sp);
233 continue;
234 }
235 }
236
237 // Next check the host platform it if wasn't already checked above
238 if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName()))
239 {
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000240 if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, nullptr))
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000241 {
242 platforms.push_back(host_platform_sp);
243 continue;
244 }
245 }
246
247 // Just find a platform that matches the architecture in the executable file
Jason Molendae92a74c2015-11-21 04:00:43 +0000248 PlatformSP fallback_platform_sp (Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr));
249 if (fallback_platform_sp)
250 {
251 platforms.push_back(fallback_platform_sp);
252 }
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000253 }
254 }
255
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000256 Platform *platform_ptr = nullptr;
Jason Molenda9d58c722015-11-05 23:59:30 +0000257 bool more_than_one_platforms = false;
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000258 for (const auto &the_platform_sp : platforms)
259 {
260 if (platform_ptr)
261 {
262 if (platform_ptr->GetName() != the_platform_sp->GetName())
263 {
Jason Molenda9d58c722015-11-05 23:59:30 +0000264 more_than_one_platforms = true;
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000265 platform_ptr = nullptr;
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000266 break;
267 }
268 }
269 else
270 {
271 platform_ptr = the_platform_sp.get();
272 }
273 }
274
275 if (platform_ptr)
276 {
277 // All platforms for all modules in the exectuable match, so we can select this platform
278 platform_sp = platforms.front();
279 }
Jason Molenda9d58c722015-11-05 23:59:30 +0000280 else if (more_than_one_platforms == false)
281 {
282 // No platforms claim to support this file
283 error.SetErrorString ("No matching platforms found for this file, specify one with the --platform option");
284 return error;
285 }
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000286 else
287 {
288 // More than one platform claims to support this file, so the --platform option must be specified
289 StreamString error_strm;
290 std::set<Platform *> platform_set;
291 error_strm.Printf ("more than one platform supports this executable (");
292 for (const auto &the_platform_sp : platforms)
293 {
294 if (platform_set.find(the_platform_sp.get()) == platform_set.end())
295 {
296 if (!platform_set.empty())
297 error_strm.PutCString(", ");
298 error_strm.PutCString(the_platform_sp->GetName().GetCString());
299 platform_set.insert(the_platform_sp.get());
300 }
301 }
302 error_strm.Printf("), use the --platform option to specify a platform");
303 error.SetErrorString(error_strm.GetString().c_str());
304 return error;
305 }
306 }
Greg Claytonf4d6de62013-04-24 22:29:28 +0000307 }
308 }
309 }
310
Ted Woodward869e0c12015-05-11 21:23:31 +0000311 // If we have a valid architecture, make sure the current platform is
312 // compatible with that architecture
313 if (!prefer_platform_arch && arch.IsValid())
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000314 {
Ted Woodward869e0c12015-05-11 21:23:31 +0000315 if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000316 {
Ted Woodward869e0c12015-05-11 21:23:31 +0000317 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
Robert Flack8ec55a52015-05-13 00:39:24 +0000318 if (!is_dummy_target && platform_sp)
Ted Woodward869e0c12015-05-11 21:23:31 +0000319 debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
Greg Clayton3f19ada2014-07-10 23:33:37 +0000320 }
Ted Woodward869e0c12015-05-11 21:23:31 +0000321 }
322 else if (platform_arch.IsValid())
323 {
324 // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with
325 // a single architecture which should be used
326 ArchSpec fixed_platform_arch;
327 if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch))
Greg Clayton3f19ada2014-07-10 23:33:37 +0000328 {
Ted Woodward869e0c12015-05-11 21:23:31 +0000329 platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch);
Robert Flack8ec55a52015-05-13 00:39:24 +0000330 if (!is_dummy_target && platform_sp)
Ted Woodward869e0c12015-05-11 21:23:31 +0000331 debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000332 }
333 }
Greg Clayton70512312012-05-08 01:45:38 +0000334
335 if (!platform_arch.IsValid())
336 platform_arch = arch;
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000337
Jim Ingham893c9322014-11-22 01:42:44 +0000338 error = TargetList::CreateTargetInternal (debugger,
339 user_exe_path,
340 platform_arch,
341 get_dependent_files,
342 platform_sp,
343 target_sp,
344 is_dummy_target);
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000345 return error;
346}
347
Jim Ingham893c9322014-11-22 01:42:44 +0000348lldb::TargetSP
349TargetList::GetDummyTarget (lldb_private::Debugger &debugger)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350{
Jim Ingham893c9322014-11-22 01:42:44 +0000351 // FIXME: Maybe the dummy target should be per-Debugger
352 if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid())
353 {
354 ArchSpec arch(Target::GetDefaultArchitecture());
355 if (!arch.IsValid())
356 arch = HostInfo::GetArchitecture();
357 Error err = CreateDummyTarget(debugger,
358 arch.GetTriple().getTriple().c_str(),
359 m_dummy_target_sp);
360 }
361
362 return m_dummy_target_sp;
363}
364
365Error
366TargetList::CreateDummyTarget (Debugger &debugger,
367 const char *specified_arch_name,
368 lldb::TargetSP &target_sp)
369{
370 PlatformSP host_platform_sp(Platform::GetHostPlatform());
371 return CreateTargetInternal (debugger,
372 (const char *) nullptr,
373 specified_arch_name,
374 false,
375 (const OptionGroupPlatform *) nullptr,
376 target_sp,
377 true);
378}
379
380Error
381TargetList::CreateTargetInternal (Debugger &debugger,
Greg Claytond26a1e52015-01-28 22:08:17 +0000382 const char *user_exe_path,
383 const ArchSpec& specified_arch,
384 bool get_dependent_files,
385 lldb::PlatformSP &platform_sp,
386 lldb::TargetSP &target_sp,
387 bool is_dummy_target)
Jim Ingham893c9322014-11-22 01:42:44 +0000388{
Zachary Turnerf343968f2016-08-09 23:06:08 +0000389 Timer scoped_timer (LLVM_PRETTY_FUNCTION,
Greg Claytona0ca6602012-10-18 16:33:33 +0000390 "TargetList::CreateTarget (file = '%s', arch = '%s')",
391 user_exe_path,
Greg Clayton70512312012-05-08 01:45:38 +0000392 specified_arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000393 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000394
Greg Clayton70512312012-05-08 01:45:38 +0000395 ArchSpec arch(specified_arch);
396
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000397 if (arch.IsValid())
Greg Clayton70512312012-05-08 01:45:38 +0000398 {
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000399 if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, nullptr))
Greg Claytonb0cc53c2014-08-20 18:13:03 +0000400 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
Greg Clayton70512312012-05-08 01:45:38 +0000401 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000402
Greg Clayton70512312012-05-08 01:45:38 +0000403 if (!platform_sp)
404 platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
405
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000406 if (!arch.IsValid())
407 arch = specified_arch;
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000408
Jason Molendad26206b52013-04-19 22:38:50 +0000409 FileSpec file (user_exe_path, false);
410 if (!file.Exists() && user_exe_path && user_exe_path[0] == '~')
411 {
Michael Sartain9f822cd2013-07-31 23:27:46 +0000412 // we want to expand the tilde but we don't want to resolve any symbolic links
413 // so we can't use the FileSpec constructor's resolve flag
Zachary Turner3f559742014-08-07 17:33:36 +0000414 llvm::SmallString<64> unglobbed_path(user_exe_path);
415 FileSpec::ResolveUsername(unglobbed_path);
Michael Sartain9f822cd2013-07-31 23:27:46 +0000416
Zachary Turner3f559742014-08-07 17:33:36 +0000417 if (unglobbed_path.empty())
418 file = FileSpec(user_exe_path, false);
419 else
420 file = FileSpec(unglobbed_path.c_str(), false);
Jason Molendad26206b52013-04-19 22:38:50 +0000421 }
Michael Sartain9f822cd2013-07-31 23:27:46 +0000422
Greg Clayton82d79292012-10-25 22:45:35 +0000423 bool user_exe_path_is_bundle = false;
424 char resolved_bundle_exe_path[PATH_MAX];
425 resolved_bundle_exe_path[0] = '\0';
Greg Claytone996fd32011-03-08 22:40:15 +0000426 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000427 {
Greg Clayton82d79292012-10-25 22:45:35 +0000428 if (file.GetFileType() == FileSpec::eFileTypeDirectory)
429 user_exe_path_is_bundle = true;
430
Chaoren Lin372e9062015-06-09 17:54:27 +0000431 if (file.IsRelative() && user_exe_path)
Greg Claytona0ca6602012-10-18 16:33:33 +0000432 {
433 // Ignore paths that start with "./" and "../"
434 if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
435 (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/')))
436 {
437 char cwd[PATH_MAX];
438 if (getcwd (cwd, sizeof(cwd)))
439 {
440 std::string cwd_user_exe_path (cwd);
441 cwd_user_exe_path += '/';
442 cwd_user_exe_path += user_exe_path;
Greg Clayton9ff5aae2013-04-04 00:15:09 +0000443 FileSpec cwd_file (cwd_user_exe_path.c_str(), false);
444 if (cwd_file.Exists())
445 file = cwd_file;
Greg Claytona0ca6602012-10-18 16:33:33 +0000446 }
447 }
448 }
449
Jim Ingham5aee1622010-08-09 23:31:02 +0000450 ModuleSP exe_module_sp;
Greg Claytone996fd32011-03-08 22:40:15 +0000451 if (platform_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000452 {
453 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
Greg Clayton8012cad2014-11-17 19:39:20 +0000454 ModuleSpec module_spec(file, arch);
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000455 error = platform_sp->ResolveExecutable(module_spec,
456 exe_module_sp,
457 executable_search_paths.GetSize() ? &executable_search_paths : nullptr);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000458 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459
Greg Claytone996fd32011-03-08 22:40:15 +0000460 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461 {
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000462 if (exe_module_sp->GetObjectFile() == nullptr)
Jim Ingham5aee1622010-08-09 23:31:02 +0000463 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000464 if (arch.IsValid())
465 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000466 error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s",
467 file.GetPath().c_str(),
Greg Clayton64195a22011-02-23 00:35:02 +0000468 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000469 }
470 else
471 {
Greg Claytonb5ad4ec2013-04-29 17:25:54 +0000472 error.SetErrorStringWithFormat("unsupported file type \"%s\"",
473 file.GetPath().c_str());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000474 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000475 return error;
476 }
Jim Ingham893c9322014-11-22 01:42:44 +0000477 target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target));
Jim Ingham5aee1622010-08-09 23:31:02 +0000478 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Greg Clayton82d79292012-10-25 22:45:35 +0000479 if (user_exe_path_is_bundle)
480 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000482 }
Greg Claytone996fd32011-03-08 22:40:15 +0000483 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000484 {
Greg Claytone996fd32011-03-08 22:40:15 +0000485 // No file was specified, just create an empty target with any arch
486 // if a valid arch was specified
Jim Ingham893c9322014-11-22 01:42:44 +0000487 target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target));
Greg Claytone996fd32011-03-08 22:40:15 +0000488 }
489
490 if (target_sp)
491 {
Greg Clayton82d79292012-10-25 22:45:35 +0000492 // Set argv0 with what the user typed, unless the user specified a
493 // directory. If the user specified a directory, then it is probably a
494 // bundle that was resolved and we need to use the resolved bundle path
Greg Claytona0ca6602012-10-18 16:33:33 +0000495 if (user_exe_path)
496 {
497 // Use exactly what the user typed as the first argument when we exec or posix_spawn
Greg Clayton82d79292012-10-25 22:45:35 +0000498 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
499 {
500 target_sp->SetArg0 (resolved_bundle_exe_path);
501 }
502 else
503 {
Michael Sartain9f822cd2013-07-31 23:27:46 +0000504 // Use resolved path
505 target_sp->SetArg0 (file.GetPath().c_str());
Greg Clayton82d79292012-10-25 22:45:35 +0000506 }
Greg Claytona0ca6602012-10-18 16:33:33 +0000507 }
508 if (file.GetDirectory())
509 {
510 FileSpec file_dir;
511 file_dir.GetDirectory() = file.GetDirectory();
512 target_sp->GetExecutableSearchPaths ().Append (file_dir);
513 }
Jim Ingham893c9322014-11-22 01:42:44 +0000514
515 // Don't put the dummy target in the target list, it's held separately.
516 if (!is_dummy_target)
517 {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000518 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Jim Ingham893c9322014-11-22 01:42:44 +0000519 m_selected_target_idx = m_target_list.size();
520 m_target_list.push_back(target_sp);
Jim Ingham33df7cd2014-12-06 01:28:03 +0000521 // Now prime this from the dummy target:
522 target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget());
Jim Ingham893c9322014-11-22 01:42:44 +0000523 }
524 else
525 {
526 m_dummy_target_sp = target_sp;
527 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000528 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000530 return error;
531}
532
533bool
534TargetList::DeleteTarget (TargetSP &target_sp)
535{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000536 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000537 collection::iterator pos, end = m_target_list.end();
538
539 for (pos = m_target_list.begin(); pos != end; ++pos)
540 {
541 if (pos->get() == target_sp.get())
542 {
543 m_target_list.erase(pos);
544 return true;
545 }
546 }
547 return false;
548}
549
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550TargetSP
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000551TargetList::FindTargetWithExecutableAndArchitecture(const FileSpec &exe_file_spec,
552 const ArchSpec *exe_arch_ptr) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000554 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000555 TargetSP target_sp;
Sean Callananddd7a2a2013-10-03 22:27:29 +0000556 bool full_match = (bool)exe_file_spec.GetDirectory();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557
558 collection::const_iterator pos, end = m_target_list.end();
559 for (pos = m_target_list.begin(); pos != end; ++pos)
560 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000561 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562
Greg Claytonaa149cb2011-08-11 02:48:45 +0000563 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000564 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000565 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000566 {
567 if (exe_arch_ptr)
568 {
Sean Callananbf4b7be2012-12-13 22:07:14 +0000569 if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000570 continue;
571 }
572 target_sp = *pos;
573 break;
574 }
575 }
576 }
577 return target_sp;
578}
579
580TargetSP
581TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
582{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000583 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584 TargetSP target_sp;
585 collection::const_iterator pos, end = m_target_list.end();
586 for (pos = m_target_list.begin(); pos != end; ++pos)
587 {
588 Process* process = (*pos)->GetProcessSP().get();
589 if (process && process->GetID() == pid)
590 {
591 target_sp = *pos;
592 break;
593 }
594 }
595 return target_sp;
596}
597
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000598TargetSP
599TargetList::FindTargetWithProcess (Process *process) const
600{
601 TargetSP target_sp;
602 if (process)
603 {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000604 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000605 collection::const_iterator pos, end = m_target_list.end();
606 for (pos = m_target_list.begin(); pos != end; ++pos)
607 {
608 if (process == (*pos)->GetProcessSP().get())
609 {
610 target_sp = *pos;
611 break;
612 }
613 }
614 }
615 return target_sp;
616}
617
618TargetSP
619TargetList::GetTargetSP (Target *target) const
620{
621 TargetSP target_sp;
622 if (target)
623 {
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000624 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000625 collection::const_iterator pos, end = m_target_list.end();
626 for (pos = m_target_list.begin(); pos != end; ++pos)
627 {
628 if (target == (*pos).get())
629 {
630 target_sp = *pos;
631 break;
632 }
633 }
634 }
635 return target_sp;
636}
637
638uint32_t
639TargetList::SendAsyncInterrupt (lldb::pid_t pid)
640{
641 uint32_t num_async_interrupts_sent = 0;
642
643 if (pid != LLDB_INVALID_PROCESS_ID)
644 {
645 TargetSP target_sp(FindTargetWithProcessID (pid));
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000646 if (target_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000647 {
648 Process* process = target_sp->GetProcessSP().get();
649 if (process)
650 {
Jim Inghamcfc09352012-07-27 23:57:19 +0000651 process->SendAsyncInterrupt();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 ++num_async_interrupts_sent;
653 }
654 }
655 }
656 else
657 {
658 // We don't have a valid pid to broadcast to, so broadcast to the target
659 // list's async broadcaster...
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000660 BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661 }
662
663 return num_async_interrupts_sent;
664}
665
666uint32_t
667TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
668{
669 uint32_t num_signals_sent = 0;
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000670 Process *process = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000671 if (pid == LLDB_INVALID_PROCESS_ID)
672 {
673 // Signal all processes with signal
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000674 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000675 collection::iterator pos, end = m_target_list.end();
676 for (pos = m_target_list.begin(); pos != end; ++pos)
677 {
678 process = (*pos)->GetProcessSP().get();
679 if (process)
680 {
681 if (process->IsAlive())
682 {
683 ++num_signals_sent;
684 process->Signal (signo);
685 }
686 }
687 }
688 }
689 else
690 {
691 // Signal a specific process with signal
692 TargetSP target_sp(FindTargetWithProcessID (pid));
Eugene Zelenkoe65b2cf2015-12-15 01:33:19 +0000693 if (target_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000694 {
695 process = target_sp->GetProcessSP().get();
696 if (process)
697 {
698 if (process->IsAlive())
699 {
700 ++num_signals_sent;
701 process->Signal (signo);
702 }
703 }
704 }
705 }
706 return num_signals_sent;
707}
708
709int
710TargetList::GetNumTargets () const
711{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000712 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000713 return m_target_list.size();
714}
715
716lldb::TargetSP
717TargetList::GetTargetAtIndex (uint32_t idx) const
718{
719 TargetSP target_sp;
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000720 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000721 if (idx < m_target_list.size())
722 target_sp = m_target_list[idx];
723 return target_sp;
724}
725
726uint32_t
Jim Ingham8499e1a2012-05-08 23:06:07 +0000727TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
728{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000729 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Jim Ingham8499e1a2012-05-08 23:06:07 +0000730 size_t num_targets = m_target_list.size();
731 for (size_t idx = 0; idx < num_targets; idx++)
732 {
733 if (target_sp == m_target_list[idx])
734 return idx;
735 }
736 return UINT32_MAX;
737}
738
739uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000740TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000741{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000742 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000743 collection::const_iterator pos,
744 begin = m_target_list.begin(),
745 end = m_target_list.end();
746 for (pos = begin; pos != end; ++pos)
747 {
748 if (pos->get() == target)
749 {
Jim Ingham2976d002010-08-26 21:32:51 +0000750 m_selected_target_idx = std::distance (begin, pos);
751 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000752 }
753 }
Jim Ingham2976d002010-08-26 21:32:51 +0000754 m_selected_target_idx = 0;
755 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000756}
757
758lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000759TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000760{
Saleem Abdulrasool16ff8602016-05-18 01:59:10 +0000761 std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000762 if (m_selected_target_idx >= m_target_list.size())
763 m_selected_target_idx = 0;
764 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000765}