blob: 6033a60cf86dd831ddedc2536106a3eb7f3a57c3 [file] [log] [blame]
Chris Lattner24943d22010-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"
15#include "lldb/Core/Event.h"
16#include "lldb/Core/State.h"
17#include "lldb/Core/Timer.h"
18#include "lldb/Host/Host.h"
19#include "lldb/Target/Process.h"
20#include "lldb/Target/TargetList.h"
21
22using namespace lldb;
23using namespace lldb_private;
24
25
26//----------------------------------------------------------------------
27// TargetList constructor
28//----------------------------------------------------------------------
29TargetList::TargetList() :
30 Broadcaster("TargetList"),
31 m_target_list(),
32 m_target_list_mutex (Mutex::eMutexTypeRecursive),
Jim Inghamc8332952010-08-26 21:32:51 +000033 m_selected_target_idx (0)
Chris Lattner24943d22010-06-08 16:52:24 +000034{
35}
36
37//----------------------------------------------------------------------
38// Destructor
39//----------------------------------------------------------------------
40TargetList::~TargetList()
41{
42 Mutex::Locker locker(m_target_list_mutex);
43 m_target_list.clear();
44}
45
46Error
47TargetList::CreateTarget
48(
Greg Clayton63094e02010-06-23 01:19:29 +000049 Debugger &debugger,
Chris Lattner24943d22010-06-08 16:52:24 +000050 const FileSpec& file,
51 const ArchSpec& arch,
52 const UUID *uuid_ptr,
53 bool get_dependent_files,
54 TargetSP &target_sp
55)
56{
57 Timer scoped_timer (__PRETTY_FUNCTION__,
58 "TargetList::CreateTarget (file = '%s/%s', arch = '%s', uuid = %p)",
59 file.GetDirectory().AsCString(),
60 file.GetFilename().AsCString(),
61 arch.AsCString(),
62 uuid_ptr);
Jim Ingham7508e732010-08-09 23:31:02 +000063 Error error;
64
65 if (!file)
Chris Lattner24943d22010-06-08 16:52:24 +000066 {
Greg Clayton63094e02010-06-23 01:19:29 +000067 target_sp.reset(new Target(debugger));
Jim Ingham7508e732010-08-09 23:31:02 +000068 target_sp->SetArchitecture(arch);
69 }
70 else
71 {
72 ModuleSP exe_module_sp;
73 FileSpec resolved_file(file);
Caroline Ticeeddffe92010-09-10 04:48:55 +000074
75 if (!resolved_file.Exists())
76 resolved_file.ResolveExecutableLocation ();
77
Jim Ingham7508e732010-08-09 23:31:02 +000078 if (!Host::ResolveExecutableInBundle (&resolved_file))
79 resolved_file = file;
Chris Lattner24943d22010-06-08 16:52:24 +000080
Jim Ingham7508e732010-08-09 23:31:02 +000081 error = ModuleList::GetSharedModule(resolved_file,
82 arch,
83 uuid_ptr,
84 NULL,
85 0,
86 exe_module_sp,
87 NULL,
88 NULL);
89 if (exe_module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000090 {
Jim Ingham7508e732010-08-09 23:31:02 +000091 if (exe_module_sp->GetObjectFile() == NULL)
92 {
93 error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
94 file.GetDirectory().AsCString(),
95 file.GetDirectory() ? "/" : "",
96 file.GetFilename().AsCString(),
97 arch.AsCString());
98 return error;
99 }
100 target_sp.reset(new Target(debugger));
101 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner24943d22010-06-08 16:52:24 +0000102 }
Jim Ingham7508e732010-08-09 23:31:02 +0000103 }
Caroline Tice1ebef442010-09-27 00:30:10 +0000104
105 if (target_sp.get())
106 target_sp->UpdateInstanceName();
Jim Ingham7508e732010-08-09 23:31:02 +0000107
108 if (target_sp.get())
109 {
110 Mutex::Locker locker(m_target_list_mutex);
Jim Inghamc8332952010-08-26 21:32:51 +0000111 m_selected_target_idx = m_target_list.size();
Jim Ingham7508e732010-08-09 23:31:02 +0000112 m_target_list.push_back(target_sp);
113 }
Chris Lattner24943d22010-06-08 16:52:24 +0000114
115// target_sp.reset(new Target);
116// // Let the target resolve any funky bundle paths before we try and get
117// // the object file...
118// target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
119// if (exe_module_sp->GetObjectFile() == NULL)
120// {
121// error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
122// file.GetDirectory().AsCString(),
123// file.GetDirectory() ? "/" : "",
124// file.GetFilename().AsCString(),
125// arch.AsCString());
126// }
127// else
128// {
129// if (target_sp.get())
130// {
131// error.Clear();
132// Mutex::Locker locker(m_target_list_mutex);
Jim Inghamc8332952010-08-26 21:32:51 +0000133// m_selected_target_idx = m_target_list.size();
Chris Lattner24943d22010-06-08 16:52:24 +0000134// m_target_list.push_back(target_sp);
135// }
136// }
Chris Lattner24943d22010-06-08 16:52:24 +0000137 else
138 {
139 target_sp.reset();
140 }
141
142 return error;
143}
144
145bool
146TargetList::DeleteTarget (TargetSP &target_sp)
147{
148 Mutex::Locker locker(m_target_list_mutex);
149 collection::iterator pos, end = m_target_list.end();
150
151 for (pos = m_target_list.begin(); pos != end; ++pos)
152 {
153 if (pos->get() == target_sp.get())
154 {
155 m_target_list.erase(pos);
156 return true;
157 }
158 }
159 return false;
160}
161
162
163TargetSP
164TargetList::FindTargetWithExecutableAndArchitecture
165(
166 const FileSpec &exe_file_spec,
167 const ArchSpec *exe_arch_ptr
168) const
169{
170 Mutex::Locker locker (m_target_list_mutex);
171 TargetSP target_sp;
172 bool full_match = exe_file_spec.GetDirectory();
173
174 collection::const_iterator pos, end = m_target_list.end();
175 for (pos = m_target_list.begin(); pos != end; ++pos)
176 {
177 ModuleSP module_sp ((*pos)->GetExecutableModule());
178
179 if (module_sp)
180 {
181 if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match))
182 {
183 if (exe_arch_ptr)
184 {
185 if (*exe_arch_ptr != module_sp->GetArchitecture())
186 continue;
187 }
188 target_sp = *pos;
189 break;
190 }
191 }
192 }
193 return target_sp;
194}
195
196TargetSP
197TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
198{
199 Mutex::Locker locker(m_target_list_mutex);
200 TargetSP target_sp;
201 collection::const_iterator pos, end = m_target_list.end();
202 for (pos = m_target_list.begin(); pos != end; ++pos)
203 {
204 Process* process = (*pos)->GetProcessSP().get();
205 if (process && process->GetID() == pid)
206 {
207 target_sp = *pos;
208 break;
209 }
210 }
211 return target_sp;
212}
213
214
215TargetSP
216TargetList::FindTargetWithProcess (Process *process) const
217{
218 TargetSP target_sp;
219 if (process)
220 {
221 Mutex::Locker locker(m_target_list_mutex);
222 collection::const_iterator pos, end = m_target_list.end();
223 for (pos = m_target_list.begin(); pos != end; ++pos)
224 {
225 if (process == (*pos)->GetProcessSP().get())
226 {
227 target_sp = *pos;
228 break;
229 }
230 }
231 }
232 return target_sp;
233}
234
235TargetSP
236TargetList::GetTargetSP (Target *target) const
237{
238 TargetSP target_sp;
239 if (target)
240 {
241 Mutex::Locker locker(m_target_list_mutex);
242 collection::const_iterator pos, end = m_target_list.end();
243 for (pos = m_target_list.begin(); pos != end; ++pos)
244 {
245 if (target == (*pos).get())
246 {
247 target_sp = *pos;
248 break;
249 }
250 }
251 }
252 return target_sp;
253}
254
255uint32_t
256TargetList::SendAsyncInterrupt (lldb::pid_t pid)
257{
258 uint32_t num_async_interrupts_sent = 0;
259
260 if (pid != LLDB_INVALID_PROCESS_ID)
261 {
262 TargetSP target_sp(FindTargetWithProcessID (pid));
263 if (target_sp.get())
264 {
265 Process* process = target_sp->GetProcessSP().get();
266 if (process)
267 {
268 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
269 ++num_async_interrupts_sent;
270 }
271 }
272 }
273 else
274 {
275 // We don't have a valid pid to broadcast to, so broadcast to the target
276 // list's async broadcaster...
277 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
278 }
279
280 return num_async_interrupts_sent;
281}
282
283uint32_t
284TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
285{
286 uint32_t num_signals_sent = 0;
287 Process *process = NULL;
288 if (pid == LLDB_INVALID_PROCESS_ID)
289 {
290 // Signal all processes with signal
291 Mutex::Locker locker(m_target_list_mutex);
292 collection::iterator pos, end = m_target_list.end();
293 for (pos = m_target_list.begin(); pos != end; ++pos)
294 {
295 process = (*pos)->GetProcessSP().get();
296 if (process)
297 {
298 if (process->IsAlive())
299 {
300 ++num_signals_sent;
301 process->Signal (signo);
302 }
303 }
304 }
305 }
306 else
307 {
308 // Signal a specific process with signal
309 TargetSP target_sp(FindTargetWithProcessID (pid));
310 if (target_sp.get())
311 {
312 process = target_sp->GetProcessSP().get();
313 if (process)
314 {
315 if (process->IsAlive())
316 {
317 ++num_signals_sent;
318 process->Signal (signo);
319 }
320 }
321 }
322 }
323 return num_signals_sent;
324}
325
326int
327TargetList::GetNumTargets () const
328{
329 Mutex::Locker locker (m_target_list_mutex);
330 return m_target_list.size();
331}
332
333lldb::TargetSP
334TargetList::GetTargetAtIndex (uint32_t idx) const
335{
336 TargetSP target_sp;
337 Mutex::Locker locker (m_target_list_mutex);
338 if (idx < m_target_list.size())
339 target_sp = m_target_list[idx];
340 return target_sp;
341}
342
343uint32_t
Jim Inghamc8332952010-08-26 21:32:51 +0000344TargetList::SetSelectedTarget (Target* target)
Chris Lattner24943d22010-06-08 16:52:24 +0000345{
346 Mutex::Locker locker (m_target_list_mutex);
347 collection::const_iterator pos,
348 begin = m_target_list.begin(),
349 end = m_target_list.end();
350 for (pos = begin; pos != end; ++pos)
351 {
352 if (pos->get() == target)
353 {
Jim Inghamc8332952010-08-26 21:32:51 +0000354 m_selected_target_idx = std::distance (begin, pos);
355 return m_selected_target_idx;
Chris Lattner24943d22010-06-08 16:52:24 +0000356 }
357 }
Jim Inghamc8332952010-08-26 21:32:51 +0000358 m_selected_target_idx = 0;
359 return m_selected_target_idx;
Chris Lattner24943d22010-06-08 16:52:24 +0000360}
361
362lldb::TargetSP
Jim Inghamc8332952010-08-26 21:32:51 +0000363TargetList::GetSelectedTarget ()
Chris Lattner24943d22010-06-08 16:52:24 +0000364{
365 Mutex::Locker locker (m_target_list_mutex);
Jim Inghamc8332952010-08-26 21:32:51 +0000366 if (m_selected_target_idx >= m_target_list.size())
367 m_selected_target_idx = 0;
368 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000369}