blob: af681d22f45e52aec1e5705fd79e7aac00f477d4 [file] [log] [blame]
Chris Lattner30fdc8d2010-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 Ingham2976d002010-08-26 21:32:51 +000033 m_selected_target_idx (0)
Chris Lattner30fdc8d2010-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 Clayton66111032010-06-23 01:19:29 +000049 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050 const FileSpec& file,
51 const ArchSpec& arch,
Greg Clayton60830262011-02-04 18:53:10 +000052 const lldb_private::UUID *uuid_ptr,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053 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(),
Greg Clayton64195a22011-02-23 00:35:02 +000061 arch.GetArchitectureName(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062 uuid_ptr);
Jim Ingham5aee1622010-08-09 23:31:02 +000063 Error error;
64
65 if (!file)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066 {
Greg Clayton66111032010-06-23 01:19:29 +000067 target_sp.reset(new Target(debugger));
Jim Ingham5aee1622010-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 Tice428a9a52010-09-10 04:48:55 +000074
75 if (!resolved_file.Exists())
76 resolved_file.ResolveExecutableLocation ();
77
Greg Claytondd36def2010-10-17 22:03:32 +000078 if (!Host::ResolveExecutableInBundle (resolved_file))
Jim Ingham5aee1622010-08-09 23:31:02 +000079 resolved_file = file;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080
Greg Claytonbc5cad62010-12-08 04:55:11 +000081 error = ModuleList::GetSharedModule (resolved_file,
82 arch,
83 uuid_ptr,
84 NULL,
85 0,
86 exe_module_sp,
87 NULL,
88 NULL);
Jim Ingham5aee1622010-08-09 23:31:02 +000089 if (exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000090 {
Jim Ingham5aee1622010-08-09 23:31:02 +000091 if (exe_module_sp->GetObjectFile() == NULL)
92 {
Greg Claytonbc5cad62010-12-08 04:55:11 +000093 if (arch.IsValid())
94 {
95 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
96 file.GetDirectory().AsCString(),
97 file.GetDirectory() ? "/" : "",
98 file.GetFilename().AsCString(),
Greg Clayton64195a22011-02-23 00:35:02 +000099 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +0000100 }
101 else
102 {
103 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
104 file.GetDirectory().AsCString(),
105 file.GetDirectory() ? "/" : "",
106 file.GetFilename().AsCString());
107 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000108 return error;
109 }
110 target_sp.reset(new Target(debugger));
111 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000112 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000113 }
Caroline Tice1559a462010-09-27 00:30:10 +0000114
115 if (target_sp.get())
116 target_sp->UpdateInstanceName();
Jim Ingham5aee1622010-08-09 23:31:02 +0000117
118 if (target_sp.get())
119 {
120 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000121 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000122 m_target_list.push_back(target_sp);
123 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124
125// target_sp.reset(new Target);
126// // Let the target resolve any funky bundle paths before we try and get
127// // the object file...
128// target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
129// if (exe_module_sp->GetObjectFile() == NULL)
130// {
131// error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
132// file.GetDirectory().AsCString(),
133// file.GetDirectory() ? "/" : "",
134// file.GetFilename().AsCString(),
135// arch.AsCString());
136// }
137// else
138// {
139// if (target_sp.get())
140// {
141// error.Clear();
142// Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000143// m_selected_target_idx = m_target_list.size();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144// m_target_list.push_back(target_sp);
145// }
146// }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 else
148 {
149 target_sp.reset();
150 }
151
152 return error;
153}
154
155bool
156TargetList::DeleteTarget (TargetSP &target_sp)
157{
158 Mutex::Locker locker(m_target_list_mutex);
159 collection::iterator pos, end = m_target_list.end();
160
161 for (pos = m_target_list.begin(); pos != end; ++pos)
162 {
163 if (pos->get() == target_sp.get())
164 {
165 m_target_list.erase(pos);
166 return true;
167 }
168 }
169 return false;
170}
171
172
173TargetSP
174TargetList::FindTargetWithExecutableAndArchitecture
175(
176 const FileSpec &exe_file_spec,
177 const ArchSpec *exe_arch_ptr
178) const
179{
180 Mutex::Locker locker (m_target_list_mutex);
181 TargetSP target_sp;
182 bool full_match = exe_file_spec.GetDirectory();
183
184 collection::const_iterator pos, end = m_target_list.end();
185 for (pos = m_target_list.begin(); pos != end; ++pos)
186 {
187 ModuleSP module_sp ((*pos)->GetExecutableModule());
188
189 if (module_sp)
190 {
191 if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match))
192 {
193 if (exe_arch_ptr)
194 {
195 if (*exe_arch_ptr != module_sp->GetArchitecture())
196 continue;
197 }
198 target_sp = *pos;
199 break;
200 }
201 }
202 }
203 return target_sp;
204}
205
206TargetSP
207TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
208{
209 Mutex::Locker locker(m_target_list_mutex);
210 TargetSP target_sp;
211 collection::const_iterator pos, end = m_target_list.end();
212 for (pos = m_target_list.begin(); pos != end; ++pos)
213 {
214 Process* process = (*pos)->GetProcessSP().get();
215 if (process && process->GetID() == pid)
216 {
217 target_sp = *pos;
218 break;
219 }
220 }
221 return target_sp;
222}
223
224
225TargetSP
226TargetList::FindTargetWithProcess (Process *process) const
227{
228 TargetSP target_sp;
229 if (process)
230 {
231 Mutex::Locker locker(m_target_list_mutex);
232 collection::const_iterator pos, end = m_target_list.end();
233 for (pos = m_target_list.begin(); pos != end; ++pos)
234 {
235 if (process == (*pos)->GetProcessSP().get())
236 {
237 target_sp = *pos;
238 break;
239 }
240 }
241 }
242 return target_sp;
243}
244
245TargetSP
246TargetList::GetTargetSP (Target *target) const
247{
248 TargetSP target_sp;
249 if (target)
250 {
251 Mutex::Locker locker(m_target_list_mutex);
252 collection::const_iterator pos, end = m_target_list.end();
253 for (pos = m_target_list.begin(); pos != end; ++pos)
254 {
255 if (target == (*pos).get())
256 {
257 target_sp = *pos;
258 break;
259 }
260 }
261 }
262 return target_sp;
263}
264
265uint32_t
266TargetList::SendAsyncInterrupt (lldb::pid_t pid)
267{
268 uint32_t num_async_interrupts_sent = 0;
269
270 if (pid != LLDB_INVALID_PROCESS_ID)
271 {
272 TargetSP target_sp(FindTargetWithProcessID (pid));
273 if (target_sp.get())
274 {
275 Process* process = target_sp->GetProcessSP().get();
276 if (process)
277 {
278 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
279 ++num_async_interrupts_sent;
280 }
281 }
282 }
283 else
284 {
285 // We don't have a valid pid to broadcast to, so broadcast to the target
286 // list's async broadcaster...
287 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
288 }
289
290 return num_async_interrupts_sent;
291}
292
293uint32_t
294TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
295{
296 uint32_t num_signals_sent = 0;
297 Process *process = NULL;
298 if (pid == LLDB_INVALID_PROCESS_ID)
299 {
300 // Signal all processes with signal
301 Mutex::Locker locker(m_target_list_mutex);
302 collection::iterator pos, end = m_target_list.end();
303 for (pos = m_target_list.begin(); pos != end; ++pos)
304 {
305 process = (*pos)->GetProcessSP().get();
306 if (process)
307 {
308 if (process->IsAlive())
309 {
310 ++num_signals_sent;
311 process->Signal (signo);
312 }
313 }
314 }
315 }
316 else
317 {
318 // Signal a specific process with signal
319 TargetSP target_sp(FindTargetWithProcessID (pid));
320 if (target_sp.get())
321 {
322 process = target_sp->GetProcessSP().get();
323 if (process)
324 {
325 if (process->IsAlive())
326 {
327 ++num_signals_sent;
328 process->Signal (signo);
329 }
330 }
331 }
332 }
333 return num_signals_sent;
334}
335
336int
337TargetList::GetNumTargets () const
338{
339 Mutex::Locker locker (m_target_list_mutex);
340 return m_target_list.size();
341}
342
343lldb::TargetSP
344TargetList::GetTargetAtIndex (uint32_t idx) const
345{
346 TargetSP target_sp;
347 Mutex::Locker locker (m_target_list_mutex);
348 if (idx < m_target_list.size())
349 target_sp = m_target_list[idx];
350 return target_sp;
351}
352
353uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000354TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000355{
356 Mutex::Locker locker (m_target_list_mutex);
357 collection::const_iterator pos,
358 begin = m_target_list.begin(),
359 end = m_target_list.end();
360 for (pos = begin; pos != end; ++pos)
361 {
362 if (pos->get() == target)
363 {
Jim Ingham2976d002010-08-26 21:32:51 +0000364 m_selected_target_idx = std::distance (begin, pos);
365 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000366 }
367 }
Jim Ingham2976d002010-08-26 21:32:51 +0000368 m_selected_target_idx = 0;
369 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370}
371
372lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000373TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374{
375 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000376 if (m_selected_target_idx >= m_target_list.size())
377 m_selected_target_idx = 0;
378 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379}