1*30fdc8d8SChris Lattner //===-- TargetList.cpp ------------------------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner 10*30fdc8d8SChris Lattner // C Includes 11*30fdc8d8SChris Lattner // C++ Includes 12*30fdc8d8SChris Lattner // Other libraries and framework includes 13*30fdc8d8SChris Lattner // Project includes 14*30fdc8d8SChris Lattner #include "lldb/Core/Broadcaster.h" 15*30fdc8d8SChris Lattner #include "lldb/Core/Event.h" 16*30fdc8d8SChris Lattner #include "lldb/Core/State.h" 17*30fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 18*30fdc8d8SChris Lattner #include "lldb/Host/Host.h" 19*30fdc8d8SChris Lattner #include "lldb/Target/Process.h" 20*30fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 21*30fdc8d8SChris Lattner 22*30fdc8d8SChris Lattner using namespace lldb; 23*30fdc8d8SChris Lattner using namespace lldb_private; 24*30fdc8d8SChris Lattner 25*30fdc8d8SChris Lattner 26*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 27*30fdc8d8SChris Lattner // TargetList constructor 28*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 29*30fdc8d8SChris Lattner TargetList::TargetList() : 30*30fdc8d8SChris Lattner Broadcaster("TargetList"), 31*30fdc8d8SChris Lattner m_target_list(), 32*30fdc8d8SChris Lattner m_target_list_mutex (Mutex::eMutexTypeRecursive), 33*30fdc8d8SChris Lattner m_current_target_idx (0) 34*30fdc8d8SChris Lattner { 35*30fdc8d8SChris Lattner } 36*30fdc8d8SChris Lattner 37*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 38*30fdc8d8SChris Lattner // Destructor 39*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 40*30fdc8d8SChris Lattner TargetList::~TargetList() 41*30fdc8d8SChris Lattner { 42*30fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 43*30fdc8d8SChris Lattner m_target_list.clear(); 44*30fdc8d8SChris Lattner } 45*30fdc8d8SChris Lattner 46*30fdc8d8SChris Lattner Error 47*30fdc8d8SChris Lattner TargetList::CreateTarget 48*30fdc8d8SChris Lattner ( 49*30fdc8d8SChris Lattner const FileSpec& file, 50*30fdc8d8SChris Lattner const ArchSpec& arch, 51*30fdc8d8SChris Lattner const UUID *uuid_ptr, 52*30fdc8d8SChris Lattner bool get_dependent_files, 53*30fdc8d8SChris Lattner TargetSP &target_sp 54*30fdc8d8SChris Lattner ) 55*30fdc8d8SChris Lattner { 56*30fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 57*30fdc8d8SChris Lattner "TargetList::CreateTarget (file = '%s/%s', arch = '%s', uuid = %p)", 58*30fdc8d8SChris Lattner file.GetDirectory().AsCString(), 59*30fdc8d8SChris Lattner file.GetFilename().AsCString(), 60*30fdc8d8SChris Lattner arch.AsCString(), 61*30fdc8d8SChris Lattner uuid_ptr); 62*30fdc8d8SChris Lattner ModuleSP exe_module_sp; 63*30fdc8d8SChris Lattner FileSpec resolved_file(file); 64*30fdc8d8SChris Lattner if (!Host::ResolveExecutableInBundle (&resolved_file)) 65*30fdc8d8SChris Lattner resolved_file = file; 66*30fdc8d8SChris Lattner 67*30fdc8d8SChris Lattner Error error = ModuleList::GetSharedModule(resolved_file, 68*30fdc8d8SChris Lattner arch, 69*30fdc8d8SChris Lattner uuid_ptr, 70*30fdc8d8SChris Lattner NULL, 71*30fdc8d8SChris Lattner 0, 72*30fdc8d8SChris Lattner exe_module_sp, 73*30fdc8d8SChris Lattner NULL, 74*30fdc8d8SChris Lattner NULL); 75*30fdc8d8SChris Lattner if (exe_module_sp) 76*30fdc8d8SChris Lattner { 77*30fdc8d8SChris Lattner target_sp.reset(new Target); 78*30fdc8d8SChris Lattner target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 79*30fdc8d8SChris Lattner 80*30fdc8d8SChris Lattner if (target_sp.get()) 81*30fdc8d8SChris Lattner { 82*30fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 83*30fdc8d8SChris Lattner m_current_target_idx = m_target_list.size(); 84*30fdc8d8SChris Lattner m_target_list.push_back(target_sp); 85*30fdc8d8SChris Lattner } 86*30fdc8d8SChris Lattner 87*30fdc8d8SChris Lattner // target_sp.reset(new Target); 88*30fdc8d8SChris Lattner // // Let the target resolve any funky bundle paths before we try and get 89*30fdc8d8SChris Lattner // // the object file... 90*30fdc8d8SChris Lattner // target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 91*30fdc8d8SChris Lattner // if (exe_module_sp->GetObjectFile() == NULL) 92*30fdc8d8SChris Lattner // { 93*30fdc8d8SChris Lattner // error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s", 94*30fdc8d8SChris Lattner // file.GetDirectory().AsCString(), 95*30fdc8d8SChris Lattner // file.GetDirectory() ? "/" : "", 96*30fdc8d8SChris Lattner // file.GetFilename().AsCString(), 97*30fdc8d8SChris Lattner // arch.AsCString()); 98*30fdc8d8SChris Lattner // } 99*30fdc8d8SChris Lattner // else 100*30fdc8d8SChris Lattner // { 101*30fdc8d8SChris Lattner // if (target_sp.get()) 102*30fdc8d8SChris Lattner // { 103*30fdc8d8SChris Lattner // error.Clear(); 104*30fdc8d8SChris Lattner // Mutex::Locker locker(m_target_list_mutex); 105*30fdc8d8SChris Lattner // m_current_target_idx = m_target_list.size(); 106*30fdc8d8SChris Lattner // m_target_list.push_back(target_sp); 107*30fdc8d8SChris Lattner // } 108*30fdc8d8SChris Lattner // } 109*30fdc8d8SChris Lattner } 110*30fdc8d8SChris Lattner else 111*30fdc8d8SChris Lattner { 112*30fdc8d8SChris Lattner target_sp.reset(); 113*30fdc8d8SChris Lattner } 114*30fdc8d8SChris Lattner 115*30fdc8d8SChris Lattner return error; 116*30fdc8d8SChris Lattner } 117*30fdc8d8SChris Lattner 118*30fdc8d8SChris Lattner bool 119*30fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp) 120*30fdc8d8SChris Lattner { 121*30fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 122*30fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 123*30fdc8d8SChris Lattner 124*30fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 125*30fdc8d8SChris Lattner { 126*30fdc8d8SChris Lattner if (pos->get() == target_sp.get()) 127*30fdc8d8SChris Lattner { 128*30fdc8d8SChris Lattner m_target_list.erase(pos); 129*30fdc8d8SChris Lattner return true; 130*30fdc8d8SChris Lattner } 131*30fdc8d8SChris Lattner } 132*30fdc8d8SChris Lattner return false; 133*30fdc8d8SChris Lattner } 134*30fdc8d8SChris Lattner 135*30fdc8d8SChris Lattner 136*30fdc8d8SChris Lattner TargetSP 137*30fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture 138*30fdc8d8SChris Lattner ( 139*30fdc8d8SChris Lattner const FileSpec &exe_file_spec, 140*30fdc8d8SChris Lattner const ArchSpec *exe_arch_ptr 141*30fdc8d8SChris Lattner ) const 142*30fdc8d8SChris Lattner { 143*30fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 144*30fdc8d8SChris Lattner TargetSP target_sp; 145*30fdc8d8SChris Lattner bool full_match = exe_file_spec.GetDirectory(); 146*30fdc8d8SChris Lattner 147*30fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 148*30fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 149*30fdc8d8SChris Lattner { 150*30fdc8d8SChris Lattner ModuleSP module_sp ((*pos)->GetExecutableModule()); 151*30fdc8d8SChris Lattner 152*30fdc8d8SChris Lattner if (module_sp) 153*30fdc8d8SChris Lattner { 154*30fdc8d8SChris Lattner if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match)) 155*30fdc8d8SChris Lattner { 156*30fdc8d8SChris Lattner if (exe_arch_ptr) 157*30fdc8d8SChris Lattner { 158*30fdc8d8SChris Lattner if (*exe_arch_ptr != module_sp->GetArchitecture()) 159*30fdc8d8SChris Lattner continue; 160*30fdc8d8SChris Lattner } 161*30fdc8d8SChris Lattner target_sp = *pos; 162*30fdc8d8SChris Lattner break; 163*30fdc8d8SChris Lattner } 164*30fdc8d8SChris Lattner } 165*30fdc8d8SChris Lattner } 166*30fdc8d8SChris Lattner return target_sp; 167*30fdc8d8SChris Lattner } 168*30fdc8d8SChris Lattner 169*30fdc8d8SChris Lattner TargetSP 170*30fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 171*30fdc8d8SChris Lattner { 172*30fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 173*30fdc8d8SChris Lattner TargetSP target_sp; 174*30fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 175*30fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 176*30fdc8d8SChris Lattner { 177*30fdc8d8SChris Lattner Process* process = (*pos)->GetProcessSP().get(); 178*30fdc8d8SChris Lattner if (process && process->GetID() == pid) 179*30fdc8d8SChris Lattner { 180*30fdc8d8SChris Lattner target_sp = *pos; 181*30fdc8d8SChris Lattner break; 182*30fdc8d8SChris Lattner } 183*30fdc8d8SChris Lattner } 184*30fdc8d8SChris Lattner return target_sp; 185*30fdc8d8SChris Lattner } 186*30fdc8d8SChris Lattner 187*30fdc8d8SChris Lattner 188*30fdc8d8SChris Lattner TargetSP 189*30fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const 190*30fdc8d8SChris Lattner { 191*30fdc8d8SChris Lattner TargetSP target_sp; 192*30fdc8d8SChris Lattner if (process) 193*30fdc8d8SChris Lattner { 194*30fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 195*30fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 196*30fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 197*30fdc8d8SChris Lattner { 198*30fdc8d8SChris Lattner if (process == (*pos)->GetProcessSP().get()) 199*30fdc8d8SChris Lattner { 200*30fdc8d8SChris Lattner target_sp = *pos; 201*30fdc8d8SChris Lattner break; 202*30fdc8d8SChris Lattner } 203*30fdc8d8SChris Lattner } 204*30fdc8d8SChris Lattner } 205*30fdc8d8SChris Lattner return target_sp; 206*30fdc8d8SChris Lattner } 207*30fdc8d8SChris Lattner 208*30fdc8d8SChris Lattner TargetSP 209*30fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const 210*30fdc8d8SChris Lattner { 211*30fdc8d8SChris Lattner TargetSP target_sp; 212*30fdc8d8SChris Lattner if (target) 213*30fdc8d8SChris Lattner { 214*30fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 215*30fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 216*30fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 217*30fdc8d8SChris Lattner { 218*30fdc8d8SChris Lattner if (target == (*pos).get()) 219*30fdc8d8SChris Lattner { 220*30fdc8d8SChris Lattner target_sp = *pos; 221*30fdc8d8SChris Lattner break; 222*30fdc8d8SChris Lattner } 223*30fdc8d8SChris Lattner } 224*30fdc8d8SChris Lattner } 225*30fdc8d8SChris Lattner return target_sp; 226*30fdc8d8SChris Lattner } 227*30fdc8d8SChris Lattner 228*30fdc8d8SChris Lattner uint32_t 229*30fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid) 230*30fdc8d8SChris Lattner { 231*30fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 232*30fdc8d8SChris Lattner 233*30fdc8d8SChris Lattner if (pid != LLDB_INVALID_PROCESS_ID) 234*30fdc8d8SChris Lattner { 235*30fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 236*30fdc8d8SChris Lattner if (target_sp.get()) 237*30fdc8d8SChris Lattner { 238*30fdc8d8SChris Lattner Process* process = target_sp->GetProcessSP().get(); 239*30fdc8d8SChris Lattner if (process) 240*30fdc8d8SChris Lattner { 241*30fdc8d8SChris Lattner process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 242*30fdc8d8SChris Lattner ++num_async_interrupts_sent; 243*30fdc8d8SChris Lattner } 244*30fdc8d8SChris Lattner } 245*30fdc8d8SChris Lattner } 246*30fdc8d8SChris Lattner else 247*30fdc8d8SChris Lattner { 248*30fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 249*30fdc8d8SChris Lattner // list's async broadcaster... 250*30fdc8d8SChris Lattner BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 251*30fdc8d8SChris Lattner } 252*30fdc8d8SChris Lattner 253*30fdc8d8SChris Lattner return num_async_interrupts_sent; 254*30fdc8d8SChris Lattner } 255*30fdc8d8SChris Lattner 256*30fdc8d8SChris Lattner uint32_t 257*30fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 258*30fdc8d8SChris Lattner { 259*30fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 260*30fdc8d8SChris Lattner Process *process = NULL; 261*30fdc8d8SChris Lattner if (pid == LLDB_INVALID_PROCESS_ID) 262*30fdc8d8SChris Lattner { 263*30fdc8d8SChris Lattner // Signal all processes with signal 264*30fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 265*30fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 266*30fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 267*30fdc8d8SChris Lattner { 268*30fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 269*30fdc8d8SChris Lattner if (process) 270*30fdc8d8SChris Lattner { 271*30fdc8d8SChris Lattner if (process->IsAlive()) 272*30fdc8d8SChris Lattner { 273*30fdc8d8SChris Lattner ++num_signals_sent; 274*30fdc8d8SChris Lattner process->Signal (signo); 275*30fdc8d8SChris Lattner } 276*30fdc8d8SChris Lattner } 277*30fdc8d8SChris Lattner } 278*30fdc8d8SChris Lattner } 279*30fdc8d8SChris Lattner else 280*30fdc8d8SChris Lattner { 281*30fdc8d8SChris Lattner // Signal a specific process with signal 282*30fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 283*30fdc8d8SChris Lattner if (target_sp.get()) 284*30fdc8d8SChris Lattner { 285*30fdc8d8SChris Lattner process = target_sp->GetProcessSP().get(); 286*30fdc8d8SChris Lattner if (process) 287*30fdc8d8SChris Lattner { 288*30fdc8d8SChris Lattner if (process->IsAlive()) 289*30fdc8d8SChris Lattner { 290*30fdc8d8SChris Lattner ++num_signals_sent; 291*30fdc8d8SChris Lattner process->Signal (signo); 292*30fdc8d8SChris Lattner } 293*30fdc8d8SChris Lattner } 294*30fdc8d8SChris Lattner } 295*30fdc8d8SChris Lattner } 296*30fdc8d8SChris Lattner return num_signals_sent; 297*30fdc8d8SChris Lattner } 298*30fdc8d8SChris Lattner 299*30fdc8d8SChris Lattner int 300*30fdc8d8SChris Lattner TargetList::GetNumTargets () const 301*30fdc8d8SChris Lattner { 302*30fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 303*30fdc8d8SChris Lattner return m_target_list.size(); 304*30fdc8d8SChris Lattner } 305*30fdc8d8SChris Lattner 306*30fdc8d8SChris Lattner lldb::TargetSP 307*30fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const 308*30fdc8d8SChris Lattner { 309*30fdc8d8SChris Lattner TargetSP target_sp; 310*30fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 311*30fdc8d8SChris Lattner if (idx < m_target_list.size()) 312*30fdc8d8SChris Lattner target_sp = m_target_list[idx]; 313*30fdc8d8SChris Lattner return target_sp; 314*30fdc8d8SChris Lattner } 315*30fdc8d8SChris Lattner 316*30fdc8d8SChris Lattner uint32_t 317*30fdc8d8SChris Lattner TargetList::SetCurrentTarget (Target* target) 318*30fdc8d8SChris Lattner { 319*30fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 320*30fdc8d8SChris Lattner collection::const_iterator pos, 321*30fdc8d8SChris Lattner begin = m_target_list.begin(), 322*30fdc8d8SChris Lattner end = m_target_list.end(); 323*30fdc8d8SChris Lattner for (pos = begin; pos != end; ++pos) 324*30fdc8d8SChris Lattner { 325*30fdc8d8SChris Lattner if (pos->get() == target) 326*30fdc8d8SChris Lattner { 327*30fdc8d8SChris Lattner m_current_target_idx = std::distance (begin, pos); 328*30fdc8d8SChris Lattner return m_current_target_idx; 329*30fdc8d8SChris Lattner } 330*30fdc8d8SChris Lattner } 331*30fdc8d8SChris Lattner m_current_target_idx = 0; 332*30fdc8d8SChris Lattner return m_current_target_idx; 333*30fdc8d8SChris Lattner } 334*30fdc8d8SChris Lattner 335*30fdc8d8SChris Lattner lldb::TargetSP 336*30fdc8d8SChris Lattner TargetList::GetCurrentTarget () 337*30fdc8d8SChris Lattner { 338*30fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 339*30fdc8d8SChris Lattner if (m_current_target_idx >= m_target_list.size()) 340*30fdc8d8SChris Lattner m_current_target_idx = 0; 341*30fdc8d8SChris Lattner return GetTargetAtIndex (m_current_target_idx); 342*30fdc8d8SChris Lattner } 343