blob: ff9c508a695beb8eb38d82f1f01f706db6131537 [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
13// Project includes
14#include "lldb/Core/Broadcaster.h"
Greg Claytonded470d2011-03-19 01:12:21 +000015#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/Event.h"
Greg Clayton1f746072012-08-29 21:13:06 +000017#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/State.h"
19#include "lldb/Core/Timer.h"
20#include "lldb/Host/Host.h"
Greg Claytonb3a40ba2012-03-20 18:34:04 +000021#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytoncac9c5f2011-09-24 00:52:29 +000022#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytone996fd32011-03-08 22:40:15 +000023#include "lldb/Target/Platform.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Target/Process.h"
25#include "lldb/Target/TargetList.h"
26
27using namespace lldb;
28using namespace lldb_private;
29
Jim Ingham4bddaeb2012-02-16 06:50:00 +000030ConstString &
31TargetList::GetStaticBroadcasterClass ()
32{
33 static ConstString class_name ("lldb.targetList");
34 return class_name;
35}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036
37//----------------------------------------------------------------------
38// TargetList constructor
39//----------------------------------------------------------------------
Jim Ingham4bddaeb2012-02-16 06:50:00 +000040TargetList::TargetList(Debugger &debugger) :
Jim Ingham4f465cf2012-10-10 18:32:14 +000041 Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042 m_target_list(),
43 m_target_list_mutex (Mutex::eMutexTypeRecursive),
Jim Ingham2976d002010-08-26 21:32:51 +000044 m_selected_target_idx (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045{
Jim Ingham4bddaeb2012-02-16 06:50:00 +000046 CheckInWithManager();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047}
48
49//----------------------------------------------------------------------
50// Destructor
51//----------------------------------------------------------------------
52TargetList::~TargetList()
53{
54 Mutex::Locker locker(m_target_list_mutex);
55 m_target_list.clear();
56}
57
58Error
Greg Claytoncac9c5f2011-09-24 00:52:29 +000059TargetList::CreateTarget (Debugger &debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +000060 const char *user_exe_path,
Greg Claytoncac9c5f2011-09-24 00:52:29 +000061 const char *triple_cstr,
62 bool get_dependent_files,
63 const OptionGroupPlatform *platform_options,
64 TargetSP &target_sp)
65{
66 Error error;
67 PlatformSP platform_sp;
Greg Claytoncac9c5f2011-09-24 00:52:29 +000068
Johnny Chencdc21d42012-01-05 01:26:01 +000069 // This is purposely left empty unless it is specified by triple_cstr.
70 // If not initialized via triple_cstr, then the currently selected platform
71 // will set the architecture correctly.
Greg Clayton70512312012-05-08 01:45:38 +000072 const ArchSpec arch(triple_cstr);
73 if (triple_cstr && triple_cstr[0])
Greg Claytoncac9c5f2011-09-24 00:52:29 +000074 {
Greg Claytoncac9c5f2011-09-24 00:52:29 +000075 if (!arch.IsValid())
76 {
Greg Clayton86edbf42011-10-26 00:56:27 +000077 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
Greg Claytoncac9c5f2011-09-24 00:52:29 +000078 return error;
79 }
80 }
Greg Claytonb3a40ba2012-03-20 18:34:04 +000081
Greg Clayton70512312012-05-08 01:45:38 +000082 ArchSpec platform_arch(arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +000083 CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
84 if (platform_options)
85 {
86 if (platform_options->PlatformWasSpecified ())
87 {
88 const bool select_platform = true;
89 platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
90 arch,
91 select_platform,
Greg Clayton70512312012-05-08 01:45:38 +000092 error,
93 platform_arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +000094 if (!platform_sp)
95 return error;
96 }
97 }
98
99 if (!platform_sp)
100 {
101 // Get the current platform and make sure it is compatible with the
102 // current architecture if we have a valid architecture.
103 platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
104
Greg Clayton70512312012-05-08 01:45:38 +0000105 if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, &platform_arch))
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000106 {
Greg Clayton70512312012-05-08 01:45:38 +0000107 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000108 }
109 }
Greg Clayton70512312012-05-08 01:45:38 +0000110
111 if (!platform_arch.IsValid())
112 platform_arch = arch;
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000113
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000114 error = TargetList::CreateTarget (debugger,
Greg Claytona0ca6602012-10-18 16:33:33 +0000115 user_exe_path,
Greg Clayton70512312012-05-08 01:45:38 +0000116 platform_arch,
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000117 get_dependent_files,
118 platform_sp,
119 target_sp);
120 return error;
121}
122
123Error
Greg Claytona0ca6602012-10-18 16:33:33 +0000124TargetList::CreateTarget (Debugger &debugger,
125 const char *user_exe_path,
126 const ArchSpec& specified_arch,
127 bool get_dependent_files,
128 PlatformSP &platform_sp,
129 TargetSP &target_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130{
131 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytona0ca6602012-10-18 16:33:33 +0000132 "TargetList::CreateTarget (file = '%s', arch = '%s')",
133 user_exe_path,
Greg Clayton70512312012-05-08 01:45:38 +0000134 specified_arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000135 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000136
Greg Clayton70512312012-05-08 01:45:38 +0000137 ArchSpec arch(specified_arch);
138
139 if (platform_sp)
140 {
141 if (arch.IsValid())
142 {
143 if (!platform_sp->IsCompatibleArchitecture(arch))
144 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
145 }
146 }
147 else if (arch.IsValid())
148 {
149 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
150 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000151
Greg Clayton70512312012-05-08 01:45:38 +0000152 if (!platform_sp)
153 platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
154
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000155 if (!arch.IsValid())
156 arch = specified_arch;
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000157
Greg Claytona0ca6602012-10-18 16:33:33 +0000158 FileSpec file (user_exe_path, false);
Greg Clayton82d79292012-10-25 22:45:35 +0000159 bool user_exe_path_is_bundle = false;
160 char resolved_bundle_exe_path[PATH_MAX];
161 resolved_bundle_exe_path[0] = '\0';
Greg Claytone996fd32011-03-08 22:40:15 +0000162 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000163 {
Greg Clayton82d79292012-10-25 22:45:35 +0000164 if (file.GetFileType() == FileSpec::eFileTypeDirectory)
165 user_exe_path_is_bundle = true;
166
Greg Claytona0ca6602012-10-18 16:33:33 +0000167 if (file.IsRelativeToCurrentWorkingDirectory())
168 {
169 // Ignore paths that start with "./" and "../"
170 if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') ||
171 (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/')))
172 {
173 char cwd[PATH_MAX];
174 if (getcwd (cwd, sizeof(cwd)))
175 {
176 std::string cwd_user_exe_path (cwd);
177 cwd_user_exe_path += '/';
178 cwd_user_exe_path += user_exe_path;
179 file.SetFile(cwd_user_exe_path.c_str(), false);
180 }
181 }
182 }
183
Jim Ingham5aee1622010-08-09 23:31:02 +0000184 ModuleSP exe_module_sp;
Greg Claytone996fd32011-03-08 22:40:15 +0000185 if (platform_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000186 {
187 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
Greg Clayton70512312012-05-08 01:45:38 +0000188 error = platform_sp->ResolveExecutable (file,
189 arch,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000190 exe_module_sp,
191 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
192 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193
Greg Claytone996fd32011-03-08 22:40:15 +0000194 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000196 if (exe_module_sp->GetObjectFile() == NULL)
197 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000198 if (arch.IsValid())
199 {
200 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
201 file.GetDirectory().AsCString(),
202 file.GetDirectory() ? "/" : "",
203 file.GetFilename().AsCString(),
Greg Clayton64195a22011-02-23 00:35:02 +0000204 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000205 }
206 else
207 {
208 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
209 file.GetDirectory().AsCString(),
210 file.GetDirectory() ? "/" : "",
211 file.GetFilename().AsCString());
212 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000213 return error;
214 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000215 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +0000216 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Greg Clayton82d79292012-10-25 22:45:35 +0000217 if (user_exe_path_is_bundle)
218 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000220 }
Greg Claytone996fd32011-03-08 22:40:15 +0000221 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000222 {
Greg Claytone996fd32011-03-08 22:40:15 +0000223 // No file was specified, just create an empty target with any arch
224 // if a valid arch was specified
Greg Clayton32e0a752011-03-30 18:16:51 +0000225 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000226 }
227
228 if (target_sp)
229 {
Greg Clayton82d79292012-10-25 22:45:35 +0000230 // Set argv0 with what the user typed, unless the user specified a
231 // directory. If the user specified a directory, then it is probably a
232 // bundle that was resolved and we need to use the resolved bundle path
Greg Claytona0ca6602012-10-18 16:33:33 +0000233 if (user_exe_path)
234 {
235 // Use exactly what the user typed as the first argument when we exec or posix_spawn
Greg Clayton82d79292012-10-25 22:45:35 +0000236 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0])
237 {
238 target_sp->SetArg0 (resolved_bundle_exe_path);
239 }
240 else
241 {
242 // Just use what the user typed
243 target_sp->SetArg0 (user_exe_path);
244 }
Greg Claytona0ca6602012-10-18 16:33:33 +0000245 }
246 if (file.GetDirectory())
247 {
248 FileSpec file_dir;
249 file_dir.GetDirectory() = file.GetDirectory();
250 target_sp->GetExecutableSearchPaths ().Append (file_dir);
251 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000252 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000253 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000254 m_target_list.push_back(target_sp);
Greg Claytona0ca6602012-10-18 16:33:33 +0000255
256
Jim Ingham5aee1622010-08-09 23:31:02 +0000257 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259 return error;
260}
261
262bool
263TargetList::DeleteTarget (TargetSP &target_sp)
264{
265 Mutex::Locker locker(m_target_list_mutex);
266 collection::iterator pos, end = m_target_list.end();
267
268 for (pos = m_target_list.begin(); pos != end; ++pos)
269 {
270 if (pos->get() == target_sp.get())
271 {
272 m_target_list.erase(pos);
273 return true;
274 }
275 }
276 return false;
277}
278
279
280TargetSP
281TargetList::FindTargetWithExecutableAndArchitecture
282(
283 const FileSpec &exe_file_spec,
284 const ArchSpec *exe_arch_ptr
285) const
286{
287 Mutex::Locker locker (m_target_list_mutex);
288 TargetSP target_sp;
289 bool full_match = exe_file_spec.GetDirectory();
290
291 collection::const_iterator pos, end = m_target_list.end();
292 for (pos = m_target_list.begin(); pos != end; ++pos)
293 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000294 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000295
Greg Claytonaa149cb2011-08-11 02:48:45 +0000296 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000298 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000299 {
300 if (exe_arch_ptr)
301 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000302 if (*exe_arch_ptr != exe_module->GetArchitecture())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303 continue;
304 }
305 target_sp = *pos;
306 break;
307 }
308 }
309 }
310 return target_sp;
311}
312
313TargetSP
314TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
315{
316 Mutex::Locker locker(m_target_list_mutex);
317 TargetSP target_sp;
318 collection::const_iterator pos, end = m_target_list.end();
319 for (pos = m_target_list.begin(); pos != end; ++pos)
320 {
321 Process* process = (*pos)->GetProcessSP().get();
322 if (process && process->GetID() == pid)
323 {
324 target_sp = *pos;
325 break;
326 }
327 }
328 return target_sp;
329}
330
331
332TargetSP
333TargetList::FindTargetWithProcess (Process *process) const
334{
335 TargetSP target_sp;
336 if (process)
337 {
338 Mutex::Locker locker(m_target_list_mutex);
339 collection::const_iterator pos, end = m_target_list.end();
340 for (pos = m_target_list.begin(); pos != end; ++pos)
341 {
342 if (process == (*pos)->GetProcessSP().get())
343 {
344 target_sp = *pos;
345 break;
346 }
347 }
348 }
349 return target_sp;
350}
351
352TargetSP
353TargetList::GetTargetSP (Target *target) const
354{
355 TargetSP target_sp;
356 if (target)
357 {
358 Mutex::Locker locker(m_target_list_mutex);
359 collection::const_iterator pos, end = m_target_list.end();
360 for (pos = m_target_list.begin(); pos != end; ++pos)
361 {
362 if (target == (*pos).get())
363 {
364 target_sp = *pos;
365 break;
366 }
367 }
368 }
369 return target_sp;
370}
371
372uint32_t
373TargetList::SendAsyncInterrupt (lldb::pid_t pid)
374{
375 uint32_t num_async_interrupts_sent = 0;
376
377 if (pid != LLDB_INVALID_PROCESS_ID)
378 {
379 TargetSP target_sp(FindTargetWithProcessID (pid));
380 if (target_sp.get())
381 {
382 Process* process = target_sp->GetProcessSP().get();
383 if (process)
384 {
Jim Inghamcfc09352012-07-27 23:57:19 +0000385 process->SendAsyncInterrupt();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386 ++num_async_interrupts_sent;
387 }
388 }
389 }
390 else
391 {
392 // We don't have a valid pid to broadcast to, so broadcast to the target
393 // list's async broadcaster...
394 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
395 }
396
397 return num_async_interrupts_sent;
398}
399
400uint32_t
401TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
402{
403 uint32_t num_signals_sent = 0;
404 Process *process = NULL;
405 if (pid == LLDB_INVALID_PROCESS_ID)
406 {
407 // Signal all processes with signal
408 Mutex::Locker locker(m_target_list_mutex);
409 collection::iterator pos, end = m_target_list.end();
410 for (pos = m_target_list.begin(); pos != end; ++pos)
411 {
412 process = (*pos)->GetProcessSP().get();
413 if (process)
414 {
415 if (process->IsAlive())
416 {
417 ++num_signals_sent;
418 process->Signal (signo);
419 }
420 }
421 }
422 }
423 else
424 {
425 // Signal a specific process with signal
426 TargetSP target_sp(FindTargetWithProcessID (pid));
427 if (target_sp.get())
428 {
429 process = target_sp->GetProcessSP().get();
430 if (process)
431 {
432 if (process->IsAlive())
433 {
434 ++num_signals_sent;
435 process->Signal (signo);
436 }
437 }
438 }
439 }
440 return num_signals_sent;
441}
442
443int
444TargetList::GetNumTargets () const
445{
446 Mutex::Locker locker (m_target_list_mutex);
447 return m_target_list.size();
448}
449
450lldb::TargetSP
451TargetList::GetTargetAtIndex (uint32_t idx) const
452{
453 TargetSP target_sp;
454 Mutex::Locker locker (m_target_list_mutex);
455 if (idx < m_target_list.size())
456 target_sp = m_target_list[idx];
457 return target_sp;
458}
459
460uint32_t
Jim Ingham8499e1a2012-05-08 23:06:07 +0000461TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
462{
463 Mutex::Locker locker (m_target_list_mutex);
464 size_t num_targets = m_target_list.size();
465 for (size_t idx = 0; idx < num_targets; idx++)
466 {
467 if (target_sp == m_target_list[idx])
468 return idx;
469 }
470 return UINT32_MAX;
471}
472
473uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000474TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475{
476 Mutex::Locker locker (m_target_list_mutex);
477 collection::const_iterator pos,
478 begin = m_target_list.begin(),
479 end = m_target_list.end();
480 for (pos = begin; pos != end; ++pos)
481 {
482 if (pos->get() == target)
483 {
Jim Ingham2976d002010-08-26 21:32:51 +0000484 m_selected_target_idx = std::distance (begin, pos);
485 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486 }
487 }
Jim Ingham2976d002010-08-26 21:32:51 +0000488 m_selected_target_idx = 0;
489 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490}
491
492lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000493TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494{
495 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000496 if (m_selected_target_idx >= m_target_list.size())
497 m_selected_target_idx = 0;
498 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499}