blob: e8a8ba906a3842bc9e9b051cd65a060a8b77c970 [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"
Greg Claytonb1888f22011-03-19 01:12:21 +000015#include "lldb/Core/Debugger.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Core/Event.h"
17#include "lldb/Core/State.h"
18#include "lldb/Core/Timer.h"
19#include "lldb/Host/Host.h"
Greg Claytone4b9c1f2011-03-08 22:40:15 +000020#include "lldb/Target/Platform.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Target/Process.h"
22#include "lldb/Target/TargetList.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
27
28//----------------------------------------------------------------------
29// TargetList constructor
30//----------------------------------------------------------------------
31TargetList::TargetList() :
32 Broadcaster("TargetList"),
33 m_target_list(),
34 m_target_list_mutex (Mutex::eMutexTypeRecursive),
Jim Inghamc8332952010-08-26 21:32:51 +000035 m_selected_target_idx (0)
Chris Lattner24943d22010-06-08 16:52:24 +000036{
37}
38
39//----------------------------------------------------------------------
40// Destructor
41//----------------------------------------------------------------------
42TargetList::~TargetList()
43{
44 Mutex::Locker locker(m_target_list_mutex);
45 m_target_list.clear();
46}
47
48Error
49TargetList::CreateTarget
50(
Greg Clayton63094e02010-06-23 01:19:29 +000051 Debugger &debugger,
Chris Lattner24943d22010-06-08 16:52:24 +000052 const FileSpec& file,
53 const ArchSpec& arch,
Chris Lattner24943d22010-06-08 16:52:24 +000054 bool get_dependent_files,
55 TargetSP &target_sp
56)
57{
58 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytone4b9c1f2011-03-08 22:40:15 +000059 "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
Chris Lattner24943d22010-06-08 16:52:24 +000060 file.GetDirectory().AsCString(),
61 file.GetFilename().AsCString(),
Greg Claytone4b9c1f2011-03-08 22:40:15 +000062 arch.GetArchitectureName());
Jim Ingham7508e732010-08-09 23:31:02 +000063 Error error;
Greg Claytonb1888f22011-03-19 01:12:21 +000064
65 PlatformSP platform_sp (debugger.GetPlatformList().GetSelectedPlatform ());
Jim Ingham7508e732010-08-09 23:31:02 +000066
Greg Claytone4b9c1f2011-03-08 22:40:15 +000067 if (file)
Jim Ingham7508e732010-08-09 23:31:02 +000068 {
69 ModuleSP exe_module_sp;
70 FileSpec resolved_file(file);
Caroline Ticeeddffe92010-09-10 04:48:55 +000071
Greg Claytone4b9c1f2011-03-08 22:40:15 +000072 if (platform_sp)
73 error = platform_sp->ResolveExecutable (file, arch, exe_module_sp);
Chris Lattner24943d22010-06-08 16:52:24 +000074
Greg Claytone4b9c1f2011-03-08 22:40:15 +000075 if (error.Success() && exe_module_sp)
Chris Lattner24943d22010-06-08 16:52:24 +000076 {
Jim Ingham7508e732010-08-09 23:31:02 +000077 if (exe_module_sp->GetObjectFile() == NULL)
78 {
Greg Claytonfa2f48b2010-12-08 04:55:11 +000079 if (arch.IsValid())
80 {
81 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
82 file.GetDirectory().AsCString(),
83 file.GetDirectory() ? "/" : "",
84 file.GetFilename().AsCString(),
Greg Clayton940b1032011-02-23 00:35:02 +000085 arch.GetArchitectureName());
Greg Claytonfa2f48b2010-12-08 04:55:11 +000086 }
87 else
88 {
89 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
90 file.GetDirectory().AsCString(),
91 file.GetDirectory() ? "/" : "",
92 file.GetFilename().AsCString());
93 }
Jim Ingham7508e732010-08-09 23:31:02 +000094 return error;
95 }
Greg Clayton24bc5d92011-03-30 18:16:51 +000096 target_sp.reset(new Target(debugger, arch, platform_sp));
Jim Ingham7508e732010-08-09 23:31:02 +000097 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 }
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000100 else
Jim Ingham7508e732010-08-09 23:31:02 +0000101 {
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000102 // No file was specified, just create an empty target with any arch
103 // if a valid arch was specified
Greg Clayton24bc5d92011-03-30 18:16:51 +0000104 target_sp.reset(new Target(debugger, arch, platform_sp));
Greg Claytone4b9c1f2011-03-08 22:40:15 +0000105 }
106
107 if (target_sp)
108 {
109 target_sp->UpdateInstanceName();
110
Jim Ingham7508e732010-08-09 23:31:02 +0000111 Mutex::Locker locker(m_target_list_mutex);
Jim Inghamc8332952010-08-26 21:32:51 +0000112 m_selected_target_idx = m_target_list.size();
Jim Ingham7508e732010-08-09 23:31:02 +0000113 m_target_list.push_back(target_sp);
114 }
Chris Lattner24943d22010-06-08 16:52:24 +0000115
Chris Lattner24943d22010-06-08 16:52:24 +0000116 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 {
Greg Clayton5beb99d2011-08-11 02:48:45 +0000151 Module *exe_module = (*pos)->GetExecutableModulePointer();
Chris Lattner24943d22010-06-08 16:52:24 +0000152
Greg Clayton5beb99d2011-08-11 02:48:45 +0000153 if (exe_module)
Chris Lattner24943d22010-06-08 16:52:24 +0000154 {
Greg Clayton5beb99d2011-08-11 02:48:45 +0000155 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
Chris Lattner24943d22010-06-08 16:52:24 +0000156 {
157 if (exe_arch_ptr)
158 {
Greg Clayton5beb99d2011-08-11 02:48:45 +0000159 if (*exe_arch_ptr != exe_module->GetArchitecture())
Chris Lattner24943d22010-06-08 16:52:24 +0000160 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
Jim Inghamc8332952010-08-26 21:32:51 +0000318TargetList::SetSelectedTarget (Target* target)
Chris Lattner24943d22010-06-08 16:52:24 +0000319{
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 {
Jim Inghamc8332952010-08-26 21:32:51 +0000328 m_selected_target_idx = std::distance (begin, pos);
329 return m_selected_target_idx;
Chris Lattner24943d22010-06-08 16:52:24 +0000330 }
331 }
Jim Inghamc8332952010-08-26 21:32:51 +0000332 m_selected_target_idx = 0;
333 return m_selected_target_idx;
Chris Lattner24943d22010-06-08 16:52:24 +0000334}
335
336lldb::TargetSP
Jim Inghamc8332952010-08-26 21:32:51 +0000337TargetList::GetSelectedTarget ()
Chris Lattner24943d22010-06-08 16:52:24 +0000338{
339 Mutex::Locker locker (m_target_list_mutex);
Jim Inghamc8332952010-08-26 21:32:51 +0000340 if (m_selected_target_idx >= m_target_list.size())
341 m_selected_target_idx = 0;
342 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner24943d22010-06-08 16:52:24 +0000343}