blob: d9879139dc5ff3096d2952112da87956845d917f [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 Claytoncac9c5f2011-09-24 00:52:29 +000071 ArchSpec arch;
72
73 if (triple_cstr)
74 {
75 arch.SetTriple(triple_cstr, platform_sp.get());
76 if (!arch.IsValid())
77 {
Greg Clayton86edbf42011-10-26 00:56:27 +000078 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
Greg Claytoncac9c5f2011-09-24 00:52:29 +000079 return error;
80 }
81 }
Greg Claytonb3a40ba2012-03-20 18:34:04 +000082
83 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,
92 error);
93 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
104 if (arch.IsValid() && !platform_sp->IsCompatibleWithArchitecture(arch))
105 {
106 platform_sp = Platform::GetPlatformForArchitecture(arch);
107 }
108 }
109
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000110 error = TargetList::CreateTarget (debugger,
111 file,
112 arch,
113 get_dependent_files,
114 platform_sp,
115 target_sp);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000116
117 if (target_sp)
118 {
119 if (file.GetDirectory())
120 {
121 FileSpec file_dir;
122 file_dir.GetDirectory() = file.GetDirectory();
123 target_sp->GetExecutableSearchPaths ().Append (file_dir);
124 }
125 }
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000126 return error;
127}
128
129Error
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000130TargetList::CreateTarget
131(
Greg Clayton66111032010-06-23 01:19:29 +0000132 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133 const FileSpec& file,
134 const ArchSpec& arch,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135 bool get_dependent_files,
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000136 PlatformSP &platform_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137 TargetSP &target_sp
138)
139{
140 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytone996fd32011-03-08 22:40:15 +0000141 "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000142 file.GetDirectory().AsCString(),
143 file.GetFilename().AsCString(),
Greg Claytone996fd32011-03-08 22:40:15 +0000144 arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000145 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000146
Jim Ingham5aee1622010-08-09 23:31:02 +0000147
Greg Claytone996fd32011-03-08 22:40:15 +0000148 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000149 {
150 ModuleSP exe_module_sp;
151 FileSpec resolved_file(file);
Caroline Tice428a9a52010-09-10 04:48:55 +0000152
Greg Claytone996fd32011-03-08 22:40:15 +0000153 if (platform_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000154 {
155 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
156 error = platform_sp->ResolveExecutable (file, arch,
157 exe_module_sp,
158 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
Greg Claytonb3a40ba2012-03-20 18:34:04 +0000159
160 if (exe_module_sp)
161 {
162 const ArchSpec &arch = exe_module_sp->GetArchitecture();
163 if (arch.IsValid() && !platform_sp->IsCompatibleWithArchitecture(arch))
164 platform_sp = Platform::GetPlatformForArchitecture(arch);
165 }
Greg Claytonc859e2d2012-02-13 23:10:39 +0000166 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167
Greg Claytone996fd32011-03-08 22:40:15 +0000168 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000169 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000170 if (exe_module_sp->GetObjectFile() == NULL)
171 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000172 if (arch.IsValid())
173 {
174 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
175 file.GetDirectory().AsCString(),
176 file.GetDirectory() ? "/" : "",
177 file.GetFilename().AsCString(),
Greg Clayton64195a22011-02-23 00:35:02 +0000178 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000179 }
180 else
181 {
182 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
183 file.GetDirectory().AsCString(),
184 file.GetDirectory() ? "/" : "",
185 file.GetFilename().AsCString());
186 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000187 return error;
188 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000189 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +0000190 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000192 }
Greg Claytone996fd32011-03-08 22:40:15 +0000193 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000194 {
Greg Claytone996fd32011-03-08 22:40:15 +0000195 // No file was specified, just create an empty target with any arch
196 // if a valid arch was specified
Greg Clayton32e0a752011-03-30 18:16:51 +0000197 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000198 }
199
200 if (target_sp)
201 {
202 target_sp->UpdateInstanceName();
203
Jim Ingham5aee1622010-08-09 23:31:02 +0000204 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000205 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000206 m_target_list.push_back(target_sp);
207 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209 return error;
210}
211
212bool
213TargetList::DeleteTarget (TargetSP &target_sp)
214{
215 Mutex::Locker locker(m_target_list_mutex);
216 collection::iterator pos, end = m_target_list.end();
217
218 for (pos = m_target_list.begin(); pos != end; ++pos)
219 {
220 if (pos->get() == target_sp.get())
221 {
222 m_target_list.erase(pos);
223 return true;
224 }
225 }
226 return false;
227}
228
229
230TargetSP
231TargetList::FindTargetWithExecutableAndArchitecture
232(
233 const FileSpec &exe_file_spec,
234 const ArchSpec *exe_arch_ptr
235) const
236{
237 Mutex::Locker locker (m_target_list_mutex);
238 TargetSP target_sp;
239 bool full_match = exe_file_spec.GetDirectory();
240
241 collection::const_iterator pos, end = m_target_list.end();
242 for (pos = m_target_list.begin(); pos != end; ++pos)
243 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000244 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245
Greg Claytonaa149cb2011-08-11 02:48:45 +0000246 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000248 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249 {
250 if (exe_arch_ptr)
251 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000252 if (*exe_arch_ptr != exe_module->GetArchitecture())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000253 continue;
254 }
255 target_sp = *pos;
256 break;
257 }
258 }
259 }
260 return target_sp;
261}
262
263TargetSP
264TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
265{
266 Mutex::Locker locker(m_target_list_mutex);
267 TargetSP target_sp;
268 collection::const_iterator pos, end = m_target_list.end();
269 for (pos = m_target_list.begin(); pos != end; ++pos)
270 {
271 Process* process = (*pos)->GetProcessSP().get();
272 if (process && process->GetID() == pid)
273 {
274 target_sp = *pos;
275 break;
276 }
277 }
278 return target_sp;
279}
280
281
282TargetSP
283TargetList::FindTargetWithProcess (Process *process) const
284{
285 TargetSP target_sp;
286 if (process)
287 {
288 Mutex::Locker locker(m_target_list_mutex);
289 collection::const_iterator pos, end = m_target_list.end();
290 for (pos = m_target_list.begin(); pos != end; ++pos)
291 {
292 if (process == (*pos)->GetProcessSP().get())
293 {
294 target_sp = *pos;
295 break;
296 }
297 }
298 }
299 return target_sp;
300}
301
302TargetSP
303TargetList::GetTargetSP (Target *target) const
304{
305 TargetSP target_sp;
306 if (target)
307 {
308 Mutex::Locker locker(m_target_list_mutex);
309 collection::const_iterator pos, end = m_target_list.end();
310 for (pos = m_target_list.begin(); pos != end; ++pos)
311 {
312 if (target == (*pos).get())
313 {
314 target_sp = *pos;
315 break;
316 }
317 }
318 }
319 return target_sp;
320}
321
322uint32_t
323TargetList::SendAsyncInterrupt (lldb::pid_t pid)
324{
325 uint32_t num_async_interrupts_sent = 0;
326
327 if (pid != LLDB_INVALID_PROCESS_ID)
328 {
329 TargetSP target_sp(FindTargetWithProcessID (pid));
330 if (target_sp.get())
331 {
332 Process* process = target_sp->GetProcessSP().get();
333 if (process)
334 {
335 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
336 ++num_async_interrupts_sent;
337 }
338 }
339 }
340 else
341 {
342 // We don't have a valid pid to broadcast to, so broadcast to the target
343 // list's async broadcaster...
344 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
345 }
346
347 return num_async_interrupts_sent;
348}
349
350uint32_t
351TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
352{
353 uint32_t num_signals_sent = 0;
354 Process *process = NULL;
355 if (pid == LLDB_INVALID_PROCESS_ID)
356 {
357 // Signal all processes with signal
358 Mutex::Locker locker(m_target_list_mutex);
359 collection::iterator pos, end = m_target_list.end();
360 for (pos = m_target_list.begin(); pos != end; ++pos)
361 {
362 process = (*pos)->GetProcessSP().get();
363 if (process)
364 {
365 if (process->IsAlive())
366 {
367 ++num_signals_sent;
368 process->Signal (signo);
369 }
370 }
371 }
372 }
373 else
374 {
375 // Signal a specific process with signal
376 TargetSP target_sp(FindTargetWithProcessID (pid));
377 if (target_sp.get())
378 {
379 process = target_sp->GetProcessSP().get();
380 if (process)
381 {
382 if (process->IsAlive())
383 {
384 ++num_signals_sent;
385 process->Signal (signo);
386 }
387 }
388 }
389 }
390 return num_signals_sent;
391}
392
393int
394TargetList::GetNumTargets () const
395{
396 Mutex::Locker locker (m_target_list_mutex);
397 return m_target_list.size();
398}
399
400lldb::TargetSP
401TargetList::GetTargetAtIndex (uint32_t idx) const
402{
403 TargetSP target_sp;
404 Mutex::Locker locker (m_target_list_mutex);
405 if (idx < m_target_list.size())
406 target_sp = m_target_list[idx];
407 return target_sp;
408}
409
410uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000411TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000412{
413 Mutex::Locker locker (m_target_list_mutex);
414 collection::const_iterator pos,
415 begin = m_target_list.begin(),
416 end = m_target_list.end();
417 for (pos = begin; pos != end; ++pos)
418 {
419 if (pos->get() == target)
420 {
Jim Ingham2976d002010-08-26 21:32:51 +0000421 m_selected_target_idx = std::distance (begin, pos);
422 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000423 }
424 }
Jim Ingham2976d002010-08-26 21:32:51 +0000425 m_selected_target_idx = 0;
426 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427}
428
429lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000430TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431{
432 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000433 if (m_selected_target_idx >= m_target_list.size())
434 m_selected_target_idx = 0;
435 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000436}