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