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