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"
15ded470d3SGreg Clayton #include "lldb/Core/Debugger.h"
1630fdc8d8SChris Lattner #include "lldb/Core/Event.h"
1730fdc8d8SChris Lattner #include "lldb/Core/State.h"
1830fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
1930fdc8d8SChris Lattner #include "lldb/Host/Host.h"
20e996fd30SGreg Clayton #include "lldb/Target/Platform.h"
2130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2230fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
2330fdc8d8SChris Lattner 
2430fdc8d8SChris Lattner using namespace lldb;
2530fdc8d8SChris Lattner using namespace lldb_private;
2630fdc8d8SChris Lattner 
2730fdc8d8SChris Lattner 
2830fdc8d8SChris Lattner //----------------------------------------------------------------------
2930fdc8d8SChris Lattner // TargetList constructor
3030fdc8d8SChris Lattner //----------------------------------------------------------------------
3130fdc8d8SChris Lattner TargetList::TargetList() :
3230fdc8d8SChris Lattner     Broadcaster("TargetList"),
3330fdc8d8SChris Lattner     m_target_list(),
3430fdc8d8SChris Lattner     m_target_list_mutex (Mutex::eMutexTypeRecursive),
352976d00aSJim Ingham     m_selected_target_idx (0)
3630fdc8d8SChris Lattner {
3730fdc8d8SChris Lattner }
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner //----------------------------------------------------------------------
4030fdc8d8SChris Lattner // Destructor
4130fdc8d8SChris Lattner //----------------------------------------------------------------------
4230fdc8d8SChris Lattner TargetList::~TargetList()
4330fdc8d8SChris Lattner {
4430fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
4530fdc8d8SChris Lattner     m_target_list.clear();
4630fdc8d8SChris Lattner }
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner Error
4930fdc8d8SChris Lattner TargetList::CreateTarget
5030fdc8d8SChris Lattner (
516611103cSGreg Clayton     Debugger &debugger,
5230fdc8d8SChris Lattner     const FileSpec& file,
5330fdc8d8SChris Lattner     const ArchSpec& arch,
5430fdc8d8SChris Lattner     bool get_dependent_files,
5530fdc8d8SChris Lattner     TargetSP &target_sp
5630fdc8d8SChris Lattner )
5730fdc8d8SChris Lattner {
5830fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
59e996fd30SGreg Clayton                         "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
6030fdc8d8SChris Lattner                         file.GetDirectory().AsCString(),
6130fdc8d8SChris Lattner                         file.GetFilename().AsCString(),
62e996fd30SGreg Clayton                         arch.GetArchitectureName());
635aee162fSJim Ingham     Error error;
645aee162fSJim Ingham 
65ded470d3SGreg Clayton     PlatformSP platform_sp (debugger.GetPlatformList().GetSelectedPlatform ());
66ded470d3SGreg Clayton 
67e996fd30SGreg Clayton     if (file)
685aee162fSJim Ingham     {
6930fdc8d8SChris Lattner         ModuleSP exe_module_sp;
7030fdc8d8SChris Lattner         FileSpec resolved_file(file);
71428a9a58SCaroline Tice 
72e996fd30SGreg Clayton         if (platform_sp)
73e996fd30SGreg Clayton             error = platform_sp->ResolveExecutable (file, arch, exe_module_sp);
74428a9a58SCaroline Tice 
75e996fd30SGreg Clayton         if (error.Success() && exe_module_sp)
7630fdc8d8SChris Lattner         {
775aee162fSJim Ingham             if (exe_module_sp->GetObjectFile() == NULL)
785aee162fSJim Ingham             {
79bc5cad6cSGreg Clayton                 if (arch.IsValid())
80bc5cad6cSGreg Clayton                 {
81bc5cad6cSGreg Clayton                     error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
825aee162fSJim Ingham                                                    file.GetDirectory().AsCString(),
835aee162fSJim Ingham                                                    file.GetDirectory() ? "/" : "",
845aee162fSJim Ingham                                                    file.GetFilename().AsCString(),
8564195a2cSGreg Clayton                                                    arch.GetArchitectureName());
86bc5cad6cSGreg Clayton                 }
87bc5cad6cSGreg Clayton                 else
88bc5cad6cSGreg Clayton                 {
89bc5cad6cSGreg Clayton                     error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
90bc5cad6cSGreg Clayton                                                    file.GetDirectory().AsCString(),
91bc5cad6cSGreg Clayton                                                    file.GetDirectory() ? "/" : "",
92bc5cad6cSGreg Clayton                                                    file.GetFilename().AsCString());
93bc5cad6cSGreg Clayton                 }
945aee162fSJim Ingham                 return error;
955aee162fSJim Ingham             }
9632e0a750SGreg Clayton             target_sp.reset(new Target(debugger, arch, platform_sp));
9730fdc8d8SChris Lattner             target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
985aee162fSJim Ingham         }
995aee162fSJim Ingham     }
100e996fd30SGreg Clayton     else
101e996fd30SGreg Clayton     {
102e996fd30SGreg Clayton         // No file was specified, just create an empty target with any arch
103e996fd30SGreg Clayton         // if a valid arch was specified
10432e0a750SGreg Clayton         target_sp.reset(new Target(debugger, arch, platform_sp));
105e996fd30SGreg Clayton     }
1061559a46bSCaroline Tice 
107e996fd30SGreg Clayton     if (target_sp)
108e996fd30SGreg Clayton     {
1091559a46bSCaroline Tice         target_sp->UpdateInstanceName();
11030fdc8d8SChris Lattner 
11130fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
1122976d00aSJim Ingham         m_selected_target_idx = m_target_list.size();
11330fdc8d8SChris Lattner         m_target_list.push_back(target_sp);
11430fdc8d8SChris Lattner     }
11530fdc8d8SChris Lattner 
11630fdc8d8SChris Lattner     return error;
11730fdc8d8SChris Lattner }
11830fdc8d8SChris Lattner 
11930fdc8d8SChris Lattner bool
12030fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp)
12130fdc8d8SChris Lattner {
12230fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
12330fdc8d8SChris Lattner     collection::iterator pos, end = m_target_list.end();
12430fdc8d8SChris Lattner 
12530fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
12630fdc8d8SChris Lattner     {
12730fdc8d8SChris Lattner         if (pos->get() == target_sp.get())
12830fdc8d8SChris Lattner         {
12930fdc8d8SChris Lattner             m_target_list.erase(pos);
13030fdc8d8SChris Lattner             return true;
13130fdc8d8SChris Lattner         }
13230fdc8d8SChris Lattner     }
13330fdc8d8SChris Lattner     return false;
13430fdc8d8SChris Lattner }
13530fdc8d8SChris Lattner 
13630fdc8d8SChris Lattner 
13730fdc8d8SChris Lattner TargetSP
13830fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture
13930fdc8d8SChris Lattner (
14030fdc8d8SChris Lattner     const FileSpec &exe_file_spec,
14130fdc8d8SChris Lattner     const ArchSpec *exe_arch_ptr
14230fdc8d8SChris Lattner ) const
14330fdc8d8SChris Lattner {
14430fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
14530fdc8d8SChris Lattner     TargetSP target_sp;
14630fdc8d8SChris Lattner     bool full_match = exe_file_spec.GetDirectory();
14730fdc8d8SChris Lattner 
14830fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
14930fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
15030fdc8d8SChris Lattner     {
151*aa149cbdSGreg Clayton         Module *exe_module = (*pos)->GetExecutableModulePointer();
15230fdc8d8SChris Lattner 
153*aa149cbdSGreg Clayton         if (exe_module)
15430fdc8d8SChris Lattner         {
155*aa149cbdSGreg Clayton             if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
15630fdc8d8SChris Lattner             {
15730fdc8d8SChris Lattner                 if (exe_arch_ptr)
15830fdc8d8SChris Lattner                 {
159*aa149cbdSGreg Clayton                     if (*exe_arch_ptr != exe_module->GetArchitecture())
16030fdc8d8SChris Lattner                         continue;
16130fdc8d8SChris Lattner                 }
16230fdc8d8SChris Lattner                 target_sp = *pos;
16330fdc8d8SChris Lattner                 break;
16430fdc8d8SChris Lattner             }
16530fdc8d8SChris Lattner         }
16630fdc8d8SChris Lattner     }
16730fdc8d8SChris Lattner     return target_sp;
16830fdc8d8SChris Lattner }
16930fdc8d8SChris Lattner 
17030fdc8d8SChris Lattner TargetSP
17130fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
17230fdc8d8SChris Lattner {
17330fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
17430fdc8d8SChris Lattner     TargetSP target_sp;
17530fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
17630fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
17730fdc8d8SChris Lattner     {
17830fdc8d8SChris Lattner         Process* process = (*pos)->GetProcessSP().get();
17930fdc8d8SChris Lattner         if (process && process->GetID() == pid)
18030fdc8d8SChris Lattner         {
18130fdc8d8SChris Lattner             target_sp = *pos;
18230fdc8d8SChris Lattner             break;
18330fdc8d8SChris Lattner         }
18430fdc8d8SChris Lattner     }
18530fdc8d8SChris Lattner     return target_sp;
18630fdc8d8SChris Lattner }
18730fdc8d8SChris Lattner 
18830fdc8d8SChris Lattner 
18930fdc8d8SChris Lattner TargetSP
19030fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const
19130fdc8d8SChris Lattner {
19230fdc8d8SChris Lattner     TargetSP target_sp;
19330fdc8d8SChris Lattner     if (process)
19430fdc8d8SChris Lattner     {
19530fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
19630fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
19730fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
19830fdc8d8SChris Lattner         {
19930fdc8d8SChris Lattner             if (process == (*pos)->GetProcessSP().get())
20030fdc8d8SChris Lattner             {
20130fdc8d8SChris Lattner                 target_sp = *pos;
20230fdc8d8SChris Lattner                 break;
20330fdc8d8SChris Lattner             }
20430fdc8d8SChris Lattner         }
20530fdc8d8SChris Lattner     }
20630fdc8d8SChris Lattner     return target_sp;
20730fdc8d8SChris Lattner }
20830fdc8d8SChris Lattner 
20930fdc8d8SChris Lattner TargetSP
21030fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const
21130fdc8d8SChris Lattner {
21230fdc8d8SChris Lattner     TargetSP target_sp;
21330fdc8d8SChris Lattner     if (target)
21430fdc8d8SChris Lattner     {
21530fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
21630fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
21730fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
21830fdc8d8SChris Lattner         {
21930fdc8d8SChris Lattner             if (target == (*pos).get())
22030fdc8d8SChris Lattner             {
22130fdc8d8SChris Lattner                 target_sp = *pos;
22230fdc8d8SChris Lattner                 break;
22330fdc8d8SChris Lattner             }
22430fdc8d8SChris Lattner         }
22530fdc8d8SChris Lattner     }
22630fdc8d8SChris Lattner     return target_sp;
22730fdc8d8SChris Lattner }
22830fdc8d8SChris Lattner 
22930fdc8d8SChris Lattner uint32_t
23030fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid)
23130fdc8d8SChris Lattner {
23230fdc8d8SChris Lattner     uint32_t num_async_interrupts_sent = 0;
23330fdc8d8SChris Lattner 
23430fdc8d8SChris Lattner     if (pid != LLDB_INVALID_PROCESS_ID)
23530fdc8d8SChris Lattner     {
23630fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
23730fdc8d8SChris Lattner         if (target_sp.get())
23830fdc8d8SChris Lattner         {
23930fdc8d8SChris Lattner             Process* process = target_sp->GetProcessSP().get();
24030fdc8d8SChris Lattner             if (process)
24130fdc8d8SChris Lattner             {
24230fdc8d8SChris Lattner                 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
24330fdc8d8SChris Lattner                 ++num_async_interrupts_sent;
24430fdc8d8SChris Lattner             }
24530fdc8d8SChris Lattner         }
24630fdc8d8SChris Lattner     }
24730fdc8d8SChris Lattner     else
24830fdc8d8SChris Lattner     {
24930fdc8d8SChris Lattner         // We don't have a valid pid to broadcast to, so broadcast to the target
25030fdc8d8SChris Lattner         // list's async broadcaster...
25130fdc8d8SChris Lattner         BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
25230fdc8d8SChris Lattner     }
25330fdc8d8SChris Lattner 
25430fdc8d8SChris Lattner     return num_async_interrupts_sent;
25530fdc8d8SChris Lattner }
25630fdc8d8SChris Lattner 
25730fdc8d8SChris Lattner uint32_t
25830fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
25930fdc8d8SChris Lattner {
26030fdc8d8SChris Lattner     uint32_t num_signals_sent = 0;
26130fdc8d8SChris Lattner     Process *process = NULL;
26230fdc8d8SChris Lattner     if (pid == LLDB_INVALID_PROCESS_ID)
26330fdc8d8SChris Lattner     {
26430fdc8d8SChris Lattner         // Signal all processes with signal
26530fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
26630fdc8d8SChris Lattner         collection::iterator pos, end = m_target_list.end();
26730fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
26830fdc8d8SChris Lattner         {
26930fdc8d8SChris Lattner             process = (*pos)->GetProcessSP().get();
27030fdc8d8SChris Lattner             if (process)
27130fdc8d8SChris Lattner             {
27230fdc8d8SChris Lattner                 if (process->IsAlive())
27330fdc8d8SChris Lattner                 {
27430fdc8d8SChris Lattner                     ++num_signals_sent;
27530fdc8d8SChris Lattner                     process->Signal (signo);
27630fdc8d8SChris Lattner                 }
27730fdc8d8SChris Lattner             }
27830fdc8d8SChris Lattner         }
27930fdc8d8SChris Lattner     }
28030fdc8d8SChris Lattner     else
28130fdc8d8SChris Lattner     {
28230fdc8d8SChris Lattner         // Signal a specific process with signal
28330fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
28430fdc8d8SChris Lattner         if (target_sp.get())
28530fdc8d8SChris Lattner         {
28630fdc8d8SChris Lattner             process = target_sp->GetProcessSP().get();
28730fdc8d8SChris Lattner             if (process)
28830fdc8d8SChris Lattner             {
28930fdc8d8SChris Lattner                 if (process->IsAlive())
29030fdc8d8SChris Lattner                 {
29130fdc8d8SChris Lattner                     ++num_signals_sent;
29230fdc8d8SChris Lattner                     process->Signal (signo);
29330fdc8d8SChris Lattner                 }
29430fdc8d8SChris Lattner             }
29530fdc8d8SChris Lattner         }
29630fdc8d8SChris Lattner     }
29730fdc8d8SChris Lattner     return num_signals_sent;
29830fdc8d8SChris Lattner }
29930fdc8d8SChris Lattner 
30030fdc8d8SChris Lattner int
30130fdc8d8SChris Lattner TargetList::GetNumTargets () const
30230fdc8d8SChris Lattner {
30330fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
30430fdc8d8SChris Lattner     return m_target_list.size();
30530fdc8d8SChris Lattner }
30630fdc8d8SChris Lattner 
30730fdc8d8SChris Lattner lldb::TargetSP
30830fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const
30930fdc8d8SChris Lattner {
31030fdc8d8SChris Lattner     TargetSP target_sp;
31130fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
31230fdc8d8SChris Lattner     if (idx < m_target_list.size())
31330fdc8d8SChris Lattner         target_sp = m_target_list[idx];
31430fdc8d8SChris Lattner     return target_sp;
31530fdc8d8SChris Lattner }
31630fdc8d8SChris Lattner 
31730fdc8d8SChris Lattner uint32_t
3182976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target)
31930fdc8d8SChris Lattner {
32030fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
32130fdc8d8SChris Lattner     collection::const_iterator pos,
32230fdc8d8SChris Lattner         begin = m_target_list.begin(),
32330fdc8d8SChris Lattner         end = m_target_list.end();
32430fdc8d8SChris Lattner     for (pos = begin; pos != end; ++pos)
32530fdc8d8SChris Lattner     {
32630fdc8d8SChris Lattner         if (pos->get() == target)
32730fdc8d8SChris Lattner         {
3282976d00aSJim Ingham             m_selected_target_idx = std::distance (begin, pos);
3292976d00aSJim Ingham             return m_selected_target_idx;
33030fdc8d8SChris Lattner         }
33130fdc8d8SChris Lattner     }
3322976d00aSJim Ingham     m_selected_target_idx = 0;
3332976d00aSJim Ingham     return m_selected_target_idx;
33430fdc8d8SChris Lattner }
33530fdc8d8SChris Lattner 
33630fdc8d8SChris Lattner lldb::TargetSP
3372976d00aSJim Ingham TargetList::GetSelectedTarget ()
33830fdc8d8SChris Lattner {
33930fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
3402976d00aSJim Ingham     if (m_selected_target_idx >= m_target_list.size())
3412976d00aSJim Ingham         m_selected_target_idx = 0;
3422976d00aSJim Ingham     return GetTargetAtIndex (m_selected_target_idx);
34330fdc8d8SChris Lattner }
344