blob: d128d04040ff6d347fcb79ca662282194122d313 [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);
74 if (!Host::ResolveExecutableInBundle (&resolved_file))
75 resolved_file = file;
Chris Lattner24943d22010-06-08 16:52:24 +000076
Jim Ingham7508e732010-08-09 23:31:02 +000077 error = ModuleList::GetSharedModule(resolved_file,
78 arch,
79 uuid_ptr,
80 NULL,
81 0,
82 exe_module_sp,
83 NULL,
84 NULL);
85 if (exe_module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000086 {
Jim Ingham7508e732010-08-09 23:31:02 +000087 if (exe_module_sp->GetObjectFile() == NULL)
88 {
89 error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
90 file.GetDirectory().AsCString(),
91 file.GetDirectory() ? "/" : "",
92 file.GetFilename().AsCString(),
93 arch.AsCString());
94 return error;
95 }
96 target_sp.reset(new Target(debugger));
97 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner24943d22010-06-08 16:52:24 +000098 }
Jim Ingham7508e732010-08-09 23:31:02 +000099 }
100
101 if (target_sp.get())
102 {
103 Mutex::Locker locker(m_target_list_mutex);
Jim Inghamc8332952010-08-26 21:32:51 +0000104 m_selected_target_idx = m_target_list.size();
Jim Ingham7508e732010-08-09 23:31:02 +0000105 m_target_list.push_back(target_sp);
106 }
Chris Lattner24943d22010-06-08 16:52:24 +0000107
108// target_sp.reset(new Target);
109// // Let the target resolve any funky bundle paths before we try and get
110// // the object file...
111// target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
112// if (exe_module_sp->GetObjectFile() == NULL)
113// {
114// error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
115// file.GetDirectory().AsCString(),
116// file.GetDirectory() ? "/" : "",
117// file.GetFilename().AsCString(),
118// arch.AsCString());
119// }
120// else
121// {
122// if (target_sp.get())
123// {
124// error.Clear();
125// Mutex::Locker locker(m_target_list_mutex);
Jim Inghamc8332952010-08-26 21:32:51 +0000126// m_selected_target_idx = m_target_list.size();
Chris Lattner24943d22010-06-08 16:52:24 +0000127// m_target_list.push_back(target_sp);
128// }
129// }
Chris Lattner24943d22010-06-08 16:52:24 +0000130 else
131 {
132 target_sp.reset();
133 }
134
135 return error;
136}
137
138bool
139TargetList::DeleteTarget (TargetSP &target_sp)
140{
141 Mutex::Locker locker(m_target_list_mutex);
142 collection::iterator pos, end = m_target_list.end();
143
144 for (pos = m_target_list.begin(); pos != end; ++pos)
145 {
146 if (pos->get() == target_sp.get())
147 {
148 m_target_list.erase(pos);
149 return true;
150 }
151 }
152 return false;
153}
154
155
156TargetSP
157TargetList::FindTargetWithExecutableAndArchitecture
158(
159 const FileSpec &exe_file_spec,
160 const ArchSpec *exe_arch_ptr
161) const
162{
163 Mutex::Locker locker (m_target_list_mutex);
164 TargetSP target_sp;
165 bool full_match = exe_file_spec.GetDirectory();
166
167 collection::const_iterator pos, end = m_target_list.end();
168 for (pos = m_target_list.begin(); pos != end; ++pos)
169 {
170 ModuleSP module_sp ((*pos)->GetExecutableModule());
171
172 if (module_sp)
173 {
174 if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match))
175 {
176 if (exe_arch_ptr)
177 {
178 if (*exe_arch_ptr != module_sp->GetArchitecture())
179 continue;
180 }
181 target_sp = *pos;
182 break;
183 }
184 }
185 }
186 return target_sp;
187}
188
189TargetSP
190TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
191{
192 Mutex::Locker locker(m_target_list_mutex);
193 TargetSP target_sp;
194 collection::const_iterator pos, end = m_target_list.end();
195 for (pos = m_target_list.begin(); pos != end; ++pos)
196 {
197 Process* process = (*pos)->GetProcessSP().get();
198 if (process && process->GetID() == pid)
199 {
200 target_sp = *pos;
201 break;
202 }
203 }
204 return target_sp;
205}
206
207
208TargetSP
209TargetList::FindTargetWithProcess (Process *process) const
210{
211 TargetSP target_sp;
212 if (process)
213 {
214 Mutex::Locker locker(m_target_list_mutex);
215 collection::const_iterator pos, end = m_target_list.end();
216 for (pos = m_target_list.begin(); pos != end; ++pos)
217 {
218 if (process == (*pos)->GetProcessSP().get())
219 {
220 target_sp = *pos;
221 break;
222 }
223 }
224 }
225 return target_sp;
226}
227
228TargetSP
229TargetList::GetTargetSP (Target *target) const
230{
231 TargetSP target_sp;
232 if (target)
233 {
234 Mutex::Locker locker(m_target_list_mutex);
235 collection::const_iterator pos, end = m_target_list.end();
236 for (pos = m_target_list.begin(); pos != end; ++pos)
237 {
238 if (target == (*pos).get())
239 {
240 target_sp = *pos;
241 break;
242 }
243 }
244 }
245 return target_sp;
246}
247
248uint32_t
249TargetList::SendAsyncInterrupt (lldb::pid_t pid)
250{
251 uint32_t num_async_interrupts_sent = 0;
252
253 if (pid != LLDB_INVALID_PROCESS_ID)
254 {
255 TargetSP target_sp(FindTargetWithProcessID (pid));
256 if (target_sp.get())
257 {
258 Process* process = target_sp->GetProcessSP().get();
259 if (process)
260 {
261 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
262 ++num_async_interrupts_sent;
263 }
264 }
265 }
266 else
267 {
268 // We don't have a valid pid to broadcast to, so broadcast to the target
269 // list's async broadcaster...
270 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
271 }
272
273 return num_async_interrupts_sent;
274}
275
276uint32_t
277TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
278{
279 uint32_t num_signals_sent = 0;
280 Process *process = NULL;
281 if (pid == LLDB_INVALID_PROCESS_ID)
282 {
283 // Signal all processes with signal
284 Mutex::Locker locker(m_target_list_mutex);
285 collection::iterator pos, end = m_target_list.end();
286 for (pos = m_target_list.begin(); pos != end; ++pos)
287 {
288 process = (*pos)->GetProcessSP().get();
289 if (process)
290 {
291 if (process->IsAlive())
292 {
293 ++num_signals_sent;
294 process->Signal (signo);
295 }
296 }
297 }
298 }
299 else
300 {
301 // Signal a specific process with signal
302 TargetSP target_sp(FindTargetWithProcessID (pid));
303 if (target_sp.get())
304 {
305 process = target_sp->GetProcessSP().get();
306 if (process)
307 {
308 if (process->IsAlive())
309 {
310 ++num_signals_sent;
311 process->Signal (signo);
312 }
313 }
314 }
315 }
316 return num_signals_sent;
317}
318
319int
320TargetList::GetNumTargets () const
321{
322 Mutex::Locker locker (m_target_list_mutex);
323 return m_target_list.size();
324}
325
326lldb::TargetSP
327TargetList::GetTargetAtIndex (uint32_t idx) const
328{
329 TargetSP target_sp;
330 Mutex::Locker locker (m_target_list_mutex);
331 if (idx < m_target_list.size())
332 target_sp = m_target_list[idx];
333 return target_sp;
334}
335
336uint32_t
Jim Inghamc8332952010-08-26 21:32:51 +0000337TargetList::SetSelectedTarget (Target* target)
Chris Lattner24943d22010-06-08 16:52:24 +0000338{
339 Mutex::Locker locker (m_target_list_mutex);
340 collection::const_iterator pos,
341 begin = m_target_list.begin(),
342 end = m_target_list.end();
343 for (pos = begin; pos != end; ++pos)
344 {
345 if (pos->get() == target)
346 {
Jim Inghamc8332952010-08-26 21:32:51 +0000347 m_selected_target_idx = std::distance (begin, pos);
348 return m_selected_target_idx;
Chris Lattner24943d22010-06-08 16:52:24 +0000349 }
350 }
Jim Inghamc8332952010-08-26 21:32:51 +0000351 m_selected_target_idx = 0;
352 return m_selected_target_idx;
Chris Lattner24943d22010-06-08 16:52:24 +0000353}
354
355lldb::TargetSP
Jim Inghamc8332952010-08-26 21:32:51 +0000356TargetList::GetSelectedTarget ()
Chris Lattner24943d22010-06-08 16:52:24 +0000357{
358 Mutex::Locker locker (m_target_list_mutex);
Jim Inghamc8332952010-08-26 21:32:51 +0000359 if (m_selected_target_idx >= m_target_list.size())
360 m_selected_target_idx = 0;
361 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000362}