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