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