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