blob: 34520bbfaea6295cfcc27306087756e39210f4f9 [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"
Greg Claytonded470d2011-03-19 01:12:21 +000015#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-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 Claytone996fd32011-03-08 22:40:15 +000020#include "lldb/Target/Platform.h"
Chris Lattner30fdc8d2010-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 Ingham2976d002010-08-26 21:32:51 +000035 m_selected_target_idx (0)
Chris Lattner30fdc8d2010-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 Clayton66111032010-06-23 01:19:29 +000051 Debugger &debugger,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052 const FileSpec& file,
53 const ArchSpec& arch,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054 bool get_dependent_files,
55 TargetSP &target_sp
56)
57{
58 Timer scoped_timer (__PRETTY_FUNCTION__,
Greg Claytone996fd32011-03-08 22:40:15 +000059 "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060 file.GetDirectory().AsCString(),
61 file.GetFilename().AsCString(),
Greg Claytone996fd32011-03-08 22:40:15 +000062 arch.GetArchitectureName());
Jim Ingham5aee1622010-08-09 23:31:02 +000063 Error error;
Greg Claytonded470d2011-03-19 01:12:21 +000064
65 PlatformSP platform_sp (debugger.GetPlatformList().GetSelectedPlatform ());
Jim Ingham5aee1622010-08-09 23:31:02 +000066
Greg Claytone996fd32011-03-08 22:40:15 +000067 if (file)
Jim Ingham5aee1622010-08-09 23:31:02 +000068 {
69 ModuleSP exe_module_sp;
70 FileSpec resolved_file(file);
Greg Claytone996fd32011-03-08 22:40:15 +000071 ArchSpec platform_arch;
Caroline Tice428a9a52010-09-10 04:48:55 +000072
Greg Claytone996fd32011-03-08 22:40:15 +000073 if (platform_sp)
74 error = platform_sp->ResolveExecutable (file, arch, exe_module_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075
Greg Claytone996fd32011-03-08 22:40:15 +000076 if (error.Success() && exe_module_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077 {
Jim Ingham5aee1622010-08-09 23:31:02 +000078 if (exe_module_sp->GetObjectFile() == NULL)
79 {
Greg Claytonbc5cad62010-12-08 04:55:11 +000080 if (arch.IsValid())
81 {
82 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
83 file.GetDirectory().AsCString(),
84 file.GetDirectory() ? "/" : "",
85 file.GetFilename().AsCString(),
Greg Clayton64195a22011-02-23 00:35:02 +000086 arch.GetArchitectureName());
Greg Claytonbc5cad62010-12-08 04:55:11 +000087 }
88 else
89 {
90 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
91 file.GetDirectory().AsCString(),
92 file.GetDirectory() ? "/" : "",
93 file.GetFilename().AsCString());
94 }
Jim Ingham5aee1622010-08-09 23:31:02 +000095 return error;
96 }
Greg Claytonded470d2011-03-19 01:12:21 +000097 target_sp.reset(new Target(debugger, platform_sp));
Jim Ingham5aee1622010-08-09 23:31:02 +000098 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099 }
Jim Ingham5aee1622010-08-09 23:31:02 +0000100 }
Greg Claytone996fd32011-03-08 22:40:15 +0000101 else
Jim Ingham5aee1622010-08-09 23:31:02 +0000102 {
Greg Claytone996fd32011-03-08 22:40:15 +0000103 // No file was specified, just create an empty target with any arch
104 // if a valid arch was specified
Greg Claytonded470d2011-03-19 01:12:21 +0000105 target_sp.reset(new Target(debugger, platform_sp));
Greg Claytone996fd32011-03-08 22:40:15 +0000106 if (arch.IsValid())
107 target_sp->SetArchitecture(arch);
108 }
109
110 if (target_sp)
111 {
112 target_sp->UpdateInstanceName();
113
Jim Ingham5aee1622010-08-09 23:31:02 +0000114 Mutex::Locker locker(m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000115 m_selected_target_idx = m_target_list.size();
Jim Ingham5aee1622010-08-09 23:31:02 +0000116 m_target_list.push_back(target_sp);
117 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119 return error;
120}
121
122bool
123TargetList::DeleteTarget (TargetSP &target_sp)
124{
125 Mutex::Locker locker(m_target_list_mutex);
126 collection::iterator pos, end = m_target_list.end();
127
128 for (pos = m_target_list.begin(); pos != end; ++pos)
129 {
130 if (pos->get() == target_sp.get())
131 {
132 m_target_list.erase(pos);
133 return true;
134 }
135 }
136 return false;
137}
138
139
140TargetSP
141TargetList::FindTargetWithExecutableAndArchitecture
142(
143 const FileSpec &exe_file_spec,
144 const ArchSpec *exe_arch_ptr
145) const
146{
147 Mutex::Locker locker (m_target_list_mutex);
148 TargetSP target_sp;
149 bool full_match = exe_file_spec.GetDirectory();
150
151 collection::const_iterator pos, end = m_target_list.end();
152 for (pos = m_target_list.begin(); pos != end; ++pos)
153 {
154 ModuleSP module_sp ((*pos)->GetExecutableModule());
155
156 if (module_sp)
157 {
158 if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match))
159 {
160 if (exe_arch_ptr)
161 {
162 if (*exe_arch_ptr != module_sp->GetArchitecture())
163 continue;
164 }
165 target_sp = *pos;
166 break;
167 }
168 }
169 }
170 return target_sp;
171}
172
173TargetSP
174TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
175{
176 Mutex::Locker locker(m_target_list_mutex);
177 TargetSP target_sp;
178 collection::const_iterator pos, end = m_target_list.end();
179 for (pos = m_target_list.begin(); pos != end; ++pos)
180 {
181 Process* process = (*pos)->GetProcessSP().get();
182 if (process && process->GetID() == pid)
183 {
184 target_sp = *pos;
185 break;
186 }
187 }
188 return target_sp;
189}
190
191
192TargetSP
193TargetList::FindTargetWithProcess (Process *process) const
194{
195 TargetSP target_sp;
196 if (process)
197 {
198 Mutex::Locker locker(m_target_list_mutex);
199 collection::const_iterator pos, end = m_target_list.end();
200 for (pos = m_target_list.begin(); pos != end; ++pos)
201 {
202 if (process == (*pos)->GetProcessSP().get())
203 {
204 target_sp = *pos;
205 break;
206 }
207 }
208 }
209 return target_sp;
210}
211
212TargetSP
213TargetList::GetTargetSP (Target *target) const
214{
215 TargetSP target_sp;
216 if (target)
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 (target == (*pos).get())
223 {
224 target_sp = *pos;
225 break;
226 }
227 }
228 }
229 return target_sp;
230}
231
232uint32_t
233TargetList::SendAsyncInterrupt (lldb::pid_t pid)
234{
235 uint32_t num_async_interrupts_sent = 0;
236
237 if (pid != LLDB_INVALID_PROCESS_ID)
238 {
239 TargetSP target_sp(FindTargetWithProcessID (pid));
240 if (target_sp.get())
241 {
242 Process* process = target_sp->GetProcessSP().get();
243 if (process)
244 {
245 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
246 ++num_async_interrupts_sent;
247 }
248 }
249 }
250 else
251 {
252 // We don't have a valid pid to broadcast to, so broadcast to the target
253 // list's async broadcaster...
254 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
255 }
256
257 return num_async_interrupts_sent;
258}
259
260uint32_t
261TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
262{
263 uint32_t num_signals_sent = 0;
264 Process *process = NULL;
265 if (pid == LLDB_INVALID_PROCESS_ID)
266 {
267 // Signal all processes with signal
268 Mutex::Locker locker(m_target_list_mutex);
269 collection::iterator pos, end = m_target_list.end();
270 for (pos = m_target_list.begin(); pos != end; ++pos)
271 {
272 process = (*pos)->GetProcessSP().get();
273 if (process)
274 {
275 if (process->IsAlive())
276 {
277 ++num_signals_sent;
278 process->Signal (signo);
279 }
280 }
281 }
282 }
283 else
284 {
285 // Signal a specific process with signal
286 TargetSP target_sp(FindTargetWithProcessID (pid));
287 if (target_sp.get())
288 {
289 process = target_sp->GetProcessSP().get();
290 if (process)
291 {
292 if (process->IsAlive())
293 {
294 ++num_signals_sent;
295 process->Signal (signo);
296 }
297 }
298 }
299 }
300 return num_signals_sent;
301}
302
303int
304TargetList::GetNumTargets () const
305{
306 Mutex::Locker locker (m_target_list_mutex);
307 return m_target_list.size();
308}
309
310lldb::TargetSP
311TargetList::GetTargetAtIndex (uint32_t idx) const
312{
313 TargetSP target_sp;
314 Mutex::Locker locker (m_target_list_mutex);
315 if (idx < m_target_list.size())
316 target_sp = m_target_list[idx];
317 return target_sp;
318}
319
320uint32_t
Jim Ingham2976d002010-08-26 21:32:51 +0000321TargetList::SetSelectedTarget (Target* target)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322{
323 Mutex::Locker locker (m_target_list_mutex);
324 collection::const_iterator pos,
325 begin = m_target_list.begin(),
326 end = m_target_list.end();
327 for (pos = begin; pos != end; ++pos)
328 {
329 if (pos->get() == target)
330 {
Jim Ingham2976d002010-08-26 21:32:51 +0000331 m_selected_target_idx = std::distance (begin, pos);
332 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 }
334 }
Jim Ingham2976d002010-08-26 21:32:51 +0000335 m_selected_target_idx = 0;
336 return m_selected_target_idx;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337}
338
339lldb::TargetSP
Jim Ingham2976d002010-08-26 21:32:51 +0000340TargetList::GetSelectedTarget ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341{
342 Mutex::Locker locker (m_target_list_mutex);
Jim Ingham2976d002010-08-26 21:32:51 +0000343 if (m_selected_target_idx >= m_target_list.size())
344 m_selected_target_idx = 0;
345 return GetTargetAtIndex (m_selected_target_idx);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346}