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