blob: 34abd43e0a6a41aa17bea9d8c6d56c63b178c972 [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"
17#include "lldb/Core/State.h"
18#include "lldb/Core/Timer.h"
19#include "lldb/Host/Host.h"
Greg Claytonb3a40ba2012-03-20 18:34:04 +000020#include "lldb/Interpreter/CommandInterpreter.h"
Greg Claytoncac9c5f2011-09-24 00:52:29 +000021#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytone996fd32011-03-08 22:40:15 +000022#include "lldb/Target/Platform.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Target/Process.h"
24#include "lldb/Target/TargetList.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
Jim Ingham4bddaeb2012-02-16 06:50:00 +000029ConstString &
30TargetList::GetStaticBroadcasterClass ()
31{
32 static ConstString class_name ("lldb.targetList");
33 return class_name;
34}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
36//----------------------------------------------------------------------
37// TargetList constructor
38//----------------------------------------------------------------------
Jim Ingham4bddaeb2012-02-16 06:50:00 +000039TargetList::TargetList(Debugger &debugger) :
40 Broadcaster(&debugger, "TargetList"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041 m_target_list(),
42 m_target_list_mutex (Mutex::eMutexTypeRecursive),
Jim Ingham2976d002010-08-26 21:32:51 +000043 m_selected_target_idx (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044{
Jim Ingham4bddaeb2012-02-16 06:50:00 +000045 CheckInWithManager();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046}
47
48//----------------------------------------------------------------------
49// Destructor
50//----------------------------------------------------------------------
51TargetList::~TargetList()
52{
53 Mutex::Locker locker(m_target_list_mutex);
54 m_target_list.clear();
55}
56
57Error
Greg Claytoncac9c5f2011-09-24 00:52:29 +000058TargetList::CreateTarget (Debugger &debugger,
59 const FileSpec& file,
60 const char *triple_cstr,
61 bool get_dependent_files,
62 const OptionGroupPlatform *platform_options,
63 TargetSP &target_sp)
64{
65 Error error;
66 PlatformSP platform_sp;
Greg Claytoncac9c5f2011-09-24 00:52:29 +000067
Johnny Chencdc21d42012-01-05 01:26:01 +000068 // This is purposely left empty unless it is specified by triple_cstr.
69 // If not initialized via triple_cstr, then the currently selected platform
70 // will set the architecture correctly.
Greg Clayton70512312012-05-08 01:45:38 +000071 const ArchSpec arch(triple_cstr);
72 if (triple_cstr && triple_cstr[0])
Greg Claytoncac9c5f2011-09-24 00:52:29 +000073 {
Greg Claytoncac9c5f2011-09-24 00:52:29 +000074 if (!arch.IsValid())
75 {
Greg Clayton86edbf42011-10-26 00:56:27 +000076 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
Greg Claytoncac9c5f2011-09-24 00:52:29 +000077 return error;
78 }
79 }
Greg Claytonb3a40ba2012-03-20 18:34:04 +000080
Greg Clayton70512312012-05-08 01:45:38 +000081 ArchSpec platform_arch(arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +000082 CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
83 if (platform_options)
84 {
85 if (platform_options->PlatformWasSpecified ())
86 {
87 const bool select_platform = true;
88 platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
89 arch,
90 select_platform,
Greg Clayton70512312012-05-08 01:45:38 +000091 error,
92 platform_arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +000093 if (!platform_sp)
94 return error;
95 }
96 }
97
98 if (!platform_sp)
99 {
100 // Get the current platform and make sure it is compatible with the
101 // current architecture if we have a valid architecture.
102 platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
103
Greg Clayton70512312012-05-08 01:45:38 +0000104 if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, &platform_arch))
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000105 {
Greg Clayton70512312012-05-08 01:45:38 +0000106 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000107 }
108 }
Greg Clayton70512312012-05-08 01:45:38 +0000109
110 if (!platform_arch.IsValid())
111 platform_arch = arch;
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000112
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000113 error = TargetList::CreateTarget (debugger,
114 file,
Greg Clayton70512312012-05-08 01:45:38 +0000115 platform_arch,
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000116 get_dependent_files,
117 platform_sp,
118 target_sp);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000119
120 if (target_sp)
121 {
122 if (file.GetDirectory())
123 {
124 FileSpec file_dir;
125 file_dir.GetDirectory() = file.GetDirectory();
126 target_sp->GetExecutableSearchPaths ().Append (file_dir);
127 }
128 }
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000129 return error;
130}
131
132Error
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133TargetList::CreateTarget
134(
Greg Clayton66111032010-06-23 01:19:29 +0000135 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000136 const FileSpec& file,
Greg Clayton70512312012-05-08 01:45:38 +0000137 const ArchSpec& specified_arch,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000138 bool get_dependent_files,
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000139 PlatformSP &platform_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000140 TargetSP &target_sp
141)
142{
143 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytone996fd32011-03-08 22:40:15 +0000144 "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145 file.GetDirectory().AsCString(),
146 file.GetFilename().AsCString(),
Greg Clayton70512312012-05-08 01:45:38 +0000147 specified_arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000148 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000149
Greg Clayton70512312012-05-08 01:45:38 +0000150 ArchSpec arch(specified_arch);
151
152 if (platform_sp)
153 {
154 if (arch.IsValid())
155 {
156 if (!platform_sp->IsCompatibleArchitecture(arch))
157 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
158 }
159 }
160 else if (arch.IsValid())
161 {
162 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
163 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000164
Greg Clayton70512312012-05-08 01:45:38 +0000165 if (!platform_sp)
166 platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
167
Greg Clayton8ae50eb2012-06-05 21:17:09 +0000168 if (!arch.IsValid())
169 arch = specified_arch;
170
171
Greg Claytone996fd32011-03-08 22:40:15 +0000172 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000173 {
174 ModuleSP exe_module_sp;
175 FileSpec resolved_file(file);
Greg Claytone996fd32011-03-08 22:40:15 +0000176 if (platform_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000177 {
178 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
Greg Clayton70512312012-05-08 01:45:38 +0000179 error = platform_sp->ResolveExecutable (file,
180 arch,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000181 exe_module_sp,
182 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
183 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184
Greg Claytone996fd32011-03-08 22:40:15 +0000185 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000187 if (exe_module_sp->GetObjectFile() == NULL)
188 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000189 if (arch.IsValid())
190 {
191 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
192 file.GetDirectory().AsCString(),
193 file.GetDirectory() ? "/" : "",
194 file.GetFilename().AsCString(),
Greg Clayton64195a22011-02-23 00:35:02 +0000195 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000196 }
197 else
198 {
199 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
200 file.GetDirectory().AsCString(),
201 file.GetDirectory() ? "/" : "",
202 file.GetFilename().AsCString());
203 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000204 return error;
205 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000206 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +0000207 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000209 }
Greg Claytone996fd32011-03-08 22:40:15 +0000210 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000211 {
Greg Claytone996fd32011-03-08 22:40:15 +0000212 // No file was specified, just create an empty target with any arch
213 // if a valid arch was specified
Greg Clayton32e0a752011-03-30 18:16:51 +0000214 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000215 }
216
217 if (target_sp)
218 {
219 target_sp->UpdateInstanceName();
220
Jim Ingham5aee1622010-08-09 23:31:02 +0000221 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000222 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000223 m_target_list.push_back(target_sp);
224 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 return error;
227}
228
229bool
230TargetList::DeleteTarget (TargetSP &target_sp)
231{
232 Mutex::Locker locker(m_target_list_mutex);
233 collection::iterator pos, end = m_target_list.end();
234
235 for (pos = m_target_list.begin(); pos != end; ++pos)
236 {
237 if (pos->get() == target_sp.get())
238 {
239 m_target_list.erase(pos);
240 return true;
241 }
242 }
243 return false;
244}
245
246
247TargetSP
248TargetList::FindTargetWithExecutableAndArchitecture
249(
250 const FileSpec &exe_file_spec,
251 const ArchSpec *exe_arch_ptr
252) const
253{
254 Mutex::Locker locker (m_target_list_mutex);
255 TargetSP target_sp;
256 bool full_match = exe_file_spec.GetDirectory();
257
258 collection::const_iterator pos, end = m_target_list.end();
259 for (pos = m_target_list.begin(); pos != end; ++pos)
260 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000261 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262
Greg Claytonaa149cb2011-08-11 02:48:45 +0000263 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000265 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266 {
267 if (exe_arch_ptr)
268 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000269 if (*exe_arch_ptr != exe_module->GetArchitecture())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000270 continue;
271 }
272 target_sp = *pos;
273 break;
274 }
275 }
276 }
277 return target_sp;
278}
279
280TargetSP
281TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
282{
283 Mutex::Locker locker(m_target_list_mutex);
284 TargetSP target_sp;
285 collection::const_iterator pos, end = m_target_list.end();
286 for (pos = m_target_list.begin(); pos != end; ++pos)
287 {
288 Process* process = (*pos)->GetProcessSP().get();
289 if (process && process->GetID() == pid)
290 {
291 target_sp = *pos;
292 break;
293 }
294 }
295 return target_sp;
296}
297
298
299TargetSP
300TargetList::FindTargetWithProcess (Process *process) const
301{
302 TargetSP target_sp;
303 if (process)
304 {
305 Mutex::Locker locker(m_target_list_mutex);
306 collection::const_iterator pos, end = m_target_list.end();
307 for (pos = m_target_list.begin(); pos != end; ++pos)
308 {
309 if (process == (*pos)->GetProcessSP().get())
310 {
311 target_sp = *pos;
312 break;
313 }
314 }
315 }
316 return target_sp;
317}
318
319TargetSP
320TargetList::GetTargetSP (Target *target) const
321{
322 TargetSP target_sp;
323 if (target)
324 {
325 Mutex::Locker locker(m_target_list_mutex);
326 collection::const_iterator pos, end = m_target_list.end();
327 for (pos = m_target_list.begin(); pos != end; ++pos)
328 {
329 if (target == (*pos).get())
330 {
331 target_sp = *pos;
332 break;
333 }
334 }
335 }
336 return target_sp;
337}
338
339uint32_t
340TargetList::SendAsyncInterrupt (lldb::pid_t pid)
341{
342 uint32_t num_async_interrupts_sent = 0;
343
344 if (pid != LLDB_INVALID_PROCESS_ID)
345 {
346 TargetSP target_sp(FindTargetWithProcessID (pid));
347 if (target_sp.get())
348 {
349 Process* process = target_sp->GetProcessSP().get();
350 if (process)
351 {
352 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
353 ++num_async_interrupts_sent;
354 }
355 }
356 }
357 else
358 {
359 // We don't have a valid pid to broadcast to, so broadcast to the target
360 // list's async broadcaster...
361 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
362 }
363
364 return num_async_interrupts_sent;
365}
366
367uint32_t
368TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
369{
370 uint32_t num_signals_sent = 0;
371 Process *process = NULL;
372 if (pid == LLDB_INVALID_PROCESS_ID)
373 {
374 // Signal all processes with signal
375 Mutex::Locker locker(m_target_list_mutex);
376 collection::iterator pos, end = m_target_list.end();
377 for (pos = m_target_list.begin(); pos != end; ++pos)
378 {
379 process = (*pos)->GetProcessSP().get();
380 if (process)
381 {
382 if (process->IsAlive())
383 {
384 ++num_signals_sent;
385 process->Signal (signo);
386 }
387 }
388 }
389 }
390 else
391 {
392 // Signal a specific process with signal
393 TargetSP target_sp(FindTargetWithProcessID (pid));
394 if (target_sp.get())
395 {
396 process = target_sp->GetProcessSP().get();
397 if (process)
398 {
399 if (process->IsAlive())
400 {
401 ++num_signals_sent;
402 process->Signal (signo);
403 }
404 }
405 }
406 }
407 return num_signals_sent;
408}
409
410int
411TargetList::GetNumTargets () const
412{
413 Mutex::Locker locker (m_target_list_mutex);
414 return m_target_list.size();
415}
416
417lldb::TargetSP
418TargetList::GetTargetAtIndex (uint32_t idx) const
419{
420 TargetSP target_sp;
421 Mutex::Locker locker (m_target_list_mutex);
422 if (idx < m_target_list.size())
423 target_sp = m_target_list[idx];
424 return target_sp;
425}
426
427uint32_t
Jim Ingham8499e1a2012-05-08 23:06:07 +0000428TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const
429{
430 Mutex::Locker locker (m_target_list_mutex);
431 size_t num_targets = m_target_list.size();
432 for (size_t idx = 0; idx < num_targets; idx++)
433 {
434 if (target_sp == m_target_list[idx])
435 return idx;
436 }
437 return UINT32_MAX;
438}
439
440uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000441TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000442{
443 Mutex::Locker locker (m_target_list_mutex);
444 collection::const_iterator pos,
445 begin = m_target_list.begin(),
446 end = m_target_list.end();
447 for (pos = begin; pos != end; ++pos)
448 {
449 if (pos->get() == target)
450 {
Jim Ingham2976d002010-08-26 21:32:51 +0000451 m_selected_target_idx = std::distance (begin, pos);
452 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453 }
454 }
Jim Ingham2976d002010-08-26 21:32:51 +0000455 m_selected_target_idx = 0;
456 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000457}
458
459lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000460TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461{
462 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000463 if (m_selected_target_idx >= m_target_list.size())
464 m_selected_target_idx = 0;
465 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466}