blob: eec77fba062f8c1346ec2119c5ca391b677cb9e7 [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
28
29//----------------------------------------------------------------------
30// TargetList constructor
31//----------------------------------------------------------------------
32TargetList::TargetList() :
33 Broadcaster("TargetList"),
34 m_target_list(),
35 m_target_list_mutex (Mutex::eMutexTypeRecursive),
Jim Ingham2976d002010-08-26 21:32:51 +000036 m_selected_target_idx (0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037{
38}
39
40//----------------------------------------------------------------------
41// Destructor
42//----------------------------------------------------------------------
43TargetList::~TargetList()
44{
45 Mutex::Locker locker(m_target_list_mutex);
46 m_target_list.clear();
47}
48
49Error
Greg Claytoncac9c5f2011-09-24 00:52:29 +000050TargetList::CreateTarget (Debugger &debugger,
51 const FileSpec& file,
52 const char *triple_cstr,
53 bool get_dependent_files,
54 const OptionGroupPlatform *platform_options,
55 TargetSP &target_sp)
56{
57 Error error;
58 PlatformSP platform_sp;
59 if (platform_options)
60 {
61 if (platform_options->PlatformWasSpecified ())
62 {
63 const bool select_platform = true;
64 platform_sp = platform_options->CreatePlatformWithOptions (debugger.GetCommandInterpreter(),
65 select_platform,
66 error);
67 if (!platform_sp)
68 return error;
69 }
70 }
71
72 if (!platform_sp)
73 platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
74
75 ArchSpec arch;
76
77 if (triple_cstr)
78 {
79 arch.SetTriple(triple_cstr, platform_sp.get());
80 if (!arch.IsValid())
81 {
Greg Clayton86edbf42011-10-26 00:56:27 +000082 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
Greg Claytoncac9c5f2011-09-24 00:52:29 +000083 return error;
84 }
85 }
86 error = TargetList::CreateTarget (debugger,
87 file,
88 arch,
89 get_dependent_files,
90 platform_sp,
91 target_sp);
92 return error;
93}
94
95Error
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096TargetList::CreateTarget
97(
Greg Clayton66111032010-06-23 01:19:29 +000098 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099 const FileSpec& file,
100 const ArchSpec& arch,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101 bool get_dependent_files,
Greg Claytoncac9c5f2011-09-24 00:52:29 +0000102 const PlatformSP &platform_sp,
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103 TargetSP &target_sp
104)
105{
106 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytone996fd32011-03-08 22:40:15 +0000107 "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108 file.GetDirectory().AsCString(),
109 file.GetFilename().AsCString(),
Greg Claytone996fd32011-03-08 22:40:15 +0000110 arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +0000111 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +0000112
Jim Ingham5aee1622010-08-09 23:31:02 +0000113
Greg Claytone996fd32011-03-08 22:40:15 +0000114 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +0000115 {
116 ModuleSP exe_module_sp;
117 FileSpec resolved_file(file);
Caroline Tice428a9a52010-09-10 04:48:55 +0000118
Greg Claytone996fd32011-03-08 22:40:15 +0000119 if (platform_sp)
120 error = platform_sp->ResolveExecutable (file, arch, exe_module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121
Greg Claytone996fd32011-03-08 22:40:15 +0000122 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123 {
Jim Ingham5aee1622010-08-09 23:31:02 +0000124 if (exe_module_sp->GetObjectFile() == NULL)
125 {
Greg Claytonbc5cad62010-12-08 04:55:11 +0000126 if (arch.IsValid())
127 {
128 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
129 file.GetDirectory().AsCString(),
130 file.GetDirectory() ? "/" : "",
131 file.GetFilename().AsCString(),
Greg Clayton64195a22011-02-23 00:35:02 +0000132 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000133 }
134 else
135 {
136 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
137 file.GetDirectory().AsCString(),
138 file.GetDirectory() ? "/" : "",
139 file.GetFilename().AsCString());
140 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000141 return error;
142 }
Greg Clayton32e0a752011-03-30 18:16:51 +0000143 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +0000144 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000146 }
Greg Claytone996fd32011-03-08 22:40:15 +0000147 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000148 {
Greg Claytone996fd32011-03-08 22:40:15 +0000149 // No file was specified, just create an empty target with any arch
150 // if a valid arch was specified
Greg Clayton32e0a752011-03-30 18:16:51 +0000151 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000152 }
153
154 if (target_sp)
155 {
156 target_sp->UpdateInstanceName();
157
Jim Ingham5aee1622010-08-09 23:31:02 +0000158 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000159 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000160 m_target_list.push_back(target_sp);
161 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163 return error;
164}
165
166bool
167TargetList::DeleteTarget (TargetSP &target_sp)
168{
169 Mutex::Locker locker(m_target_list_mutex);
170 collection::iterator pos, end = m_target_list.end();
171
172 for (pos = m_target_list.begin(); pos != end; ++pos)
173 {
174 if (pos->get() == target_sp.get())
175 {
176 m_target_list.erase(pos);
177 return true;
178 }
179 }
180 return false;
181}
182
183
184TargetSP
185TargetList::FindTargetWithExecutableAndArchitecture
186(
187 const FileSpec &exe_file_spec,
188 const ArchSpec *exe_arch_ptr
189) const
190{
191 Mutex::Locker locker (m_target_list_mutex);
192 TargetSP target_sp;
193 bool full_match = exe_file_spec.GetDirectory();
194
195 collection::const_iterator pos, end = m_target_list.end();
196 for (pos = m_target_list.begin(); pos != end; ++pos)
197 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000198 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199
Greg Claytonaa149cb2011-08-11 02:48:45 +0000200 if (exe_module)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000202 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000203 {
204 if (exe_arch_ptr)
205 {
Greg Claytonaa149cb2011-08-11 02:48:45 +0000206 if (*exe_arch_ptr != exe_module->GetArchitecture())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207 continue;
208 }
209 target_sp = *pos;
210 break;
211 }
212 }
213 }
214 return target_sp;
215}
216
217TargetSP
218TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
219{
220 Mutex::Locker locker(m_target_list_mutex);
221 TargetSP target_sp;
222 collection::const_iterator pos, end = m_target_list.end();
223 for (pos = m_target_list.begin(); pos != end; ++pos)
224 {
225 Process* process = (*pos)->GetProcessSP().get();
226 if (process && process->GetID() == pid)
227 {
228 target_sp = *pos;
229 break;
230 }
231 }
232 return target_sp;
233}
234
235
236TargetSP
237TargetList::FindTargetWithProcess (Process *process) const
238{
239 TargetSP target_sp;
240 if (process)
241 {
242 Mutex::Locker locker(m_target_list_mutex);
243 collection::const_iterator pos, end = m_target_list.end();
244 for (pos = m_target_list.begin(); pos != end; ++pos)
245 {
246 if (process == (*pos)->GetProcessSP().get())
247 {
248 target_sp = *pos;
249 break;
250 }
251 }
252 }
253 return target_sp;
254}
255
256TargetSP
257TargetList::GetTargetSP (Target *target) const
258{
259 TargetSP target_sp;
260 if (target)
261 {
262 Mutex::Locker locker(m_target_list_mutex);
263 collection::const_iterator pos, end = m_target_list.end();
264 for (pos = m_target_list.begin(); pos != end; ++pos)
265 {
266 if (target == (*pos).get())
267 {
268 target_sp = *pos;
269 break;
270 }
271 }
272 }
273 return target_sp;
274}
275
276uint32_t
277TargetList::SendAsyncInterrupt (lldb::pid_t pid)
278{
279 uint32_t num_async_interrupts_sent = 0;
280
281 if (pid != LLDB_INVALID_PROCESS_ID)
282 {
283 TargetSP target_sp(FindTargetWithProcessID (pid));
284 if (target_sp.get())
285 {
286 Process* process = target_sp->GetProcessSP().get();
287 if (process)
288 {
289 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
290 ++num_async_interrupts_sent;
291 }
292 }
293 }
294 else
295 {
296 // We don't have a valid pid to broadcast to, so broadcast to the target
297 // list's async broadcaster...
298 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
299 }
300
301 return num_async_interrupts_sent;
302}
303
304uint32_t
305TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
306{
307 uint32_t num_signals_sent = 0;
308 Process *process = NULL;
309 if (pid == LLDB_INVALID_PROCESS_ID)
310 {
311 // Signal all processes with signal
312 Mutex::Locker locker(m_target_list_mutex);
313 collection::iterator pos, end = m_target_list.end();
314 for (pos = m_target_list.begin(); pos != end; ++pos)
315 {
316 process = (*pos)->GetProcessSP().get();
317 if (process)
318 {
319 if (process->IsAlive())
320 {
321 ++num_signals_sent;
322 process->Signal (signo);
323 }
324 }
325 }
326 }
327 else
328 {
329 // Signal a specific process with signal
330 TargetSP target_sp(FindTargetWithProcessID (pid));
331 if (target_sp.get())
332 {
333 process = target_sp->GetProcessSP().get();
334 if (process)
335 {
336 if (process->IsAlive())
337 {
338 ++num_signals_sent;
339 process->Signal (signo);
340 }
341 }
342 }
343 }
344 return num_signals_sent;
345}
346
347int
348TargetList::GetNumTargets () const
349{
350 Mutex::Locker locker (m_target_list_mutex);
351 return m_target_list.size();
352}
353
354lldb::TargetSP
355TargetList::GetTargetAtIndex (uint32_t idx) const
356{
357 TargetSP target_sp;
358 Mutex::Locker locker (m_target_list_mutex);
359 if (idx < m_target_list.size())
360 target_sp = m_target_list[idx];
361 return target_sp;
362}
363
364uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000365TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366{
367 Mutex::Locker locker (m_target_list_mutex);
368 collection::const_iterator pos,
369 begin = m_target_list.begin(),
370 end = m_target_list.end();
371 for (pos = begin; pos != end; ++pos)
372 {
373 if (pos->get() == target)
374 {
Jim Ingham2976d002010-08-26 21:32:51 +0000375 m_selected_target_idx = std::distance (begin, pos);
376 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377 }
378 }
Jim Ingham2976d002010-08-26 21:32:51 +0000379 m_selected_target_idx = 0;
380 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381}
382
383lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000384TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385{
386 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000387 if (m_selected_target_idx >= m_target_list.size())
388 m_selected_target_idx = 0;
389 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390}