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 
75*cdc21d4cSJohnny Chen     // This is purposely left empty unless it is specified by triple_cstr.
76*cdc21d4cSJohnny Chen     // If not initialized via triple_cstr, then the currently selected platform
77*cdc21d4cSJohnny Chen     // will set the architecture correctly.
78cac9c5f9SGreg Clayton     ArchSpec arch;
79cac9c5f9SGreg Clayton 
80cac9c5f9SGreg Clayton     if (triple_cstr)
81cac9c5f9SGreg Clayton     {
82cac9c5f9SGreg Clayton         arch.SetTriple(triple_cstr, platform_sp.get());
83cac9c5f9SGreg Clayton         if (!arch.IsValid())
84cac9c5f9SGreg Clayton         {
8586edbf41SGreg Clayton             error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr);
86cac9c5f9SGreg Clayton             return error;
87cac9c5f9SGreg Clayton         }
88cac9c5f9SGreg Clayton     }
89cac9c5f9SGreg Clayton     error = TargetList::CreateTarget (debugger,
90cac9c5f9SGreg Clayton                                       file,
91cac9c5f9SGreg Clayton                                       arch,
92cac9c5f9SGreg Clayton                                       get_dependent_files,
93cac9c5f9SGreg Clayton                                       platform_sp,
94cac9c5f9SGreg Clayton                                       target_sp);
95cac9c5f9SGreg Clayton     return error;
96cac9c5f9SGreg Clayton }
97cac9c5f9SGreg Clayton 
98cac9c5f9SGreg Clayton Error
9930fdc8d8SChris Lattner TargetList::CreateTarget
10030fdc8d8SChris Lattner (
1016611103cSGreg Clayton     Debugger &debugger,
10230fdc8d8SChris Lattner     const FileSpec& file,
10330fdc8d8SChris Lattner     const ArchSpec& arch,
10430fdc8d8SChris Lattner     bool get_dependent_files,
105cac9c5f9SGreg Clayton     const PlatformSP &platform_sp,
10630fdc8d8SChris Lattner     TargetSP &target_sp
10730fdc8d8SChris Lattner )
10830fdc8d8SChris Lattner {
10930fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
110e996fd30SGreg Clayton                         "TargetList::CreateTarget (file = '%s/%s', arch = '%s')",
11130fdc8d8SChris Lattner                         file.GetDirectory().AsCString(),
11230fdc8d8SChris Lattner                         file.GetFilename().AsCString(),
113e996fd30SGreg Clayton                         arch.GetArchitectureName());
1145aee162fSJim Ingham     Error error;
1155aee162fSJim Ingham 
116ded470d3SGreg Clayton 
117e996fd30SGreg Clayton     if (file)
1185aee162fSJim Ingham     {
11930fdc8d8SChris Lattner         ModuleSP exe_module_sp;
12030fdc8d8SChris Lattner         FileSpec resolved_file(file);
121428a9a58SCaroline Tice 
122e996fd30SGreg Clayton         if (platform_sp)
123e996fd30SGreg Clayton             error = platform_sp->ResolveExecutable (file, arch, exe_module_sp);
124428a9a58SCaroline Tice 
125e996fd30SGreg Clayton         if (error.Success() && exe_module_sp)
12630fdc8d8SChris Lattner         {
1275aee162fSJim Ingham             if (exe_module_sp->GetObjectFile() == NULL)
1285aee162fSJim Ingham             {
129bc5cad6cSGreg Clayton                 if (arch.IsValid())
130bc5cad6cSGreg Clayton                 {
131bc5cad6cSGreg Clayton                     error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s",
1325aee162fSJim Ingham                                                    file.GetDirectory().AsCString(),
1335aee162fSJim Ingham                                                    file.GetDirectory() ? "/" : "",
1345aee162fSJim Ingham                                                    file.GetFilename().AsCString(),
13564195a2cSGreg Clayton                                                    arch.GetArchitectureName());
136bc5cad6cSGreg Clayton                 }
137bc5cad6cSGreg Clayton                 else
138bc5cad6cSGreg Clayton                 {
139bc5cad6cSGreg Clayton                     error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"",
140bc5cad6cSGreg Clayton                                                    file.GetDirectory().AsCString(),
141bc5cad6cSGreg Clayton                                                    file.GetDirectory() ? "/" : "",
142bc5cad6cSGreg Clayton                                                    file.GetFilename().AsCString());
143bc5cad6cSGreg Clayton                 }
1445aee162fSJim Ingham                 return error;
1455aee162fSJim Ingham             }
14632e0a750SGreg Clayton             target_sp.reset(new Target(debugger, arch, platform_sp));
14730fdc8d8SChris Lattner             target_sp->SetExecutableModule (exe_module_sp, get_dependent_files);
1485aee162fSJim Ingham         }
1495aee162fSJim Ingham     }
150e996fd30SGreg Clayton     else
151e996fd30SGreg Clayton     {
152e996fd30SGreg Clayton         // No file was specified, just create an empty target with any arch
153e996fd30SGreg Clayton         // if a valid arch was specified
15432e0a750SGreg Clayton         target_sp.reset(new Target(debugger, arch, platform_sp));
155e996fd30SGreg Clayton     }
1561559a46bSCaroline Tice 
157e996fd30SGreg Clayton     if (target_sp)
158e996fd30SGreg Clayton     {
1591559a46bSCaroline Tice         target_sp->UpdateInstanceName();
16030fdc8d8SChris Lattner 
16130fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
1622976d00aSJim Ingham         m_selected_target_idx = m_target_list.size();
16330fdc8d8SChris Lattner         m_target_list.push_back(target_sp);
16430fdc8d8SChris Lattner     }
16530fdc8d8SChris Lattner 
16630fdc8d8SChris Lattner     return error;
16730fdc8d8SChris Lattner }
16830fdc8d8SChris Lattner 
16930fdc8d8SChris Lattner bool
17030fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp)
17130fdc8d8SChris Lattner {
17230fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
17330fdc8d8SChris Lattner     collection::iterator pos, end = m_target_list.end();
17430fdc8d8SChris Lattner 
17530fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
17630fdc8d8SChris Lattner     {
17730fdc8d8SChris Lattner         if (pos->get() == target_sp.get())
17830fdc8d8SChris Lattner         {
17930fdc8d8SChris Lattner             m_target_list.erase(pos);
18030fdc8d8SChris Lattner             return true;
18130fdc8d8SChris Lattner         }
18230fdc8d8SChris Lattner     }
18330fdc8d8SChris Lattner     return false;
18430fdc8d8SChris Lattner }
18530fdc8d8SChris Lattner 
18630fdc8d8SChris Lattner 
18730fdc8d8SChris Lattner TargetSP
18830fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture
18930fdc8d8SChris Lattner (
19030fdc8d8SChris Lattner     const FileSpec &exe_file_spec,
19130fdc8d8SChris Lattner     const ArchSpec *exe_arch_ptr
19230fdc8d8SChris Lattner ) const
19330fdc8d8SChris Lattner {
19430fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
19530fdc8d8SChris Lattner     TargetSP target_sp;
19630fdc8d8SChris Lattner     bool full_match = exe_file_spec.GetDirectory();
19730fdc8d8SChris Lattner 
19830fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
19930fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
20030fdc8d8SChris Lattner     {
201aa149cbdSGreg Clayton         Module *exe_module = (*pos)->GetExecutableModulePointer();
20230fdc8d8SChris Lattner 
203aa149cbdSGreg Clayton         if (exe_module)
20430fdc8d8SChris Lattner         {
205aa149cbdSGreg Clayton             if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match))
20630fdc8d8SChris Lattner             {
20730fdc8d8SChris Lattner                 if (exe_arch_ptr)
20830fdc8d8SChris Lattner                 {
209aa149cbdSGreg Clayton                     if (*exe_arch_ptr != exe_module->GetArchitecture())
21030fdc8d8SChris Lattner                         continue;
21130fdc8d8SChris Lattner                 }
21230fdc8d8SChris Lattner                 target_sp = *pos;
21330fdc8d8SChris Lattner                 break;
21430fdc8d8SChris Lattner             }
21530fdc8d8SChris Lattner         }
21630fdc8d8SChris Lattner     }
21730fdc8d8SChris Lattner     return target_sp;
21830fdc8d8SChris Lattner }
21930fdc8d8SChris Lattner 
22030fdc8d8SChris Lattner TargetSP
22130fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const
22230fdc8d8SChris Lattner {
22330fdc8d8SChris Lattner     Mutex::Locker locker(m_target_list_mutex);
22430fdc8d8SChris Lattner     TargetSP target_sp;
22530fdc8d8SChris Lattner     collection::const_iterator pos, end = m_target_list.end();
22630fdc8d8SChris Lattner     for (pos = m_target_list.begin(); pos != end; ++pos)
22730fdc8d8SChris Lattner     {
22830fdc8d8SChris Lattner         Process* process = (*pos)->GetProcessSP().get();
22930fdc8d8SChris Lattner         if (process && process->GetID() == pid)
23030fdc8d8SChris Lattner         {
23130fdc8d8SChris Lattner             target_sp = *pos;
23230fdc8d8SChris Lattner             break;
23330fdc8d8SChris Lattner         }
23430fdc8d8SChris Lattner     }
23530fdc8d8SChris Lattner     return target_sp;
23630fdc8d8SChris Lattner }
23730fdc8d8SChris Lattner 
23830fdc8d8SChris Lattner 
23930fdc8d8SChris Lattner TargetSP
24030fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const
24130fdc8d8SChris Lattner {
24230fdc8d8SChris Lattner     TargetSP target_sp;
24330fdc8d8SChris Lattner     if (process)
24430fdc8d8SChris Lattner     {
24530fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
24630fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
24730fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
24830fdc8d8SChris Lattner         {
24930fdc8d8SChris Lattner             if (process == (*pos)->GetProcessSP().get())
25030fdc8d8SChris Lattner             {
25130fdc8d8SChris Lattner                 target_sp = *pos;
25230fdc8d8SChris Lattner                 break;
25330fdc8d8SChris Lattner             }
25430fdc8d8SChris Lattner         }
25530fdc8d8SChris Lattner     }
25630fdc8d8SChris Lattner     return target_sp;
25730fdc8d8SChris Lattner }
25830fdc8d8SChris Lattner 
25930fdc8d8SChris Lattner TargetSP
26030fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const
26130fdc8d8SChris Lattner {
26230fdc8d8SChris Lattner     TargetSP target_sp;
26330fdc8d8SChris Lattner     if (target)
26430fdc8d8SChris Lattner     {
26530fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
26630fdc8d8SChris Lattner         collection::const_iterator pos, end = m_target_list.end();
26730fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
26830fdc8d8SChris Lattner         {
26930fdc8d8SChris Lattner             if (target == (*pos).get())
27030fdc8d8SChris Lattner             {
27130fdc8d8SChris Lattner                 target_sp = *pos;
27230fdc8d8SChris Lattner                 break;
27330fdc8d8SChris Lattner             }
27430fdc8d8SChris Lattner         }
27530fdc8d8SChris Lattner     }
27630fdc8d8SChris Lattner     return target_sp;
27730fdc8d8SChris Lattner }
27830fdc8d8SChris Lattner 
27930fdc8d8SChris Lattner uint32_t
28030fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid)
28130fdc8d8SChris Lattner {
28230fdc8d8SChris Lattner     uint32_t num_async_interrupts_sent = 0;
28330fdc8d8SChris Lattner 
28430fdc8d8SChris Lattner     if (pid != LLDB_INVALID_PROCESS_ID)
28530fdc8d8SChris Lattner     {
28630fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
28730fdc8d8SChris Lattner         if (target_sp.get())
28830fdc8d8SChris Lattner         {
28930fdc8d8SChris Lattner             Process* process = target_sp->GetProcessSP().get();
29030fdc8d8SChris Lattner             if (process)
29130fdc8d8SChris Lattner             {
29230fdc8d8SChris Lattner                 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
29330fdc8d8SChris Lattner                 ++num_async_interrupts_sent;
29430fdc8d8SChris Lattner             }
29530fdc8d8SChris Lattner         }
29630fdc8d8SChris Lattner     }
29730fdc8d8SChris Lattner     else
29830fdc8d8SChris Lattner     {
29930fdc8d8SChris Lattner         // We don't have a valid pid to broadcast to, so broadcast to the target
30030fdc8d8SChris Lattner         // list's async broadcaster...
30130fdc8d8SChris Lattner         BroadcastEvent (Process::eBroadcastBitInterrupt, NULL);
30230fdc8d8SChris Lattner     }
30330fdc8d8SChris Lattner 
30430fdc8d8SChris Lattner     return num_async_interrupts_sent;
30530fdc8d8SChris Lattner }
30630fdc8d8SChris Lattner 
30730fdc8d8SChris Lattner uint32_t
30830fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo)
30930fdc8d8SChris Lattner {
31030fdc8d8SChris Lattner     uint32_t num_signals_sent = 0;
31130fdc8d8SChris Lattner     Process *process = NULL;
31230fdc8d8SChris Lattner     if (pid == LLDB_INVALID_PROCESS_ID)
31330fdc8d8SChris Lattner     {
31430fdc8d8SChris Lattner         // Signal all processes with signal
31530fdc8d8SChris Lattner         Mutex::Locker locker(m_target_list_mutex);
31630fdc8d8SChris Lattner         collection::iterator pos, end = m_target_list.end();
31730fdc8d8SChris Lattner         for (pos = m_target_list.begin(); pos != end; ++pos)
31830fdc8d8SChris Lattner         {
31930fdc8d8SChris Lattner             process = (*pos)->GetProcessSP().get();
32030fdc8d8SChris Lattner             if (process)
32130fdc8d8SChris Lattner             {
32230fdc8d8SChris Lattner                 if (process->IsAlive())
32330fdc8d8SChris Lattner                 {
32430fdc8d8SChris Lattner                     ++num_signals_sent;
32530fdc8d8SChris Lattner                     process->Signal (signo);
32630fdc8d8SChris Lattner                 }
32730fdc8d8SChris Lattner             }
32830fdc8d8SChris Lattner         }
32930fdc8d8SChris Lattner     }
33030fdc8d8SChris Lattner     else
33130fdc8d8SChris Lattner     {
33230fdc8d8SChris Lattner         // Signal a specific process with signal
33330fdc8d8SChris Lattner         TargetSP target_sp(FindTargetWithProcessID (pid));
33430fdc8d8SChris Lattner         if (target_sp.get())
33530fdc8d8SChris Lattner         {
33630fdc8d8SChris Lattner             process = target_sp->GetProcessSP().get();
33730fdc8d8SChris Lattner             if (process)
33830fdc8d8SChris Lattner             {
33930fdc8d8SChris Lattner                 if (process->IsAlive())
34030fdc8d8SChris Lattner                 {
34130fdc8d8SChris Lattner                     ++num_signals_sent;
34230fdc8d8SChris Lattner                     process->Signal (signo);
34330fdc8d8SChris Lattner                 }
34430fdc8d8SChris Lattner             }
34530fdc8d8SChris Lattner         }
34630fdc8d8SChris Lattner     }
34730fdc8d8SChris Lattner     return num_signals_sent;
34830fdc8d8SChris Lattner }
34930fdc8d8SChris Lattner 
35030fdc8d8SChris Lattner int
35130fdc8d8SChris Lattner TargetList::GetNumTargets () const
35230fdc8d8SChris Lattner {
35330fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
35430fdc8d8SChris Lattner     return m_target_list.size();
35530fdc8d8SChris Lattner }
35630fdc8d8SChris Lattner 
35730fdc8d8SChris Lattner lldb::TargetSP
35830fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const
35930fdc8d8SChris Lattner {
36030fdc8d8SChris Lattner     TargetSP target_sp;
36130fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
36230fdc8d8SChris Lattner     if (idx < m_target_list.size())
36330fdc8d8SChris Lattner         target_sp = m_target_list[idx];
36430fdc8d8SChris Lattner     return target_sp;
36530fdc8d8SChris Lattner }
36630fdc8d8SChris Lattner 
36730fdc8d8SChris Lattner uint32_t
3682976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target)
36930fdc8d8SChris Lattner {
37030fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
37130fdc8d8SChris Lattner     collection::const_iterator pos,
37230fdc8d8SChris Lattner         begin = m_target_list.begin(),
37330fdc8d8SChris Lattner         end = m_target_list.end();
37430fdc8d8SChris Lattner     for (pos = begin; pos != end; ++pos)
37530fdc8d8SChris Lattner     {
37630fdc8d8SChris Lattner         if (pos->get() == target)
37730fdc8d8SChris Lattner         {
3782976d00aSJim Ingham             m_selected_target_idx = std::distance (begin, pos);
3792976d00aSJim Ingham             return m_selected_target_idx;
38030fdc8d8SChris Lattner         }
38130fdc8d8SChris Lattner     }
3822976d00aSJim Ingham     m_selected_target_idx = 0;
3832976d00aSJim Ingham     return m_selected_target_idx;
38430fdc8d8SChris Lattner }
38530fdc8d8SChris Lattner 
38630fdc8d8SChris Lattner lldb::TargetSP
3872976d00aSJim Ingham TargetList::GetSelectedTarget ()
38830fdc8d8SChris Lattner {
38930fdc8d8SChris Lattner     Mutex::Locker locker (m_target_list_mutex);
3902976d00aSJim Ingham     if (m_selected_target_idx >= m_target_list.size())
3912976d00aSJim Ingham         m_selected_target_idx = 0;
3922976d00aSJim Ingham     return GetTargetAtIndex (m_selected_target_idx);
39330fdc8d8SChris Lattner }
394