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"
20cac9c5f9SGreg Clayton #include "lldb/Interpreter/OptionGroupPlatform.h"
21e996fd30SGreg Clayton #include "lldb/Target/Platform.h"
2230fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2330fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
2430fdc8d8SChris Lattner 
2530fdc8d8SChris Lattner using namespace lldb;
2630fdc8d8SChris Lattner using namespace lldb_private;
2730fdc8d8SChris Lattner 
2830fdc8d8SChris Lattner 
2930fdc8d8SChris Lattner //----------------------------------------------------------------------
3030fdc8d8SChris Lattner // TargetList constructor
3130fdc8d8SChris Lattner //----------------------------------------------------------------------
3230fdc8d8SChris Lattner TargetList::TargetList() :
3330fdc8d8SChris Lattner     Broadcaster("TargetList"),
3430fdc8d8SChris Lattner     m_target_list(),
3530fdc8d8SChris Lattner     m_target_list_mutex (Mutex::eMutexTypeRecursive),
362976d00aSJim Ingham     m_selected_target_idx (0)
3730fdc8d8SChris Lattner {
3830fdc8d8SChris Lattner }
3930fdc8d8SChris Lattner 
4030fdc8d8SChris Lattner //----------------------------------------------------------------------
4130fdc8d8SChris Lattner // Destructor
4230fdc8d8SChris Lattner //----------------------------------------------------------------------
4330fdc8d8SChris Lattner TargetList::~TargetList()
4430fdc8d8SChris Lattner {
4530fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
4630fdc8d8SChris Lattner     m_target_list.clear();
4730fdc8d8SChris Lattner }
4830fdc8d8SChris Lattner 
4930fdc8d8SChris Lattner Error
50cac9c5f9SGreg Clayton TargetList::CreateTarget (Debugger &debugger,
51cac9c5f9SGreg Clayton                           const FileSpec& file,
52cac9c5f9SGreg Clayton                           const char *triple_cstr,
53cac9c5f9SGreg Clayton                           bool get_dependent_files,
54cac9c5f9SGreg Clayton                           const OptionGroupPlatform *platform_options,
55cac9c5f9SGreg Clayton                           TargetSP &target_sp)
56cac9c5f9SGreg Clayton {
57cac9c5f9SGreg Clayton     Error error;
58cac9c5f9SGreg Clayton     PlatformSP platform_sp;
59cac9c5f9SGreg Clayton     if (platform_options)
60cac9c5f9SGreg Clayton     {
61cac9c5f9SGreg Clayton         if (platform_options->PlatformWasSpecified ())
62cac9c5f9SGreg Clayton         {
63cac9c5f9SGreg Clayton             const bool select_platform = true;
64cac9c5f9SGreg Clayton             platform_sp = platform_options->CreatePlatformWithOptions (debugger.GetCommandInterpreter(),
65cac9c5f9SGreg Clayton                                                                        select_platform,
66cac9c5f9SGreg Clayton                                                                        error);
67cac9c5f9SGreg Clayton             if (!platform_sp)
68cac9c5f9SGreg Clayton                 return error;
69cac9c5f9SGreg Clayton         }
70cac9c5f9SGreg Clayton     }
71cac9c5f9SGreg Clayton 
72cac9c5f9SGreg Clayton     if (!platform_sp)
73cac9c5f9SGreg Clayton         platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
74cac9c5f9SGreg Clayton 
75cac9c5f9SGreg Clayton     ArchSpec arch;
76cac9c5f9SGreg Clayton 
77cac9c5f9SGreg Clayton     if (triple_cstr)
78cac9c5f9SGreg Clayton     {
79cac9c5f9SGreg Clayton         arch.SetTriple(triple_cstr, platform_sp.get());
80cac9c5f9SGreg Clayton         if (!arch.IsValid())
81cac9c5f9SGreg Clayton         {
82*86edbf41SGreg Clayton             error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
83cac9c5f9SGreg Clayton             return error;
84cac9c5f9SGreg Clayton         }
85cac9c5f9SGreg Clayton     }
86cac9c5f9SGreg Clayton     error = TargetList::CreateTarget (debugger,
87cac9c5f9SGreg Clayton                                       file,
88cac9c5f9SGreg Clayton                                       arch,
89cac9c5f9SGreg Clayton                                       get_dependent_files,
90cac9c5f9SGreg Clayton                                       platform_sp,
91cac9c5f9SGreg Clayton                                       target_sp);
92cac9c5f9SGreg Clayton     return error;
93cac9c5f9SGreg Clayton }
94cac9c5f9SGreg Clayton 
95cac9c5f9SGreg Clayton Error
9630fdc8d8SChris Lattner TargetList::CreateTarget
9730fdc8d8SChris Lattner (
986611103cSGreg Clayton     Debugger &debugger,
9930fdc8d8SChris Lattner     const FileSpec& file,
10030fdc8d8SChris Lattner     const ArchSpec& arch,
10130fdc8d8SChris Lattner     bool get_dependent_files,
102cac9c5f9SGreg Clayton     const PlatformSP &platform_sp,
10330fdc8d8SChris Lattner     TargetSP &target_sp
10430fdc8d8SChris Lattner )
10530fdc8d8SChris Lattner {
10630fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
107e996fd30SGreg Clayton                         "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
10830fdc8d8SChris Lattner                         file.GetDirectory().AsCString(),
10930fdc8d8SChris Lattner                         file.GetFilename().AsCString(),
110e996fd30SGreg Clayton                         arch.GetArchitectureName());
1115aee162fSJim Ingham     Error error;
1125aee162fSJim Ingham 
113ded470d3SGreg Clayton 
114e996fd30SGreg Clayton     if (file)
1155aee162fSJim Ingham     {
11630fdc8d8SChris Lattner         ModuleSP exe_module_sp;
11730fdc8d8SChris Lattner         FileSpec resolved_file(file);
118428a9a58SCaroline Tice 
119e996fd30SGreg Clayton         if (platform_sp)
120e996fd30SGreg Clayton             error = platform_sp->ResolveExecutable (file, arch, exe_module_sp);
121428a9a58SCaroline Tice 
122e996fd30SGreg Clayton         if (error.Success() && exe_module_sp)
12330fdc8d8SChris Lattner         {
1245aee162fSJim Ingham             if (exe_module_sp->GetObjectFile() == NULL)
1255aee162fSJim Ingham             {
126bc5cad6cSGreg Clayton                 if (arch.IsValid())
127bc5cad6cSGreg Clayton                 {
128bc5cad6cSGreg Clayton                     error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
1295aee162fSJim Ingham                                                    file.GetDirectory().AsCString(),
1305aee162fSJim Ingham                                                    file.GetDirectory() ? "/" : "",
1315aee162fSJim Ingham                                                    file.GetFilename().AsCString(),
13264195a2cSGreg Clayton                                                    arch.GetArchitectureName());
133bc5cad6cSGreg Clayton                 }
134bc5cad6cSGreg Clayton                 else
135bc5cad6cSGreg Clayton                 {
136bc5cad6cSGreg Clayton                     error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
137bc5cad6cSGreg Clayton                                                    file.GetDirectory().AsCString(),
138bc5cad6cSGreg Clayton                                                    file.GetDirectory() ? "/" : "",
139bc5cad6cSGreg Clayton                                                    file.GetFilename().AsCString());
140bc5cad6cSGreg Clayton                 }
1415aee162fSJim Ingham                 return error;
1425aee162fSJim Ingham             }
14332e0a750SGreg Clayton             target_sp.reset(new Target(debugger, arch, platform_sp));
14430fdc8d8SChris Lattner             target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
1455aee162fSJim Ingham         }
1465aee162fSJim Ingham     }
147e996fd30SGreg Clayton     else
148e996fd30SGreg Clayton     {
149e996fd30SGreg Clayton         // No file was specified, just create an empty target with any arch
150e996fd30SGreg Clayton         // if a valid arch was specified
15132e0a750SGreg Clayton         target_sp.reset(new Target(debugger, arch, platform_sp));
152e996fd30SGreg Clayton     }
1531559a46bSCaroline Tice 
154e996fd30SGreg Clayton     if (target_sp)
155e996fd30SGreg Clayton     {
1561559a46bSCaroline Tice         target_sp->UpdateInstanceName();
15730fdc8d8SChris Lattner 
15830fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
1592976d00aSJim Ingham         m_selected_target_idx = m_target_list.size();
16030fdc8d8SChris Lattner         m_target_list.push_back(target_sp);
16130fdc8d8SChris Lattner     }
16230fdc8d8SChris Lattner 
16330fdc8d8SChris Lattner     return error;
16430fdc8d8SChris Lattner }
16530fdc8d8SChris Lattner 
16630fdc8d8SChris Lattner bool
16730fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp)
16830fdc8d8SChris Lattner {
16930fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
17030fdc8d8SChris Lattner     collection::iterator pos, end = m_target_list.end();
17130fdc8d8SChris Lattner 
17230fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
17330fdc8d8SChris Lattner     {
17430fdc8d8SChris Lattner         if (pos->get() == target_sp.get())
17530fdc8d8SChris Lattner         {
17630fdc8d8SChris Lattner             m_target_list.erase(pos);
17730fdc8d8SChris Lattner             return true;
17830fdc8d8SChris Lattner         }
17930fdc8d8SChris Lattner     }
18030fdc8d8SChris Lattner     return false;
18130fdc8d8SChris Lattner }
18230fdc8d8SChris Lattner 
18330fdc8d8SChris Lattner 
18430fdc8d8SChris Lattner TargetSP
18530fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture
18630fdc8d8SChris Lattner (
18730fdc8d8SChris Lattner     const FileSpec &exe_file_spec,
18830fdc8d8SChris Lattner     const ArchSpec *exe_arch_ptr
18930fdc8d8SChris Lattner ) const
19030fdc8d8SChris Lattner {
19130fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
19230fdc8d8SChris Lattner     TargetSP target_sp;
19330fdc8d8SChris Lattner     bool full_match = exe_file_spec.GetDirectory();
19430fdc8d8SChris Lattner 
19530fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
19630fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
19730fdc8d8SChris Lattner     {
198aa149cbdSGreg Clayton         Module *exe_module = (*pos)->GetExecutableModulePointer();
19930fdc8d8SChris Lattner 
200aa149cbdSGreg Clayton         if (exe_module)
20130fdc8d8SChris Lattner         {
202aa149cbdSGreg Clayton             if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
20330fdc8d8SChris Lattner             {
20430fdc8d8SChris Lattner                 if (exe_arch_ptr)
20530fdc8d8SChris Lattner                 {
206aa149cbdSGreg Clayton                     if (*exe_arch_ptr != exe_module->GetArchitecture())
20730fdc8d8SChris Lattner                         continue;
20830fdc8d8SChris Lattner                 }
20930fdc8d8SChris Lattner                 target_sp = *pos;
21030fdc8d8SChris Lattner                 break;
21130fdc8d8SChris Lattner             }
21230fdc8d8SChris Lattner         }
21330fdc8d8SChris Lattner     }
21430fdc8d8SChris Lattner     return target_sp;
21530fdc8d8SChris Lattner }
21630fdc8d8SChris Lattner 
21730fdc8d8SChris Lattner TargetSP
21830fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
21930fdc8d8SChris Lattner {
22030fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
22130fdc8d8SChris Lattner     TargetSP target_sp;
22230fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
22330fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
22430fdc8d8SChris Lattner     {
22530fdc8d8SChris Lattner         Process* process = (*pos)->GetProcessSP().get();
22630fdc8d8SChris Lattner         if (process && process->GetID() == pid)
22730fdc8d8SChris Lattner         {
22830fdc8d8SChris Lattner             target_sp = *pos;
22930fdc8d8SChris Lattner             break;
23030fdc8d8SChris Lattner         }
23130fdc8d8SChris Lattner     }
23230fdc8d8SChris Lattner     return target_sp;
23330fdc8d8SChris Lattner }
23430fdc8d8SChris Lattner 
23530fdc8d8SChris Lattner 
23630fdc8d8SChris Lattner TargetSP
23730fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const
23830fdc8d8SChris Lattner {
23930fdc8d8SChris Lattner     TargetSP target_sp;
24030fdc8d8SChris Lattner     if (process)
24130fdc8d8SChris Lattner     {
24230fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
24330fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
24430fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
24530fdc8d8SChris Lattner         {
24630fdc8d8SChris Lattner             if (process == (*pos)->GetProcessSP().get())
24730fdc8d8SChris Lattner             {
24830fdc8d8SChris Lattner                 target_sp = *pos;
24930fdc8d8SChris Lattner                 break;
25030fdc8d8SChris Lattner             }
25130fdc8d8SChris Lattner         }
25230fdc8d8SChris Lattner     }
25330fdc8d8SChris Lattner     return target_sp;
25430fdc8d8SChris Lattner }
25530fdc8d8SChris Lattner 
25630fdc8d8SChris Lattner TargetSP
25730fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const
25830fdc8d8SChris Lattner {
25930fdc8d8SChris Lattner     TargetSP target_sp;
26030fdc8d8SChris Lattner     if (target)
26130fdc8d8SChris Lattner     {
26230fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
26330fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
26430fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
26530fdc8d8SChris Lattner         {
26630fdc8d8SChris Lattner             if (target == (*pos).get())
26730fdc8d8SChris Lattner             {
26830fdc8d8SChris Lattner                 target_sp = *pos;
26930fdc8d8SChris Lattner                 break;
27030fdc8d8SChris Lattner             }
27130fdc8d8SChris Lattner         }
27230fdc8d8SChris Lattner     }
27330fdc8d8SChris Lattner     return target_sp;
27430fdc8d8SChris Lattner }
27530fdc8d8SChris Lattner 
27630fdc8d8SChris Lattner uint32_t
27730fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid)
27830fdc8d8SChris Lattner {
27930fdc8d8SChris Lattner     uint32_t num_async_interrupts_sent = 0;
28030fdc8d8SChris Lattner 
28130fdc8d8SChris Lattner     if (pid != LLDB_INVALID_PROCESS_ID)
28230fdc8d8SChris Lattner     {
28330fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
28430fdc8d8SChris Lattner         if (target_sp.get())
28530fdc8d8SChris Lattner         {
28630fdc8d8SChris Lattner             Process* process = target_sp->GetProcessSP().get();
28730fdc8d8SChris Lattner             if (process)
28830fdc8d8SChris Lattner             {
28930fdc8d8SChris Lattner                 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
29030fdc8d8SChris Lattner                 ++num_async_interrupts_sent;
29130fdc8d8SChris Lattner             }
29230fdc8d8SChris Lattner         }
29330fdc8d8SChris Lattner     }
29430fdc8d8SChris Lattner     else
29530fdc8d8SChris Lattner     {
29630fdc8d8SChris Lattner         // We don't have a valid pid to broadcast to, so broadcast to the target
29730fdc8d8SChris Lattner         // list's async broadcaster...
29830fdc8d8SChris Lattner         BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
29930fdc8d8SChris Lattner     }
30030fdc8d8SChris Lattner 
30130fdc8d8SChris Lattner     return num_async_interrupts_sent;
30230fdc8d8SChris Lattner }
30330fdc8d8SChris Lattner 
30430fdc8d8SChris Lattner uint32_t
30530fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
30630fdc8d8SChris Lattner {
30730fdc8d8SChris Lattner     uint32_t num_signals_sent = 0;
30830fdc8d8SChris Lattner     Process *process = NULL;
30930fdc8d8SChris Lattner     if (pid == LLDB_INVALID_PROCESS_ID)
31030fdc8d8SChris Lattner     {
31130fdc8d8SChris Lattner         // Signal all processes with signal
31230fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
31330fdc8d8SChris Lattner         collection::iterator pos, end = m_target_list.end();
31430fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
31530fdc8d8SChris Lattner         {
31630fdc8d8SChris Lattner             process = (*pos)->GetProcessSP().get();
31730fdc8d8SChris Lattner             if (process)
31830fdc8d8SChris Lattner             {
31930fdc8d8SChris Lattner                 if (process->IsAlive())
32030fdc8d8SChris Lattner                 {
32130fdc8d8SChris Lattner                     ++num_signals_sent;
32230fdc8d8SChris Lattner                     process->Signal (signo);
32330fdc8d8SChris Lattner                 }
32430fdc8d8SChris Lattner             }
32530fdc8d8SChris Lattner         }
32630fdc8d8SChris Lattner     }
32730fdc8d8SChris Lattner     else
32830fdc8d8SChris Lattner     {
32930fdc8d8SChris Lattner         // Signal a specific process with signal
33030fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
33130fdc8d8SChris Lattner         if (target_sp.get())
33230fdc8d8SChris Lattner         {
33330fdc8d8SChris Lattner             process = target_sp->GetProcessSP().get();
33430fdc8d8SChris Lattner             if (process)
33530fdc8d8SChris Lattner             {
33630fdc8d8SChris Lattner                 if (process->IsAlive())
33730fdc8d8SChris Lattner                 {
33830fdc8d8SChris Lattner                     ++num_signals_sent;
33930fdc8d8SChris Lattner                     process->Signal (signo);
34030fdc8d8SChris Lattner                 }
34130fdc8d8SChris Lattner             }
34230fdc8d8SChris Lattner         }
34330fdc8d8SChris Lattner     }
34430fdc8d8SChris Lattner     return num_signals_sent;
34530fdc8d8SChris Lattner }
34630fdc8d8SChris Lattner 
34730fdc8d8SChris Lattner int
34830fdc8d8SChris Lattner TargetList::GetNumTargets () const
34930fdc8d8SChris Lattner {
35030fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
35130fdc8d8SChris Lattner     return m_target_list.size();
35230fdc8d8SChris Lattner }
35330fdc8d8SChris Lattner 
35430fdc8d8SChris Lattner lldb::TargetSP
35530fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const
35630fdc8d8SChris Lattner {
35730fdc8d8SChris Lattner     TargetSP target_sp;
35830fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
35930fdc8d8SChris Lattner     if (idx < m_target_list.size())
36030fdc8d8SChris Lattner         target_sp = m_target_list[idx];
36130fdc8d8SChris Lattner     return target_sp;
36230fdc8d8SChris Lattner }
36330fdc8d8SChris Lattner 
36430fdc8d8SChris Lattner uint32_t
3652976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target)
36630fdc8d8SChris Lattner {
36730fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
36830fdc8d8SChris Lattner     collection::const_iterator pos,
36930fdc8d8SChris Lattner         begin = m_target_list.begin(),
37030fdc8d8SChris Lattner         end = m_target_list.end();
37130fdc8d8SChris Lattner     for (pos = begin; pos != end; ++pos)
37230fdc8d8SChris Lattner     {
37330fdc8d8SChris Lattner         if (pos->get() == target)
37430fdc8d8SChris Lattner         {
3752976d00aSJim Ingham             m_selected_target_idx = std::distance (begin, pos);
3762976d00aSJim Ingham             return m_selected_target_idx;
37730fdc8d8SChris Lattner         }
37830fdc8d8SChris Lattner     }
3792976d00aSJim Ingham     m_selected_target_idx = 0;
3802976d00aSJim Ingham     return m_selected_target_idx;
38130fdc8d8SChris Lattner }
38230fdc8d8SChris Lattner 
38330fdc8d8SChris Lattner lldb::TargetSP
3842976d00aSJim Ingham TargetList::GetSelectedTarget ()
38530fdc8d8SChris Lattner {
38630fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
3872976d00aSJim Ingham     if (m_selected_target_idx >= m_target_list.size())
3882976d00aSJim Ingham         m_selected_target_idx = 0;
3892976d00aSJim Ingham     return GetTargetAtIndex (m_selected_target_idx);
39030fdc8d8SChris Lattner }
391