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