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