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 if (arch.IsValid()) 94 { 95 error.SetErrorStringWithFormat("\"%s%s%s\" doesn't contain architecture %s", 96 file.GetDirectory().AsCString(), 97 file.GetDirectory() ? "/" : "", 98 file.GetFilename().AsCString(), 99 arch.AsCString()); 100 } 101 else 102 { 103 error.SetErrorStringWithFormat("unsupported file type \"%s%s%s\"", 104 file.GetDirectory().AsCString(), 105 file.GetDirectory() ? "/" : "", 106 file.GetFilename().AsCString()); 107 } 108 return error; 109 } 110 target_sp.reset(new Target(debugger)); 111 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 112 } 113 } 114 115 if (target_sp.get()) 116 target_sp->UpdateInstanceName(); 117 118 if (target_sp.get()) 119 { 120 Mutex::Locker locker(m_target_list_mutex); 121 m_selected_target_idx = m_target_list.size(); 122 m_target_list.push_back(target_sp); 123 } 124 125 // target_sp.reset(new Target); 126 // // Let the target resolve any funky bundle paths before we try and get 127 // // the object file... 128 // target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 129 // if (exe_module_sp->GetObjectFile() == NULL) 130 // { 131 // error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s", 132 // file.GetDirectory().AsCString(), 133 // file.GetDirectory() ? "/" : "", 134 // file.GetFilename().AsCString(), 135 // arch.AsCString()); 136 // } 137 // else 138 // { 139 // if (target_sp.get()) 140 // { 141 // error.Clear(); 142 // Mutex::Locker locker(m_target_list_mutex); 143 // m_selected_target_idx = m_target_list.size(); 144 // m_target_list.push_back(target_sp); 145 // } 146 // } 147 else 148 { 149 target_sp.reset(); 150 } 151 152 return error; 153 } 154 155 bool 156 TargetList::DeleteTarget (TargetSP &target_sp) 157 { 158 Mutex::Locker locker(m_target_list_mutex); 159 collection::iterator pos, end = m_target_list.end(); 160 161 for (pos = m_target_list.begin(); pos != end; ++pos) 162 { 163 if (pos->get() == target_sp.get()) 164 { 165 m_target_list.erase(pos); 166 return true; 167 } 168 } 169 return false; 170 } 171 172 173 TargetSP 174 TargetList::FindTargetWithExecutableAndArchitecture 175 ( 176 const FileSpec &exe_file_spec, 177 const ArchSpec *exe_arch_ptr 178 ) const 179 { 180 Mutex::Locker locker (m_target_list_mutex); 181 TargetSP target_sp; 182 bool full_match = exe_file_spec.GetDirectory(); 183 184 collection::const_iterator pos, end = m_target_list.end(); 185 for (pos = m_target_list.begin(); pos != end; ++pos) 186 { 187 ModuleSP module_sp ((*pos)->GetExecutableModule()); 188 189 if (module_sp) 190 { 191 if (FileSpec::Equal (exe_file_spec, module_sp->GetFileSpec(), full_match)) 192 { 193 if (exe_arch_ptr) 194 { 195 if (*exe_arch_ptr != module_sp->GetArchitecture()) 196 continue; 197 } 198 target_sp = *pos; 199 break; 200 } 201 } 202 } 203 return target_sp; 204 } 205 206 TargetSP 207 TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 208 { 209 Mutex::Locker locker(m_target_list_mutex); 210 TargetSP target_sp; 211 collection::const_iterator pos, end = m_target_list.end(); 212 for (pos = m_target_list.begin(); pos != end; ++pos) 213 { 214 Process* process = (*pos)->GetProcessSP().get(); 215 if (process && process->GetID() == pid) 216 { 217 target_sp = *pos; 218 break; 219 } 220 } 221 return target_sp; 222 } 223 224 225 TargetSP 226 TargetList::FindTargetWithProcess (Process *process) const 227 { 228 TargetSP target_sp; 229 if (process) 230 { 231 Mutex::Locker locker(m_target_list_mutex); 232 collection::const_iterator pos, end = m_target_list.end(); 233 for (pos = m_target_list.begin(); pos != end; ++pos) 234 { 235 if (process == (*pos)->GetProcessSP().get()) 236 { 237 target_sp = *pos; 238 break; 239 } 240 } 241 } 242 return target_sp; 243 } 244 245 TargetSP 246 TargetList::GetTargetSP (Target *target) const 247 { 248 TargetSP target_sp; 249 if (target) 250 { 251 Mutex::Locker locker(m_target_list_mutex); 252 collection::const_iterator pos, end = m_target_list.end(); 253 for (pos = m_target_list.begin(); pos != end; ++pos) 254 { 255 if (target == (*pos).get()) 256 { 257 target_sp = *pos; 258 break; 259 } 260 } 261 } 262 return target_sp; 263 } 264 265 uint32_t 266 TargetList::SendAsyncInterrupt (lldb::pid_t pid) 267 { 268 uint32_t num_async_interrupts_sent = 0; 269 270 if (pid != LLDB_INVALID_PROCESS_ID) 271 { 272 TargetSP target_sp(FindTargetWithProcessID (pid)); 273 if (target_sp.get()) 274 { 275 Process* process = target_sp->GetProcessSP().get(); 276 if (process) 277 { 278 process->BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 279 ++num_async_interrupts_sent; 280 } 281 } 282 } 283 else 284 { 285 // We don't have a valid pid to broadcast to, so broadcast to the target 286 // list's async broadcaster... 287 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 288 } 289 290 return num_async_interrupts_sent; 291 } 292 293 uint32_t 294 TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 295 { 296 uint32_t num_signals_sent = 0; 297 Process *process = NULL; 298 if (pid == LLDB_INVALID_PROCESS_ID) 299 { 300 // Signal all processes with signal 301 Mutex::Locker locker(m_target_list_mutex); 302 collection::iterator pos, end = m_target_list.end(); 303 for (pos = m_target_list.begin(); pos != end; ++pos) 304 { 305 process = (*pos)->GetProcessSP().get(); 306 if (process) 307 { 308 if (process->IsAlive()) 309 { 310 ++num_signals_sent; 311 process->Signal (signo); 312 } 313 } 314 } 315 } 316 else 317 { 318 // Signal a specific process with signal 319 TargetSP target_sp(FindTargetWithProcessID (pid)); 320 if (target_sp.get()) 321 { 322 process = target_sp->GetProcessSP().get(); 323 if (process) 324 { 325 if (process->IsAlive()) 326 { 327 ++num_signals_sent; 328 process->Signal (signo); 329 } 330 } 331 } 332 } 333 return num_signals_sent; 334 } 335 336 int 337 TargetList::GetNumTargets () const 338 { 339 Mutex::Locker locker (m_target_list_mutex); 340 return m_target_list.size(); 341 } 342 343 lldb::TargetSP 344 TargetList::GetTargetAtIndex (uint32_t idx) const 345 { 346 TargetSP target_sp; 347 Mutex::Locker locker (m_target_list_mutex); 348 if (idx < m_target_list.size()) 349 target_sp = m_target_list[idx]; 350 return target_sp; 351 } 352 353 uint32_t 354 TargetList::SetSelectedTarget (Target* target) 355 { 356 Mutex::Locker locker (m_target_list_mutex); 357 collection::const_iterator pos, 358 begin = m_target_list.begin(), 359 end = m_target_list.end(); 360 for (pos = begin; pos != end; ++pos) 361 { 362 if (pos->get() == target) 363 { 364 m_selected_target_idx = std::distance (begin, pos); 365 return m_selected_target_idx; 366 } 367 } 368 m_selected_target_idx = 0; 369 return m_selected_target_idx; 370 } 371 372 lldb::TargetSP 373 TargetList::GetSelectedTarget () 374 { 375 Mutex::Locker locker (m_target_list_mutex); 376 if (m_selected_target_idx >= m_target_list.size()) 377 m_selected_target_idx = 0; 378 return GetTargetAtIndex (m_selected_target_idx); 379 } 380