blob: 3f24dd602268931d9dd94c6f0dcdecb314c47388 [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,
60 const FileSpec& file,
61 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,
115 file,
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);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000120
121 if (target_sp)
122 {
123 if (file.GetDirectory())
124 {
125 FileSpec file_dir;
126 file_dir.GetDirectory() = file.GetDirectory();
127 target_sp->GetExecutableSearchPaths ().Append (file_dir);
128 }
129 }
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000130 return error;
131}
132
133Error
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000134TargetList::CreateTarget
135(
Greg Clayton66111032010-06-23 01:19:29 +0000136 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137 const FileSpec& file,
Greg Clayton70512312012-05-08 01:45:38 +0000138 const ArchSpec& specified_arch,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000139 bool get_dependent_files,
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000140 PlatformSP &platform_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141 TargetSP &target_sp
142)
143{
144 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytone996fd32011-03-08 22:40:15 +0000145 "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146 file.GetDirectory().AsCString(),
147 file.GetFilename().AsCString(),
Greg Clayton70512312012-05-08 01:45:38 +0000148 specified_arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000149 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000150
Greg Clayton70512312012-05-08 01:45:38 +0000151 ArchSpec arch(specified_arch);
152
153 if (platform_sp)
154 {
155 if (arch.IsValid())
156 {
157 if (!platform_sp->IsCompatibleArchitecture(arch))
158 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
159 }
160 }
161 else if (arch.IsValid())
162 {
163 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
164 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000165
Greg Clayton70512312012-05-08 01:45:38 +0000166 if (!platform_sp)
167 platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
168
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000169 if (!arch.IsValid())
170 arch = specified_arch;
171
172
Greg Claytone996fd32011-03-08 22:40:15 +0000173 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000174 {
175 ModuleSP exe_module_sp;
176 FileSpec resolved_file(file);
Greg Claytone996fd32011-03-08 22:40:15 +0000177 if (platform_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000178 {
179 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
Greg Clayton70512312012-05-08 01:45:38 +0000180 error = platform_sp->ResolveExecutable (file,
181 arch,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000182 exe_module_sp,
183 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
184 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000185
Greg Claytone996fd32011-03-08 22:40:15 +0000186 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000188 if (exe_module_sp->GetObjectFile() == NULL)
189 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000190 if (arch.IsValid())
191 {
192 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
193 file.GetDirectory().AsCString(),
194 file.GetDirectory() ? "/" : "",
195 file.GetFilename().AsCString(),
Greg Clayton64195a22011-02-23 00:35:02 +0000196 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000197 }
198 else
199 {
200 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
201 file.GetDirectory().AsCString(),
202 file.GetDirectory() ? "/" : "",
203 file.GetFilename().AsCString());
204 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000205 return error;
206 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000207 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +0000208 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000210 }
Greg Claytone996fd32011-03-08 22:40:15 +0000211 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000212 {
Greg Claytone996fd32011-03-08 22:40:15 +0000213 // No file was specified, just create an empty target with any arch
214 // if a valid arch was specified
Greg Clayton32e0a752011-03-30 18:16:51 +0000215 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000216 }
217
218 if (target_sp)
219 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000220 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000221 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000222 m_target_list.push_back(target_sp);
223 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225 return error;
226}
227
228bool
229TargetList::DeleteTarget (TargetSP &target_sp)
230{
231 Mutex::Locker locker(m_target_list_mutex);
232 collection::iterator pos, end = m_target_list.end();
233
234 for (pos = m_target_list.begin(); pos != end; ++pos)
235 {
236 if (pos->get() == target_sp.get())
237 {
238 m_target_list.erase(pos);
239 return true;
240 }
241 }
242 return false;
243}
244
245
246TargetSP
247TargetList::FindTargetWithExecutableAndArchitecture
248(
249 const FileSpec &exe_file_spec,
250 const ArchSpec *exe_arch_ptr
251) const
252{
253 Mutex::Locker locker (m_target_list_mutex);
254 TargetSP target_sp;
255 bool full_match = exe_file_spec.GetDirectory();
256
257 collection::const_iterator pos, end = m_target_list.end();
258 for (pos = m_target_list.begin(); pos != end; ++pos)
259 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000260 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000261
Greg Claytonaa149cb2011-08-11 02:48:45 +0000262 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000264 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265 {
266 if (exe_arch_ptr)
267 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000268 if (*exe_arch_ptr != exe_module->GetArchitecture())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269 continue;
270 }
271 target_sp = *pos;
272 break;
273 }
274 }
275 }
276 return target_sp;
277}
278
279TargetSP
280TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
281{
282 Mutex::Locker locker(m_target_list_mutex);
283 TargetSP target_sp;
284 collection::const_iterator pos, end = m_target_list.end();
285 for (pos = m_target_list.begin(); pos != end; ++pos)
286 {
287 Process* process = (*pos)->GetProcessSP().get();
288 if (process && process->GetID() == pid)
289 {
290 target_sp = *pos;
291 break;
292 }
293 }
294 return target_sp;
295}
296
297
298TargetSP
299TargetList::FindTargetWithProcess (Process *process) const
300{
301 TargetSP target_sp;
302 if (process)
303 {
304 Mutex::Locker locker(m_target_list_mutex);
305 collection::const_iterator pos, end = m_target_list.end();
306 for (pos = m_target_list.begin(); pos != end; ++pos)
307 {
308 if (process == (*pos)->GetProcessSP().get())
309 {
310 target_sp = *pos;
311 break;
312 }
313 }
314 }
315 return target_sp;
316}
317
318TargetSP
319TargetList::GetTargetSP (Target *target) const
320{
321 TargetSP target_sp;
322 if (target)
323 {
324 Mutex::Locker locker(m_target_list_mutex);
325 collection::const_iterator pos, end = m_target_list.end();
326 for (pos = m_target_list.begin(); pos != end; ++pos)
327 {
328 if (target == (*pos).get())
329 {
330 target_sp = *pos;
331 break;
332 }
333 }
334 }
335 return target_sp;
336}
337
338uint32_t
339TargetList::SendAsyncInterrupt (lldb::pid_t pid)
340{
341 uint32_t num_async_interrupts_sent = 0;
342
343 if (pid != LLDB_INVALID_PROCESS_ID)
344 {
345 TargetSP target_sp(FindTargetWithProcessID (pid));
346 if (target_sp.get())
347 {
348 Process* process = target_sp->GetProcessSP().get();
349 if (process)
350 {
Jim Inghamcfc09352012-07-27 23:57:19 +0000351 process->SendAsyncInterrupt();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352 ++num_async_interrupts_sent;
353 }
354 }
355 }
356 else
357 {
358 // We don't have a valid pid to broadcast to, so broadcast to the target
359 // list's async broadcaster...
360 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
361 }
362
363 return num_async_interrupts_sent;
364}
365
366uint32_t
367TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
368{
369 uint32_t num_signals_sent = 0;
370 Process *process = NULL;
371 if (pid == LLDB_INVALID_PROCESS_ID)
372 {
373 // Signal all processes with signal
374 Mutex::Locker locker(m_target_list_mutex);
375 collection::iterator pos, end = m_target_list.end();
376 for (pos = m_target_list.begin(); pos != end; ++pos)
377 {
378 process = (*pos)->GetProcessSP().get();
379 if (process)
380 {
381 if (process->IsAlive())
382 {
383 ++num_signals_sent;
384 process->Signal (signo);
385 }
386 }
387 }
388 }
389 else
390 {
391 // Signal a specific process with signal
392 TargetSP target_sp(FindTargetWithProcessID (pid));
393 if (target_sp.get())
394 {
395 process = target_sp->GetProcessSP().get();
396 if (process)
397 {
398 if (process->IsAlive())
399 {
400 ++num_signals_sent;
401 process->Signal (signo);
402 }
403 }
404 }
405 }
406 return num_signals_sent;
407}
408
409int
410TargetList::GetNumTargets () const
411{
412 Mutex::Locker locker (m_target_list_mutex);
413 return m_target_list.size();
414}
415
416lldb::TargetSP
417TargetList::GetTargetAtIndex (uint32_t idx) const
418{
419 TargetSP target_sp;
420 Mutex::Locker locker (m_target_list_mutex);
421 if (idx < m_target_list.size())
422 target_sp = m_target_list[idx];
423 return target_sp;
424}
425
426uint32_t
Jim Ingham8499e1a2012-05-08 23:06:07 +0000427TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
428{
429 Mutex::Locker locker (m_target_list_mutex);
430 size_t num_targets = m_target_list.size();
431 for (size_t idx = 0; idx < num_targets; idx++)
432 {
433 if (target_sp == m_target_list[idx])
434 return idx;
435 }
436 return UINT32_MAX;
437}
438
439uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000440TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441{
442 Mutex::Locker locker (m_target_list_mutex);
443 collection::const_iterator pos,
444 begin = m_target_list.begin(),
445 end = m_target_list.end();
446 for (pos = begin; pos != end; ++pos)
447 {
448 if (pos->get() == target)
449 {
Jim Ingham2976d002010-08-26 21:32:51 +0000450 m_selected_target_idx = std::distance (begin, pos);
451 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000452 }
453 }
Jim Ingham2976d002010-08-26 21:32:51 +0000454 m_selected_target_idx = 0;
455 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456}
457
458lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000459TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000460{
461 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000462 if (m_selected_target_idx >= m_target_list.size())
463 m_selected_target_idx = 0;
464 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465}