1*30fdc8d8SChris Lattner //===-- TargetList.cpp ------------------------------------------*- C++ -*-===//
2*30fdc8d8SChris Lattner //
3*30fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
4*30fdc8d8SChris Lattner //
5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
7*30fdc8d8SChris Lattner //
8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
9*30fdc8d8SChris Lattner 
10*30fdc8d8SChris Lattner // C Includes
11*30fdc8d8SChris Lattner // C++ Includes
12*30fdc8d8SChris Lattner // Other libraries and framework includes
13*30fdc8d8SChris Lattner // Project includes
14*30fdc8d8SChris Lattner #include "lldb/Core/Broadcaster.h"
15*30fdc8d8SChris Lattner #include "lldb/Core/Event.h"
16*30fdc8d8SChris Lattner #include "lldb/Core/State.h"
17*30fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
18*30fdc8d8SChris Lattner #include "lldb/Host/Host.h"
19*30fdc8d8SChris Lattner #include "lldb/Target/Process.h"
20*30fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
21*30fdc8d8SChris Lattner 
22*30fdc8d8SChris Lattner using namespace lldb;
23*30fdc8d8SChris Lattner using namespace lldb_private;
24*30fdc8d8SChris Lattner 
25*30fdc8d8SChris Lattner 
26*30fdc8d8SChris Lattner //----------------------------------------------------------------------
27*30fdc8d8SChris Lattner // TargetList constructor
28*30fdc8d8SChris Lattner //----------------------------------------------------------------------
29*30fdc8d8SChris Lattner TargetList::TargetList() :
30*30fdc8d8SChris Lattner     Broadcaster("TargetList"),
31*30fdc8d8SChris Lattner     m_target_list(),
32*30fdc8d8SChris Lattner     m_target_list_mutex (Mutex::eMutexTypeRecursive),
33*30fdc8d8SChris Lattner     m_current_target_idx (0)
34*30fdc8d8SChris Lattner {
35*30fdc8d8SChris Lattner }
36*30fdc8d8SChris Lattner 
37*30fdc8d8SChris Lattner //----------------------------------------------------------------------
38*30fdc8d8SChris Lattner // Destructor
39*30fdc8d8SChris Lattner //----------------------------------------------------------------------
40*30fdc8d8SChris Lattner TargetList::~TargetList()
41*30fdc8d8SChris Lattner {
42*30fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
43*30fdc8d8SChris Lattner     m_target_list.clear();
44*30fdc8d8SChris Lattner }
45*30fdc8d8SChris Lattner 
46*30fdc8d8SChris Lattner Error
47*30fdc8d8SChris Lattner TargetList::CreateTarget
48*30fdc8d8SChris Lattner (
49*30fdc8d8SChris Lattner     const FileSpec& file,
50*30fdc8d8SChris Lattner     const ArchSpec& arch,
51*30fdc8d8SChris Lattner     const UUID *uuid_ptr,
52*30fdc8d8SChris Lattner     bool get_dependent_files,
53*30fdc8d8SChris Lattner     TargetSP &target_sp
54*30fdc8d8SChris Lattner )
55*30fdc8d8SChris Lattner {
56*30fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
57*30fdc8d8SChris Lattner                         "TargetList::CreateTarget (file = '%s/%s', arch = '%s', uuid = %p)",
58*30fdc8d8SChris Lattner                         file.GetDirectory().AsCString(),
59*30fdc8d8SChris Lattner                         file.GetFilename().AsCString(),
60*30fdc8d8SChris Lattner                         arch.AsCString(),
61*30fdc8d8SChris Lattner                         uuid_ptr);
62*30fdc8d8SChris Lattner     ModuleSP exe_module_sp;
63*30fdc8d8SChris Lattner     FileSpec resolved_file(file);
64*30fdc8d8SChris Lattner     if (!Host::ResolveExecutableInBundle (&resolved_file))
65*30fdc8d8SChris Lattner         resolved_file = file;
66*30fdc8d8SChris Lattner 
67*30fdc8d8SChris Lattner     Error error = ModuleList::GetSharedModule(resolved_file,
68*30fdc8d8SChris Lattner                                               arch,
69*30fdc8d8SChris Lattner                                               uuid_ptr,
70*30fdc8d8SChris Lattner                                               NULL,
71*30fdc8d8SChris Lattner                                               0,
72*30fdc8d8SChris Lattner                                               exe_module_sp,
73*30fdc8d8SChris Lattner                                               NULL,
74*30fdc8d8SChris Lattner                                               NULL);
75*30fdc8d8SChris Lattner     if (exe_module_sp)
76*30fdc8d8SChris Lattner     {
77*30fdc8d8SChris Lattner         target_sp.reset(new Target);
78*30fdc8d8SChris Lattner         target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
79*30fdc8d8SChris Lattner 
80*30fdc8d8SChris Lattner         if (target_sp.get())
81*30fdc8d8SChris Lattner         {
82*30fdc8d8SChris Lattner             Mutex::Locker locker(m_target_list_mutex);
83*30fdc8d8SChris Lattner             m_current_target_idx = m_target_list.size();
84*30fdc8d8SChris Lattner             m_target_list.push_back(target_sp);
85*30fdc8d8SChris Lattner         }
86*30fdc8d8SChris Lattner 
87*30fdc8d8SChris Lattner //        target_sp.reset(new Target);
88*30fdc8d8SChris Lattner //        // Let the target resolve any funky bundle paths before we try and get
89*30fdc8d8SChris Lattner //        // the object file...
90*30fdc8d8SChris Lattner //        target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
91*30fdc8d8SChris Lattner //        if (exe_module_sp->GetObjectFile() == NULL)
92*30fdc8d8SChris Lattner //        {
93*30fdc8d8SChris Lattner //            error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
94*30fdc8d8SChris Lattner //                                           file.GetDirectory().AsCString(),
95*30fdc8d8SChris Lattner //                                           file.GetDirectory() ? "/" : "",
96*30fdc8d8SChris Lattner //                                           file.GetFilename().AsCString(),
97*30fdc8d8SChris Lattner //                                           arch.AsCString());
98*30fdc8d8SChris Lattner //        }
99*30fdc8d8SChris Lattner //        else
100*30fdc8d8SChris Lattner //        {
101*30fdc8d8SChris Lattner //            if (target_sp.get())
102*30fdc8d8SChris Lattner //            {
103*30fdc8d8SChris Lattner //                error.Clear();
104*30fdc8d8SChris Lattner //                Mutex::Locker locker(m_target_list_mutex);
105*30fdc8d8SChris Lattner //                m_current_target_idx = m_target_list.size();
106*30fdc8d8SChris Lattner //                m_target_list.push_back(target_sp);
107*30fdc8d8SChris Lattner //            }
108*30fdc8d8SChris Lattner //        }
109*30fdc8d8SChris Lattner     }
110*30fdc8d8SChris Lattner     else
111*30fdc8d8SChris Lattner     {
112*30fdc8d8SChris Lattner         target_sp.reset();
113*30fdc8d8SChris Lattner     }
114*30fdc8d8SChris Lattner 
115*30fdc8d8SChris Lattner     return error;
116*30fdc8d8SChris Lattner }
117*30fdc8d8SChris Lattner 
118*30fdc8d8SChris Lattner bool
119*30fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp)
120*30fdc8d8SChris Lattner {
121*30fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
122*30fdc8d8SChris Lattner     collection::iterator pos, end = m_target_list.end();
123*30fdc8d8SChris Lattner 
124*30fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
125*30fdc8d8SChris Lattner     {
126*30fdc8d8SChris Lattner         if (pos->get() == target_sp.get())
127*30fdc8d8SChris Lattner         {
128*30fdc8d8SChris Lattner             m_target_list.erase(pos);
129*30fdc8d8SChris Lattner             return true;
130*30fdc8d8SChris Lattner         }
131*30fdc8d8SChris Lattner     }
132*30fdc8d8SChris Lattner     return false;
133*30fdc8d8SChris Lattner }
134*30fdc8d8SChris Lattner 
135*30fdc8d8SChris Lattner 
136*30fdc8d8SChris Lattner TargetSP
137*30fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture
138*30fdc8d8SChris Lattner (
139*30fdc8d8SChris Lattner     const FileSpec &exe_file_spec,
140*30fdc8d8SChris Lattner     const ArchSpec *exe_arch_ptr
141*30fdc8d8SChris Lattner ) const
142*30fdc8d8SChris Lattner {
143*30fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
144*30fdc8d8SChris Lattner     TargetSP target_sp;
145*30fdc8d8SChris Lattner     bool full_match = exe_file_spec.GetDirectory();
146*30fdc8d8SChris Lattner 
147*30fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
148*30fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
149*30fdc8d8SChris Lattner     {
150*30fdc8d8SChris Lattner         ModuleSP module_sp ((*pos)->GetExecutableModule());
151*30fdc8d8SChris Lattner 
152*30fdc8d8SChris Lattner         if (module_sp)
153*30fdc8d8SChris Lattner         {
154*30fdc8d8SChris Lattner             if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match))
155*30fdc8d8SChris Lattner             {
156*30fdc8d8SChris Lattner                 if (exe_arch_ptr)
157*30fdc8d8SChris Lattner                 {
158*30fdc8d8SChris Lattner                     if (*exe_arch_ptr != module_sp->GetArchitecture())
159*30fdc8d8SChris Lattner                         continue;
160*30fdc8d8SChris Lattner                 }
161*30fdc8d8SChris Lattner                 target_sp = *pos;
162*30fdc8d8SChris Lattner                 break;
163*30fdc8d8SChris Lattner             }
164*30fdc8d8SChris Lattner         }
165*30fdc8d8SChris Lattner     }
166*30fdc8d8SChris Lattner     return target_sp;
167*30fdc8d8SChris Lattner }
168*30fdc8d8SChris Lattner 
169*30fdc8d8SChris Lattner TargetSP
170*30fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
171*30fdc8d8SChris Lattner {
172*30fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
173*30fdc8d8SChris Lattner     TargetSP target_sp;
174*30fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
175*30fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
176*30fdc8d8SChris Lattner     {
177*30fdc8d8SChris Lattner         Process* process = (*pos)->GetProcessSP().get();
178*30fdc8d8SChris Lattner         if (process && process->GetID() == pid)
179*30fdc8d8SChris Lattner         {
180*30fdc8d8SChris Lattner             target_sp = *pos;
181*30fdc8d8SChris Lattner             break;
182*30fdc8d8SChris Lattner         }
183*30fdc8d8SChris Lattner     }
184*30fdc8d8SChris Lattner     return target_sp;
185*30fdc8d8SChris Lattner }
186*30fdc8d8SChris Lattner 
187*30fdc8d8SChris Lattner 
188*30fdc8d8SChris Lattner TargetSP
189*30fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const
190*30fdc8d8SChris Lattner {
191*30fdc8d8SChris Lattner     TargetSP target_sp;
192*30fdc8d8SChris Lattner     if (process)
193*30fdc8d8SChris Lattner     {
194*30fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
195*30fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
196*30fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
197*30fdc8d8SChris Lattner         {
198*30fdc8d8SChris Lattner             if (process == (*pos)->GetProcessSP().get())
199*30fdc8d8SChris Lattner             {
200*30fdc8d8SChris Lattner                 target_sp = *pos;
201*30fdc8d8SChris Lattner                 break;
202*30fdc8d8SChris Lattner             }
203*30fdc8d8SChris Lattner         }
204*30fdc8d8SChris Lattner     }
205*30fdc8d8SChris Lattner     return target_sp;
206*30fdc8d8SChris Lattner }
207*30fdc8d8SChris Lattner 
208*30fdc8d8SChris Lattner TargetSP
209*30fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const
210*30fdc8d8SChris Lattner {
211*30fdc8d8SChris Lattner     TargetSP target_sp;
212*30fdc8d8SChris Lattner     if (target)
213*30fdc8d8SChris Lattner     {
214*30fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
215*30fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
216*30fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
217*30fdc8d8SChris Lattner         {
218*30fdc8d8SChris Lattner             if (target == (*pos).get())
219*30fdc8d8SChris Lattner             {
220*30fdc8d8SChris Lattner                 target_sp = *pos;
221*30fdc8d8SChris Lattner                 break;
222*30fdc8d8SChris Lattner             }
223*30fdc8d8SChris Lattner         }
224*30fdc8d8SChris Lattner     }
225*30fdc8d8SChris Lattner     return target_sp;
226*30fdc8d8SChris Lattner }
227*30fdc8d8SChris Lattner 
228*30fdc8d8SChris Lattner uint32_t
229*30fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid)
230*30fdc8d8SChris Lattner {
231*30fdc8d8SChris Lattner     uint32_t num_async_interrupts_sent = 0;
232*30fdc8d8SChris Lattner 
233*30fdc8d8SChris Lattner     if (pid != LLDB_INVALID_PROCESS_ID)
234*30fdc8d8SChris Lattner     {
235*30fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
236*30fdc8d8SChris Lattner         if (target_sp.get())
237*30fdc8d8SChris Lattner         {
238*30fdc8d8SChris Lattner             Process* process = target_sp->GetProcessSP().get();
239*30fdc8d8SChris Lattner             if (process)
240*30fdc8d8SChris Lattner             {
241*30fdc8d8SChris Lattner                 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
242*30fdc8d8SChris Lattner                 ++num_async_interrupts_sent;
243*30fdc8d8SChris Lattner             }
244*30fdc8d8SChris Lattner         }
245*30fdc8d8SChris Lattner     }
246*30fdc8d8SChris Lattner     else
247*30fdc8d8SChris Lattner     {
248*30fdc8d8SChris Lattner         // We don't have a valid pid to broadcast to, so broadcast to the target
249*30fdc8d8SChris Lattner         // list's async broadcaster...
250*30fdc8d8SChris Lattner         BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
251*30fdc8d8SChris Lattner     }
252*30fdc8d8SChris Lattner 
253*30fdc8d8SChris Lattner     return num_async_interrupts_sent;
254*30fdc8d8SChris Lattner }
255*30fdc8d8SChris Lattner 
256*30fdc8d8SChris Lattner uint32_t
257*30fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
258*30fdc8d8SChris Lattner {
259*30fdc8d8SChris Lattner     uint32_t num_signals_sent = 0;
260*30fdc8d8SChris Lattner     Process *process = NULL;
261*30fdc8d8SChris Lattner     if (pid == LLDB_INVALID_PROCESS_ID)
262*30fdc8d8SChris Lattner     {
263*30fdc8d8SChris Lattner         // Signal all processes with signal
264*30fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
265*30fdc8d8SChris Lattner         collection::iterator pos, end = m_target_list.end();
266*30fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
267*30fdc8d8SChris Lattner         {
268*30fdc8d8SChris Lattner             process = (*pos)->GetProcessSP().get();
269*30fdc8d8SChris Lattner             if (process)
270*30fdc8d8SChris Lattner             {
271*30fdc8d8SChris Lattner                 if (process->IsAlive())
272*30fdc8d8SChris Lattner                 {
273*30fdc8d8SChris Lattner                     ++num_signals_sent;
274*30fdc8d8SChris Lattner                     process->Signal (signo);
275*30fdc8d8SChris Lattner                 }
276*30fdc8d8SChris Lattner             }
277*30fdc8d8SChris Lattner         }
278*30fdc8d8SChris Lattner     }
279*30fdc8d8SChris Lattner     else
280*30fdc8d8SChris Lattner     {
281*30fdc8d8SChris Lattner         // Signal a specific process with signal
282*30fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
283*30fdc8d8SChris Lattner         if (target_sp.get())
284*30fdc8d8SChris Lattner         {
285*30fdc8d8SChris Lattner             process = target_sp->GetProcessSP().get();
286*30fdc8d8SChris Lattner             if (process)
287*30fdc8d8SChris Lattner             {
288*30fdc8d8SChris Lattner                 if (process->IsAlive())
289*30fdc8d8SChris Lattner                 {
290*30fdc8d8SChris Lattner                     ++num_signals_sent;
291*30fdc8d8SChris Lattner                     process->Signal (signo);
292*30fdc8d8SChris Lattner                 }
293*30fdc8d8SChris Lattner             }
294*30fdc8d8SChris Lattner         }
295*30fdc8d8SChris Lattner     }
296*30fdc8d8SChris Lattner     return num_signals_sent;
297*30fdc8d8SChris Lattner }
298*30fdc8d8SChris Lattner 
299*30fdc8d8SChris Lattner int
300*30fdc8d8SChris Lattner TargetList::GetNumTargets () const
301*30fdc8d8SChris Lattner {
302*30fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
303*30fdc8d8SChris Lattner     return m_target_list.size();
304*30fdc8d8SChris Lattner }
305*30fdc8d8SChris Lattner 
306*30fdc8d8SChris Lattner lldb::TargetSP
307*30fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const
308*30fdc8d8SChris Lattner {
309*30fdc8d8SChris Lattner     TargetSP target_sp;
310*30fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
311*30fdc8d8SChris Lattner     if (idx < m_target_list.size())
312*30fdc8d8SChris Lattner         target_sp = m_target_list[idx];
313*30fdc8d8SChris Lattner     return target_sp;
314*30fdc8d8SChris Lattner }
315*30fdc8d8SChris Lattner 
316*30fdc8d8SChris Lattner uint32_t
317*30fdc8d8SChris Lattner TargetList::SetCurrentTarget (Target* target)
318*30fdc8d8SChris Lattner {
319*30fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
320*30fdc8d8SChris Lattner     collection::const_iterator pos,
321*30fdc8d8SChris Lattner         begin = m_target_list.begin(),
322*30fdc8d8SChris Lattner         end = m_target_list.end();
323*30fdc8d8SChris Lattner     for (pos = begin; pos != end; ++pos)
324*30fdc8d8SChris Lattner     {
325*30fdc8d8SChris Lattner         if (pos->get() == target)
326*30fdc8d8SChris Lattner         {
327*30fdc8d8SChris Lattner             m_current_target_idx = std::distance (begin, pos);
328*30fdc8d8SChris Lattner             return m_current_target_idx;
329*30fdc8d8SChris Lattner         }
330*30fdc8d8SChris Lattner     }
331*30fdc8d8SChris Lattner     m_current_target_idx = 0;
332*30fdc8d8SChris Lattner     return m_current_target_idx;
333*30fdc8d8SChris Lattner }
334*30fdc8d8SChris Lattner 
335*30fdc8d8SChris Lattner lldb::TargetSP
336*30fdc8d8SChris Lattner TargetList::GetCurrentTarget ()
337*30fdc8d8SChris Lattner {
338*30fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
339*30fdc8d8SChris Lattner     if (m_current_target_idx >= m_target_list.size())
340*30fdc8d8SChris Lattner         m_current_target_idx = 0;
341*30fdc8d8SChris Lattner     return GetTargetAtIndex (m_current_target_idx);
342*30fdc8d8SChris Lattner }
343