blob: 3ec4b08c1905132ad4c0a338c983fd7add366441 [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 Claytone996fd32011-03-08 22:40:15 +0000168 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000169 {
170 ModuleSP exe_module_sp;
171 FileSpec resolved_file(file);
Greg Claytone996fd32011-03-08 22:40:15 +0000172 if (platform_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000173 {
174 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
Greg Clayton70512312012-05-08 01:45:38 +0000175 error = platform_sp->ResolveExecutable (file,
176 arch,
Greg Claytonc859e2d2012-02-13 23:10:39 +0000177 exe_module_sp,
178 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
179 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180
Greg Claytone996fd32011-03-08 22:40:15 +0000181 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000183 if (exe_module_sp->GetObjectFile() == NULL)
184 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000185 if (arch.IsValid())
186 {
187 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
188 file.GetDirectory().AsCString(),
189 file.GetDirectory() ? "/" : "",
190 file.GetFilename().AsCString(),
Greg Clayton64195a22011-02-23 00:35:02 +0000191 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000192 }
193 else
194 {
195 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
196 file.GetDirectory().AsCString(),
197 file.GetDirectory() ? "/" : "",
198 file.GetFilename().AsCString());
199 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000200 return error;
201 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000202 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +0000203 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000205 }
Greg Claytone996fd32011-03-08 22:40:15 +0000206 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000207 {
Greg Claytone996fd32011-03-08 22:40:15 +0000208 // No file was specified, just create an empty target with any arch
209 // if a valid arch was specified
Greg Clayton32e0a752011-03-30 18:16:51 +0000210 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000211 }
212
213 if (target_sp)
214 {
215 target_sp->UpdateInstanceName();
216
Jim Ingham5aee1622010-08-09 23:31:02 +0000217 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000218 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000219 m_target_list.push_back(target_sp);
220 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000222 return error;
223}
224
225bool
226TargetList::DeleteTarget (TargetSP &target_sp)
227{
228 Mutex::Locker locker(m_target_list_mutex);
229 collection::iterator pos, end = m_target_list.end();
230
231 for (pos = m_target_list.begin(); pos != end; ++pos)
232 {
233 if (pos->get() == target_sp.get())
234 {
235 m_target_list.erase(pos);
236 return true;
237 }
238 }
239 return false;
240}
241
242
243TargetSP
244TargetList::FindTargetWithExecutableAndArchitecture
245(
246 const FileSpec &exe_file_spec,
247 const ArchSpec *exe_arch_ptr
248) const
249{
250 Mutex::Locker locker (m_target_list_mutex);
251 TargetSP target_sp;
252 bool full_match = exe_file_spec.GetDirectory();
253
254 collection::const_iterator pos, end = m_target_list.end();
255 for (pos = m_target_list.begin(); pos != end; ++pos)
256 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000257 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258
Greg Claytonaa149cb2011-08-11 02:48:45 +0000259 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000260 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000261 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262 {
263 if (exe_arch_ptr)
264 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000265 if (*exe_arch_ptr != exe_module->GetArchitecture())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266 continue;
267 }
268 target_sp = *pos;
269 break;
270 }
271 }
272 }
273 return target_sp;
274}
275
276TargetSP
277TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
278{
279 Mutex::Locker locker(m_target_list_mutex);
280 TargetSP target_sp;
281 collection::const_iterator pos, end = m_target_list.end();
282 for (pos = m_target_list.begin(); pos != end; ++pos)
283 {
284 Process* process = (*pos)->GetProcessSP().get();
285 if (process && process->GetID() == pid)
286 {
287 target_sp = *pos;
288 break;
289 }
290 }
291 return target_sp;
292}
293
294
295TargetSP
296TargetList::FindTargetWithProcess (Process *process) const
297{
298 TargetSP target_sp;
299 if (process)
300 {
301 Mutex::Locker locker(m_target_list_mutex);
302 collection::const_iterator pos, end = m_target_list.end();
303 for (pos = m_target_list.begin(); pos != end; ++pos)
304 {
305 if (process == (*pos)->GetProcessSP().get())
306 {
307 target_sp = *pos;
308 break;
309 }
310 }
311 }
312 return target_sp;
313}
314
315TargetSP
316TargetList::GetTargetSP (Target *target) const
317{
318 TargetSP target_sp;
319 if (target)
320 {
321 Mutex::Locker locker(m_target_list_mutex);
322 collection::const_iterator pos, end = m_target_list.end();
323 for (pos = m_target_list.begin(); pos != end; ++pos)
324 {
325 if (target == (*pos).get())
326 {
327 target_sp = *pos;
328 break;
329 }
330 }
331 }
332 return target_sp;
333}
334
335uint32_t
336TargetList::SendAsyncInterrupt (lldb::pid_t pid)
337{
338 uint32_t num_async_interrupts_sent = 0;
339
340 if (pid != LLDB_INVALID_PROCESS_ID)
341 {
342 TargetSP target_sp(FindTargetWithProcessID (pid));
343 if (target_sp.get())
344 {
345 Process* process = target_sp->GetProcessSP().get();
346 if (process)
347 {
348 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
349 ++num_async_interrupts_sent;
350 }
351 }
352 }
353 else
354 {
355 // We don't have a valid pid to broadcast to, so broadcast to the target
356 // list's async broadcaster...
357 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
358 }
359
360 return num_async_interrupts_sent;
361}
362
363uint32_t
364TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
365{
366 uint32_t num_signals_sent = 0;
367 Process *process = NULL;
368 if (pid == LLDB_INVALID_PROCESS_ID)
369 {
370 // Signal all processes with signal
371 Mutex::Locker locker(m_target_list_mutex);
372 collection::iterator pos, end = m_target_list.end();
373 for (pos = m_target_list.begin(); pos != end; ++pos)
374 {
375 process = (*pos)->GetProcessSP().get();
376 if (process)
377 {
378 if (process->IsAlive())
379 {
380 ++num_signals_sent;
381 process->Signal (signo);
382 }
383 }
384 }
385 }
386 else
387 {
388 // Signal a specific process with signal
389 TargetSP target_sp(FindTargetWithProcessID (pid));
390 if (target_sp.get())
391 {
392 process = target_sp->GetProcessSP().get();
393 if (process)
394 {
395 if (process->IsAlive())
396 {
397 ++num_signals_sent;
398 process->Signal (signo);
399 }
400 }
401 }
402 }
403 return num_signals_sent;
404}
405
406int
407TargetList::GetNumTargets () const
408{
409 Mutex::Locker locker (m_target_list_mutex);
410 return m_target_list.size();
411}
412
413lldb::TargetSP
414TargetList::GetTargetAtIndex (uint32_t idx) const
415{
416 TargetSP target_sp;
417 Mutex::Locker locker (m_target_list_mutex);
418 if (idx < m_target_list.size())
419 target_sp = m_target_list[idx];
420 return target_sp;
421}
422
423uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000424TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425{
426 Mutex::Locker locker (m_target_list_mutex);
427 collection::const_iterator pos,
428 begin = m_target_list.begin(),
429 end = m_target_list.end();
430 for (pos = begin; pos != end; ++pos)
431 {
432 if (pos->get() == target)
433 {
Jim Ingham2976d002010-08-26 21:32:51 +0000434 m_selected_target_idx = std::distance (begin, pos);
435 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000436 }
437 }
Jim Ingham2976d002010-08-26 21:32:51 +0000438 m_selected_target_idx = 0;
439 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440}
441
442lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000443TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000444{
445 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000446 if (m_selected_target_idx >= m_target_list.size())
447 m_selected_target_idx = 0;
448 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000449}