blob: 38240e1231843bf2d8d8f700c2b38be5debee29f [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 Claytoncac9c5f2011-09-24 00:52:29 +000020#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytone996fd32011-03-08 22:40:15 +000021#include "lldb/Target/Platform.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Target/Process.h"
23#include "lldb/Target/TargetList.h"
24
25using namespace lldb;
26using namespace lldb_private;
27
Jim Ingham4bddaeb2012-02-16 06:50:00 +000028ConstString &
29TargetList::GetStaticBroadcasterClass ()
30{
31 static ConstString class_name ("lldb.targetList");
32 return class_name;
33}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034
35//----------------------------------------------------------------------
36// TargetList constructor
37//----------------------------------------------------------------------
Jim Ingham4bddaeb2012-02-16 06:50:00 +000038TargetList::TargetList(Debugger &debugger) :
39 Broadcaster(&debugger, "TargetList"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040 m_target_list(),
41 m_target_list_mutex (Mutex::eMutexTypeRecursive),
Jim Ingham2976d002010-08-26 21:32:51 +000042 m_selected_target_idx (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043{
Jim Ingham4bddaeb2012-02-16 06:50:00 +000044 CheckInWithManager();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045}
46
47//----------------------------------------------------------------------
48// Destructor
49//----------------------------------------------------------------------
50TargetList::~TargetList()
51{
52 Mutex::Locker locker(m_target_list_mutex);
53 m_target_list.clear();
54}
55
56Error
Greg Claytoncac9c5f2011-09-24 00:52:29 +000057TargetList::CreateTarget (Debugger &debugger,
58 const FileSpec& file,
59 const char *triple_cstr,
60 bool get_dependent_files,
61 const OptionGroupPlatform *platform_options,
62 TargetSP &target_sp)
63{
64 Error error;
65 PlatformSP platform_sp;
66 if (platform_options)
67 {
68 if (platform_options->PlatformWasSpecified ())
69 {
70 const bool select_platform = true;
71 platform_sp = platform_options->CreatePlatformWithOptions (debugger.GetCommandInterpreter(),
72 select_platform,
73 error);
74 if (!platform_sp)
75 return error;
76 }
77 }
78
79 if (!platform_sp)
80 platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
81
Johnny Chencdc21d42012-01-05 01:26:01 +000082 // This is purposely left empty unless it is specified by triple_cstr.
83 // If not initialized via triple_cstr, then the currently selected platform
84 // will set the architecture correctly.
Greg Claytoncac9c5f2011-09-24 00:52:29 +000085 ArchSpec arch;
86
87 if (triple_cstr)
88 {
89 arch.SetTriple(triple_cstr, platform_sp.get());
90 if (!arch.IsValid())
91 {
Greg Clayton86edbf42011-10-26 00:56:27 +000092 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
Greg Claytoncac9c5f2011-09-24 00:52:29 +000093 return error;
94 }
95 }
96 error = TargetList::CreateTarget (debugger,
97 file,
98 arch,
99 get_dependent_files,
100 platform_sp,
101 target_sp);
Greg Claytonc859e2d2012-02-13 23:10:39 +0000102
103 if (target_sp)
104 {
105 if (file.GetDirectory())
106 {
107 FileSpec file_dir;
108 file_dir.GetDirectory() = file.GetDirectory();
109 target_sp->GetExecutableSearchPaths ().Append (file_dir);
110 }
111 }
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000112 return error;
113}
114
115Error
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116TargetList::CreateTarget
117(
Greg Clayton66111032010-06-23 01:19:29 +0000118 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119 const FileSpec& file,
120 const ArchSpec& arch,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121 bool get_dependent_files,
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000122 const PlatformSP &platform_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123 TargetSP &target_sp
124)
125{
126 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytone996fd32011-03-08 22:40:15 +0000127 "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000128 file.GetDirectory().AsCString(),
129 file.GetFilename().AsCString(),
Greg Claytone996fd32011-03-08 22:40:15 +0000130 arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000131 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000132
Jim Ingham5aee1622010-08-09 23:31:02 +0000133
Greg Claytone996fd32011-03-08 22:40:15 +0000134 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000135 {
136 ModuleSP exe_module_sp;
137 FileSpec resolved_file(file);
Caroline Tice428a9a52010-09-10 04:48:55 +0000138
Greg Claytone996fd32011-03-08 22:40:15 +0000139 if (platform_sp)
Greg Claytonc859e2d2012-02-13 23:10:39 +0000140 {
141 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
142 error = platform_sp->ResolveExecutable (file, arch,
143 exe_module_sp,
144 executable_search_paths.GetSize() ? &executable_search_paths : NULL);
145 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146
Greg Claytone996fd32011-03-08 22:40:15 +0000147 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000149 if (exe_module_sp->GetObjectFile() == NULL)
150 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000151 if (arch.IsValid())
152 {
153 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
154 file.GetDirectory().AsCString(),
155 file.GetDirectory() ? "/" : "",
156 file.GetFilename().AsCString(),
Greg Clayton64195a22011-02-23 00:35:02 +0000157 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000158 }
159 else
160 {
161 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
162 file.GetDirectory().AsCString(),
163 file.GetDirectory() ? "/" : "",
164 file.GetFilename().AsCString());
165 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000166 return error;
167 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000168 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +0000169 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000171 }
Greg Claytone996fd32011-03-08 22:40:15 +0000172 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000173 {
Greg Claytone996fd32011-03-08 22:40:15 +0000174 // No file was specified, just create an empty target with any arch
175 // if a valid arch was specified
Greg Clayton32e0a752011-03-30 18:16:51 +0000176 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000177 }
178
179 if (target_sp)
180 {
181 target_sp->UpdateInstanceName();
182
Jim Ingham5aee1622010-08-09 23:31:02 +0000183 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000184 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000185 m_target_list.push_back(target_sp);
186 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000188 return error;
189}
190
191bool
192TargetList::DeleteTarget (TargetSP &target_sp)
193{
194 Mutex::Locker locker(m_target_list_mutex);
195 collection::iterator pos, end = m_target_list.end();
196
197 for (pos = m_target_list.begin(); pos != end; ++pos)
198 {
199 if (pos->get() == target_sp.get())
200 {
201 m_target_list.erase(pos);
202 return true;
203 }
204 }
205 return false;
206}
207
208
209TargetSP
210TargetList::FindTargetWithExecutableAndArchitecture
211(
212 const FileSpec &exe_file_spec,
213 const ArchSpec *exe_arch_ptr
214) const
215{
216 Mutex::Locker locker (m_target_list_mutex);
217 TargetSP target_sp;
218 bool full_match = exe_file_spec.GetDirectory();
219
220 collection::const_iterator pos, end = m_target_list.end();
221 for (pos = m_target_list.begin(); pos != end; ++pos)
222 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000223 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224
Greg Claytonaa149cb2011-08-11 02:48:45 +0000225 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000227 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228 {
229 if (exe_arch_ptr)
230 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000231 if (*exe_arch_ptr != exe_module->GetArchitecture())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232 continue;
233 }
234 target_sp = *pos;
235 break;
236 }
237 }
238 }
239 return target_sp;
240}
241
242TargetSP
243TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
244{
245 Mutex::Locker locker(m_target_list_mutex);
246 TargetSP target_sp;
247 collection::const_iterator pos, end = m_target_list.end();
248 for (pos = m_target_list.begin(); pos != end; ++pos)
249 {
250 Process* process = (*pos)->GetProcessSP().get();
251 if (process && process->GetID() == pid)
252 {
253 target_sp = *pos;
254 break;
255 }
256 }
257 return target_sp;
258}
259
260
261TargetSP
262TargetList::FindTargetWithProcess (Process *process) const
263{
264 TargetSP target_sp;
265 if (process)
266 {
267 Mutex::Locker locker(m_target_list_mutex);
268 collection::const_iterator pos, end = m_target_list.end();
269 for (pos = m_target_list.begin(); pos != end; ++pos)
270 {
271 if (process == (*pos)->GetProcessSP().get())
272 {
273 target_sp = *pos;
274 break;
275 }
276 }
277 }
278 return target_sp;
279}
280
281TargetSP
282TargetList::GetTargetSP (Target *target) const
283{
284 TargetSP target_sp;
285 if (target)
286 {
287 Mutex::Locker locker(m_target_list_mutex);
288 collection::const_iterator pos, end = m_target_list.end();
289 for (pos = m_target_list.begin(); pos != end; ++pos)
290 {
291 if (target == (*pos).get())
292 {
293 target_sp = *pos;
294 break;
295 }
296 }
297 }
298 return target_sp;
299}
300
301uint32_t
302TargetList::SendAsyncInterrupt (lldb::pid_t pid)
303{
304 uint32_t num_async_interrupts_sent = 0;
305
306 if (pid != LLDB_INVALID_PROCESS_ID)
307 {
308 TargetSP target_sp(FindTargetWithProcessID (pid));
309 if (target_sp.get())
310 {
311 Process* process = target_sp->GetProcessSP().get();
312 if (process)
313 {
314 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
315 ++num_async_interrupts_sent;
316 }
317 }
318 }
319 else
320 {
321 // We don't have a valid pid to broadcast to, so broadcast to the target
322 // list's async broadcaster...
323 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
324 }
325
326 return num_async_interrupts_sent;
327}
328
329uint32_t
330TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
331{
332 uint32_t num_signals_sent = 0;
333 Process *process = NULL;
334 if (pid == LLDB_INVALID_PROCESS_ID)
335 {
336 // Signal all processes with signal
337 Mutex::Locker locker(m_target_list_mutex);
338 collection::iterator pos, end = m_target_list.end();
339 for (pos = m_target_list.begin(); pos != end; ++pos)
340 {
341 process = (*pos)->GetProcessSP().get();
342 if (process)
343 {
344 if (process->IsAlive())
345 {
346 ++num_signals_sent;
347 process->Signal (signo);
348 }
349 }
350 }
351 }
352 else
353 {
354 // Signal a specific process with signal
355 TargetSP target_sp(FindTargetWithProcessID (pid));
356 if (target_sp.get())
357 {
358 process = target_sp->GetProcessSP().get();
359 if (process)
360 {
361 if (process->IsAlive())
362 {
363 ++num_signals_sent;
364 process->Signal (signo);
365 }
366 }
367 }
368 }
369 return num_signals_sent;
370}
371
372int
373TargetList::GetNumTargets () const
374{
375 Mutex::Locker locker (m_target_list_mutex);
376 return m_target_list.size();
377}
378
379lldb::TargetSP
380TargetList::GetTargetAtIndex (uint32_t idx) const
381{
382 TargetSP target_sp;
383 Mutex::Locker locker (m_target_list_mutex);
384 if (idx < m_target_list.size())
385 target_sp = m_target_list[idx];
386 return target_sp;
387}
388
389uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000390TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391{
392 Mutex::Locker locker (m_target_list_mutex);
393 collection::const_iterator pos,
394 begin = m_target_list.begin(),
395 end = m_target_list.end();
396 for (pos = begin; pos != end; ++pos)
397 {
398 if (pos->get() == target)
399 {
Jim Ingham2976d002010-08-26 21:32:51 +0000400 m_selected_target_idx = std::distance (begin, pos);
401 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402 }
403 }
Jim Ingham2976d002010-08-26 21:32:51 +0000404 m_selected_target_idx = 0;
405 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406}
407
408lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000409TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410{
411 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000412 if (m_selected_target_idx >= m_target_list.size())
413 m_selected_target_idx = 0;
414 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000415}