130fdc8d8SChris Lattner //===-- TargetList.cpp ------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner // C Includes
1130fdc8d8SChris Lattner // C++ Includes
1230fdc8d8SChris Lattner // Other libraries and framework includes
1330fdc8d8SChris Lattner // Project includes
1430fdc8d8SChris Lattner #include "lldb/Core/Broadcaster.h"
1530fdc8d8SChris Lattner #include "lldb/Core/Event.h"
1630fdc8d8SChris Lattner #include "lldb/Core/State.h"
1730fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
1830fdc8d8SChris Lattner #include "lldb/Host/Host.h"
1930fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2030fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
2130fdc8d8SChris Lattner 
2230fdc8d8SChris Lattner using namespace lldb;
2330fdc8d8SChris Lattner using namespace lldb_private;
2430fdc8d8SChris Lattner 
2530fdc8d8SChris Lattner 
2630fdc8d8SChris Lattner //----------------------------------------------------------------------
2730fdc8d8SChris Lattner // TargetList constructor
2830fdc8d8SChris Lattner //----------------------------------------------------------------------
2930fdc8d8SChris Lattner TargetList::TargetList() :
3030fdc8d8SChris Lattner     Broadcaster("TargetList"),
3130fdc8d8SChris Lattner     m_target_list(),
3230fdc8d8SChris Lattner     m_target_list_mutex (Mutex::eMutexTypeRecursive),
33*2976d00aSJim Ingham     m_selected_target_idx (0)
3430fdc8d8SChris Lattner {
3530fdc8d8SChris Lattner }
3630fdc8d8SChris Lattner 
3730fdc8d8SChris Lattner //----------------------------------------------------------------------
3830fdc8d8SChris Lattner // Destructor
3930fdc8d8SChris Lattner //----------------------------------------------------------------------
4030fdc8d8SChris Lattner TargetList::~TargetList()
4130fdc8d8SChris Lattner {
4230fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
4330fdc8d8SChris Lattner     m_target_list.clear();
4430fdc8d8SChris Lattner }
4530fdc8d8SChris Lattner 
4630fdc8d8SChris Lattner Error
4730fdc8d8SChris Lattner TargetList::CreateTarget
4830fdc8d8SChris Lattner (
496611103cSGreg Clayton     Debugger &debugger,
5030fdc8d8SChris Lattner     const FileSpec& file,
5130fdc8d8SChris Lattner     const ArchSpec& arch,
5230fdc8d8SChris Lattner     const UUID *uuid_ptr,
5330fdc8d8SChris Lattner     bool get_dependent_files,
5430fdc8d8SChris Lattner     TargetSP &target_sp
5530fdc8d8SChris Lattner )
5630fdc8d8SChris Lattner {
5730fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
5830fdc8d8SChris Lattner                         "TargetList::CreateTarget (file = '%s/%s', arch = '%s', uuid = %p)",
5930fdc8d8SChris Lattner                         file.GetDirectory().AsCString(),
6030fdc8d8SChris Lattner                         file.GetFilename().AsCString(),
6130fdc8d8SChris Lattner                         arch.AsCString(),
6230fdc8d8SChris Lattner                         uuid_ptr);
635aee162fSJim Ingham     Error error;
645aee162fSJim Ingham 
655aee162fSJim Ingham     if (!file)
665aee162fSJim Ingham     {
675aee162fSJim Ingham         target_sp.reset(new Target(debugger));
685aee162fSJim Ingham         target_sp->SetArchitecture(arch);
695aee162fSJim Ingham     }
705aee162fSJim Ingham     else
715aee162fSJim Ingham     {
7230fdc8d8SChris Lattner         ModuleSP exe_module_sp;
7330fdc8d8SChris Lattner         FileSpec resolved_file(file);
7430fdc8d8SChris Lattner         if (!Host::ResolveExecutableInBundle (&resolved_file))
7530fdc8d8SChris Lattner             resolved_file = file;
7630fdc8d8SChris Lattner 
775aee162fSJim Ingham         error = ModuleList::GetSharedModule(resolved_file,
7830fdc8d8SChris Lattner                                                   arch,
7930fdc8d8SChris Lattner                                                   uuid_ptr,
8030fdc8d8SChris Lattner                                                   NULL,
8130fdc8d8SChris Lattner                                                   0,
8230fdc8d8SChris Lattner                                                   exe_module_sp,
8330fdc8d8SChris Lattner                                                   NULL,
8430fdc8d8SChris Lattner                                                   NULL);
8530fdc8d8SChris Lattner         if (exe_module_sp)
8630fdc8d8SChris Lattner         {
875aee162fSJim Ingham             if (exe_module_sp->GetObjectFile() == NULL)
885aee162fSJim Ingham             {
895aee162fSJim Ingham                 error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
905aee162fSJim Ingham                                                file.GetDirectory().AsCString(),
915aee162fSJim Ingham                                                file.GetDirectory() ? "/" : "",
925aee162fSJim Ingham                                                file.GetFilename().AsCString(),
935aee162fSJim Ingham                                                arch.AsCString());
945aee162fSJim Ingham                 return error;
955aee162fSJim Ingham             }
966611103cSGreg Clayton             target_sp.reset(new Target(debugger));
9730fdc8d8SChris Lattner             target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
985aee162fSJim Ingham         }
995aee162fSJim Ingham     }
10030fdc8d8SChris Lattner 
10130fdc8d8SChris Lattner     if (target_sp.get())
10230fdc8d8SChris Lattner     {
10330fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
104*2976d00aSJim Ingham         m_selected_target_idx = m_target_list.size();
10530fdc8d8SChris Lattner         m_target_list.push_back(target_sp);
10630fdc8d8SChris Lattner     }
10730fdc8d8SChris Lattner 
10830fdc8d8SChris Lattner //        target_sp.reset(new Target);
10930fdc8d8SChris Lattner //        // Let the target resolve any funky bundle paths before we try and get
11030fdc8d8SChris Lattner //        // the object file...
11130fdc8d8SChris Lattner //        target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
11230fdc8d8SChris Lattner //        if (exe_module_sp->GetObjectFile() == NULL)
11330fdc8d8SChris Lattner //        {
11430fdc8d8SChris Lattner //            error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s",
11530fdc8d8SChris Lattner //                                           file.GetDirectory().AsCString(),
11630fdc8d8SChris Lattner //                                           file.GetDirectory() ? "/" : "",
11730fdc8d8SChris Lattner //                                           file.GetFilename().AsCString(),
11830fdc8d8SChris Lattner //                                           arch.AsCString());
11930fdc8d8SChris Lattner //        }
12030fdc8d8SChris Lattner //        else
12130fdc8d8SChris Lattner //        {
12230fdc8d8SChris Lattner //            if (target_sp.get())
12330fdc8d8SChris Lattner //            {
12430fdc8d8SChris Lattner //                error.Clear();
12530fdc8d8SChris Lattner //                Mutex::Locker locker(m_target_list_mutex);
126*2976d00aSJim Ingham //                m_selected_target_idx = m_target_list.size();
12730fdc8d8SChris Lattner //                m_target_list.push_back(target_sp);
12830fdc8d8SChris Lattner //            }
12930fdc8d8SChris Lattner //        }
13030fdc8d8SChris Lattner     else
13130fdc8d8SChris Lattner     {
13230fdc8d8SChris Lattner         target_sp.reset();
13330fdc8d8SChris Lattner     }
13430fdc8d8SChris Lattner 
13530fdc8d8SChris Lattner     return error;
13630fdc8d8SChris Lattner }
13730fdc8d8SChris Lattner 
13830fdc8d8SChris Lattner bool
13930fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp)
14030fdc8d8SChris Lattner {
14130fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
14230fdc8d8SChris Lattner     collection::iterator pos, end = m_target_list.end();
14330fdc8d8SChris Lattner 
14430fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
14530fdc8d8SChris Lattner     {
14630fdc8d8SChris Lattner         if (pos->get() == target_sp.get())
14730fdc8d8SChris Lattner         {
14830fdc8d8SChris Lattner             m_target_list.erase(pos);
14930fdc8d8SChris Lattner             return true;
15030fdc8d8SChris Lattner         }
15130fdc8d8SChris Lattner     }
15230fdc8d8SChris Lattner     return false;
15330fdc8d8SChris Lattner }
15430fdc8d8SChris Lattner 
15530fdc8d8SChris Lattner 
15630fdc8d8SChris Lattner TargetSP
15730fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture
15830fdc8d8SChris Lattner (
15930fdc8d8SChris Lattner     const FileSpec &exe_file_spec,
16030fdc8d8SChris Lattner     const ArchSpec *exe_arch_ptr
16130fdc8d8SChris Lattner ) const
16230fdc8d8SChris Lattner {
16330fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
16430fdc8d8SChris Lattner     TargetSP target_sp;
16530fdc8d8SChris Lattner     bool full_match = exe_file_spec.GetDirectory();
16630fdc8d8SChris Lattner 
16730fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
16830fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
16930fdc8d8SChris Lattner     {
17030fdc8d8SChris Lattner         ModuleSP module_sp ((*pos)->GetExecutableModule());
17130fdc8d8SChris Lattner 
17230fdc8d8SChris Lattner         if (module_sp)
17330fdc8d8SChris Lattner         {
17430fdc8d8SChris Lattner             if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match))
17530fdc8d8SChris Lattner             {
17630fdc8d8SChris Lattner                 if (exe_arch_ptr)
17730fdc8d8SChris Lattner                 {
17830fdc8d8SChris Lattner                     if (*exe_arch_ptr != module_sp->GetArchitecture())
17930fdc8d8SChris Lattner                         continue;
18030fdc8d8SChris Lattner                 }
18130fdc8d8SChris Lattner                 target_sp = *pos;
18230fdc8d8SChris Lattner                 break;
18330fdc8d8SChris Lattner             }
18430fdc8d8SChris Lattner         }
18530fdc8d8SChris Lattner     }
18630fdc8d8SChris Lattner     return target_sp;
18730fdc8d8SChris Lattner }
18830fdc8d8SChris Lattner 
18930fdc8d8SChris Lattner TargetSP
19030fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
19130fdc8d8SChris Lattner {
19230fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
19330fdc8d8SChris Lattner     TargetSP target_sp;
19430fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
19530fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
19630fdc8d8SChris Lattner     {
19730fdc8d8SChris Lattner         Process* process = (*pos)->GetProcessSP().get();
19830fdc8d8SChris Lattner         if (process && process->GetID() == pid)
19930fdc8d8SChris Lattner         {
20030fdc8d8SChris Lattner             target_sp = *pos;
20130fdc8d8SChris Lattner             break;
20230fdc8d8SChris Lattner         }
20330fdc8d8SChris Lattner     }
20430fdc8d8SChris Lattner     return target_sp;
20530fdc8d8SChris Lattner }
20630fdc8d8SChris Lattner 
20730fdc8d8SChris Lattner 
20830fdc8d8SChris Lattner TargetSP
20930fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const
21030fdc8d8SChris Lattner {
21130fdc8d8SChris Lattner     TargetSP target_sp;
21230fdc8d8SChris Lattner     if (process)
21330fdc8d8SChris Lattner     {
21430fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
21530fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
21630fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
21730fdc8d8SChris Lattner         {
21830fdc8d8SChris Lattner             if (process == (*pos)->GetProcessSP().get())
21930fdc8d8SChris Lattner             {
22030fdc8d8SChris Lattner                 target_sp = *pos;
22130fdc8d8SChris Lattner                 break;
22230fdc8d8SChris Lattner             }
22330fdc8d8SChris Lattner         }
22430fdc8d8SChris Lattner     }
22530fdc8d8SChris Lattner     return target_sp;
22630fdc8d8SChris Lattner }
22730fdc8d8SChris Lattner 
22830fdc8d8SChris Lattner TargetSP
22930fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const
23030fdc8d8SChris Lattner {
23130fdc8d8SChris Lattner     TargetSP target_sp;
23230fdc8d8SChris Lattner     if (target)
23330fdc8d8SChris Lattner     {
23430fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
23530fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
23630fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
23730fdc8d8SChris Lattner         {
23830fdc8d8SChris Lattner             if (target == (*pos).get())
23930fdc8d8SChris Lattner             {
24030fdc8d8SChris Lattner                 target_sp = *pos;
24130fdc8d8SChris Lattner                 break;
24230fdc8d8SChris Lattner             }
24330fdc8d8SChris Lattner         }
24430fdc8d8SChris Lattner     }
24530fdc8d8SChris Lattner     return target_sp;
24630fdc8d8SChris Lattner }
24730fdc8d8SChris Lattner 
24830fdc8d8SChris Lattner uint32_t
24930fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid)
25030fdc8d8SChris Lattner {
25130fdc8d8SChris Lattner     uint32_t num_async_interrupts_sent = 0;
25230fdc8d8SChris Lattner 
25330fdc8d8SChris Lattner     if (pid != LLDB_INVALID_PROCESS_ID)
25430fdc8d8SChris Lattner     {
25530fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
25630fdc8d8SChris Lattner         if (target_sp.get())
25730fdc8d8SChris Lattner         {
25830fdc8d8SChris Lattner             Process* process = target_sp->GetProcessSP().get();
25930fdc8d8SChris Lattner             if (process)
26030fdc8d8SChris Lattner             {
26130fdc8d8SChris Lattner                 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
26230fdc8d8SChris Lattner                 ++num_async_interrupts_sent;
26330fdc8d8SChris Lattner             }
26430fdc8d8SChris Lattner         }
26530fdc8d8SChris Lattner     }
26630fdc8d8SChris Lattner     else
26730fdc8d8SChris Lattner     {
26830fdc8d8SChris Lattner         // We don't have a valid pid to broadcast to, so broadcast to the target
26930fdc8d8SChris Lattner         // list's async broadcaster...
27030fdc8d8SChris Lattner         BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
27130fdc8d8SChris Lattner     }
27230fdc8d8SChris Lattner 
27330fdc8d8SChris Lattner     return num_async_interrupts_sent;
27430fdc8d8SChris Lattner }
27530fdc8d8SChris Lattner 
27630fdc8d8SChris Lattner uint32_t
27730fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
27830fdc8d8SChris Lattner {
27930fdc8d8SChris Lattner     uint32_t num_signals_sent = 0;
28030fdc8d8SChris Lattner     Process *process = NULL;
28130fdc8d8SChris Lattner     if (pid == LLDB_INVALID_PROCESS_ID)
28230fdc8d8SChris Lattner     {
28330fdc8d8SChris Lattner         // Signal all processes with signal
28430fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
28530fdc8d8SChris Lattner         collection::iterator pos, end = m_target_list.end();
28630fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
28730fdc8d8SChris Lattner         {
28830fdc8d8SChris Lattner             process = (*pos)->GetProcessSP().get();
28930fdc8d8SChris Lattner             if (process)
29030fdc8d8SChris Lattner             {
29130fdc8d8SChris Lattner                 if (process->IsAlive())
29230fdc8d8SChris Lattner                 {
29330fdc8d8SChris Lattner                     ++num_signals_sent;
29430fdc8d8SChris Lattner                     process->Signal (signo);
29530fdc8d8SChris Lattner                 }
29630fdc8d8SChris Lattner             }
29730fdc8d8SChris Lattner         }
29830fdc8d8SChris Lattner     }
29930fdc8d8SChris Lattner     else
30030fdc8d8SChris Lattner     {
30130fdc8d8SChris Lattner         // Signal a specific process with signal
30230fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
30330fdc8d8SChris Lattner         if (target_sp.get())
30430fdc8d8SChris Lattner         {
30530fdc8d8SChris Lattner             process = target_sp->GetProcessSP().get();
30630fdc8d8SChris Lattner             if (process)
30730fdc8d8SChris Lattner             {
30830fdc8d8SChris Lattner                 if (process->IsAlive())
30930fdc8d8SChris Lattner                 {
31030fdc8d8SChris Lattner                     ++num_signals_sent;
31130fdc8d8SChris Lattner                     process->Signal (signo);
31230fdc8d8SChris Lattner                 }
31330fdc8d8SChris Lattner             }
31430fdc8d8SChris Lattner         }
31530fdc8d8SChris Lattner     }
31630fdc8d8SChris Lattner     return num_signals_sent;
31730fdc8d8SChris Lattner }
31830fdc8d8SChris Lattner 
31930fdc8d8SChris Lattner int
32030fdc8d8SChris Lattner TargetList::GetNumTargets () const
32130fdc8d8SChris Lattner {
32230fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
32330fdc8d8SChris Lattner     return m_target_list.size();
32430fdc8d8SChris Lattner }
32530fdc8d8SChris Lattner 
32630fdc8d8SChris Lattner lldb::TargetSP
32730fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const
32830fdc8d8SChris Lattner {
32930fdc8d8SChris Lattner     TargetSP target_sp;
33030fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
33130fdc8d8SChris Lattner     if (idx < m_target_list.size())
33230fdc8d8SChris Lattner         target_sp = m_target_list[idx];
33330fdc8d8SChris Lattner     return target_sp;
33430fdc8d8SChris Lattner }
33530fdc8d8SChris Lattner 
33630fdc8d8SChris Lattner uint32_t
337*2976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target)
33830fdc8d8SChris Lattner {
33930fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
34030fdc8d8SChris Lattner     collection::const_iterator pos,
34130fdc8d8SChris Lattner         begin = m_target_list.begin(),
34230fdc8d8SChris Lattner         end = m_target_list.end();
34330fdc8d8SChris Lattner     for (pos = begin; pos != end; ++pos)
34430fdc8d8SChris Lattner     {
34530fdc8d8SChris Lattner         if (pos->get() == target)
34630fdc8d8SChris Lattner         {
347*2976d00aSJim Ingham             m_selected_target_idx = std::distance (begin, pos);
348*2976d00aSJim Ingham             return m_selected_target_idx;
34930fdc8d8SChris Lattner         }
35030fdc8d8SChris Lattner     }
351*2976d00aSJim Ingham     m_selected_target_idx = 0;
352*2976d00aSJim Ingham     return m_selected_target_idx;
35330fdc8d8SChris Lattner }
35430fdc8d8SChris Lattner 
35530fdc8d8SChris Lattner lldb::TargetSP
356*2976d00aSJim Ingham TargetList::GetSelectedTarget ()
35730fdc8d8SChris Lattner {
35830fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
359*2976d00aSJim Ingham     if (m_selected_target_idx >= m_target_list.size())
360*2976d00aSJim Ingham         m_selected_target_idx = 0;
361*2976d00aSJim Ingham     return GetTargetAtIndex (m_selected_target_idx);
36230fdc8d8SChris Lattner }
363