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 #include "lldb/lldb-python.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Core/Broadcaster.h" 17 #include "lldb/Core/Debugger.h" 18 #include "lldb/Core/Event.h" 19 #include "lldb/Core/Module.h" 20 #include "lldb/Core/ModuleSpec.h" 21 #include "lldb/Core/State.h" 22 #include "lldb/Core/Timer.h" 23 #include "lldb/Host/Host.h" 24 #include "lldb/Interpreter/CommandInterpreter.h" 25 #include "lldb/Interpreter/OptionGroupPlatform.h" 26 #include "lldb/Symbol/ObjectFile.h" 27 #include "lldb/Target/Platform.h" 28 #include "lldb/Target/Process.h" 29 #include "lldb/Target/TargetList.h" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 ConstString & 35 TargetList::GetStaticBroadcasterClass () 36 { 37 static ConstString class_name ("lldb.targetList"); 38 return class_name; 39 } 40 41 //---------------------------------------------------------------------- 42 // TargetList constructor 43 //---------------------------------------------------------------------- 44 TargetList::TargetList(Debugger &debugger) : 45 Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()), 46 m_target_list(), 47 m_target_list_mutex (Mutex::eMutexTypeRecursive), 48 m_selected_target_idx (0) 49 { 50 CheckInWithManager(); 51 } 52 53 //---------------------------------------------------------------------- 54 // Destructor 55 //---------------------------------------------------------------------- 56 TargetList::~TargetList() 57 { 58 Mutex::Locker locker(m_target_list_mutex); 59 m_target_list.clear(); 60 } 61 62 Error 63 TargetList::CreateTarget (Debugger &debugger, 64 const char *user_exe_path, 65 const char *triple_cstr, 66 bool get_dependent_files, 67 const OptionGroupPlatform *platform_options, 68 TargetSP &target_sp) 69 { 70 Error error; 71 PlatformSP platform_sp; 72 73 // This is purposely left empty unless it is specified by triple_cstr. 74 // If not initialized via triple_cstr, then the currently selected platform 75 // will set the architecture correctly. 76 const ArchSpec arch(triple_cstr); 77 if (triple_cstr && triple_cstr[0]) 78 { 79 if (!arch.IsValid()) 80 { 81 error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr); 82 return error; 83 } 84 } 85 86 ArchSpec platform_arch(arch); 87 88 89 if (user_exe_path && user_exe_path[0]) 90 { 91 ModuleSpecList module_specs; 92 ModuleSpec module_spec; 93 module_spec.GetFileSpec().SetFile(user_exe_path, true); 94 lldb::offset_t file_offset = 0; 95 lldb::offset_t file_size = 0; 96 const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); 97 if (num_specs > 0) 98 { 99 ModuleSpec matching_module_spec; 100 101 if (num_specs == 1) 102 { 103 if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 104 { 105 if (platform_arch.IsValid()) 106 { 107 if (!platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) 108 { 109 error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 110 platform_arch.GetTriple().str().c_str(), 111 matching_module_spec.GetArchitecture().GetTriple().str().c_str(), 112 module_spec.GetFileSpec().GetPath().c_str()); 113 return error; 114 } 115 } 116 else 117 { 118 // Only one arch and none was specified 119 platform_arch = matching_module_spec.GetArchitecture(); 120 } 121 } 122 } 123 else 124 { 125 if (arch.IsValid()) 126 { 127 module_spec.GetArchitecture() = arch; 128 if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 129 { 130 platform_arch = matching_module_spec.GetArchitecture(); 131 } 132 } 133 // Don't just select the first architecture, we want to let the platform select 134 // the best architecture first when there are multiple archs. 135 // else 136 // { 137 // // No arch specified, select the first arch 138 // if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 139 // { 140 // platform_arch = matching_module_spec.GetArchitecture(); 141 // } 142 // } 143 } 144 } 145 } 146 147 CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 148 if (platform_options) 149 { 150 if (platform_options->PlatformWasSpecified ()) 151 { 152 const bool select_platform = true; 153 platform_sp = platform_options->CreatePlatformWithOptions (interpreter, 154 arch, 155 select_platform, 156 error, 157 platform_arch); 158 if (!platform_sp) 159 return error; 160 } 161 } 162 163 if (!platform_sp) 164 { 165 // Get the current platform and make sure it is compatible with the 166 // current architecture if we have a valid architecture. 167 platform_sp = debugger.GetPlatformList().GetSelectedPlatform (); 168 169 if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 170 { 171 platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 172 } 173 } 174 175 if (!platform_arch.IsValid()) 176 platform_arch = arch; 177 178 error = TargetList::CreateTarget (debugger, 179 user_exe_path, 180 platform_arch, 181 get_dependent_files, 182 platform_sp, 183 target_sp); 184 return error; 185 } 186 187 Error 188 TargetList::CreateTarget (Debugger &debugger, 189 const char *user_exe_path, 190 const ArchSpec& specified_arch, 191 bool get_dependent_files, 192 PlatformSP &platform_sp, 193 TargetSP &target_sp) 194 { 195 Timer scoped_timer (__PRETTY_FUNCTION__, 196 "TargetList::CreateTarget (file = '%s', arch = '%s')", 197 user_exe_path, 198 specified_arch.GetArchitectureName()); 199 Error error; 200 201 ArchSpec arch(specified_arch); 202 203 if (platform_sp) 204 { 205 if (arch.IsValid()) 206 { 207 if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 208 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 209 } 210 } 211 else if (arch.IsValid()) 212 { 213 platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 214 } 215 216 if (!platform_sp) 217 platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 218 219 if (!arch.IsValid()) 220 arch = specified_arch; 221 222 FileSpec file (user_exe_path, false); 223 if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 224 { 225 file = FileSpec(user_exe_path, true); 226 } 227 bool user_exe_path_is_bundle = false; 228 char resolved_bundle_exe_path[PATH_MAX]; 229 resolved_bundle_exe_path[0] = '\0'; 230 if (file) 231 { 232 if (file.GetFileType() == FileSpec::eFileTypeDirectory) 233 user_exe_path_is_bundle = true; 234 235 if (file.IsRelativeToCurrentWorkingDirectory()) 236 { 237 // Ignore paths that start with "./" and "../" 238 if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 239 (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 240 { 241 char cwd[PATH_MAX]; 242 if (getcwd (cwd, sizeof(cwd))) 243 { 244 std::string cwd_user_exe_path (cwd); 245 cwd_user_exe_path += '/'; 246 cwd_user_exe_path += user_exe_path; 247 FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 248 if (cwd_file.Exists()) 249 file = cwd_file; 250 } 251 } 252 } 253 254 ModuleSP exe_module_sp; 255 if (platform_sp) 256 { 257 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 258 error = platform_sp->ResolveExecutable (file, 259 arch, 260 exe_module_sp, 261 executable_search_paths.GetSize() ? &executable_search_paths : NULL); 262 } 263 264 if (error.Success() && exe_module_sp) 265 { 266 if (exe_module_sp->GetObjectFile() == NULL) 267 { 268 if (arch.IsValid()) 269 { 270 error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 271 file.GetPath().c_str(), 272 arch.GetArchitectureName()); 273 } 274 else 275 { 276 error.SetErrorStringWithFormat("unsupported file type \"%s\"", 277 file.GetPath().c_str()); 278 } 279 return error; 280 } 281 target_sp.reset(new Target(debugger, arch, platform_sp)); 282 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 283 if (user_exe_path_is_bundle) 284 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 285 } 286 } 287 else 288 { 289 // No file was specified, just create an empty target with any arch 290 // if a valid arch was specified 291 target_sp.reset(new Target(debugger, arch, platform_sp)); 292 } 293 294 if (target_sp) 295 { 296 // Set argv0 with what the user typed, unless the user specified a 297 // directory. If the user specified a directory, then it is probably a 298 // bundle that was resolved and we need to use the resolved bundle path 299 if (user_exe_path) 300 { 301 // Use exactly what the user typed as the first argument when we exec or posix_spawn 302 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 303 { 304 target_sp->SetArg0 (resolved_bundle_exe_path); 305 } 306 else 307 { 308 // Just use what the user typed 309 target_sp->SetArg0 (user_exe_path); 310 } 311 } 312 if (file.GetDirectory()) 313 { 314 FileSpec file_dir; 315 file_dir.GetDirectory() = file.GetDirectory(); 316 target_sp->GetExecutableSearchPaths ().Append (file_dir); 317 } 318 Mutex::Locker locker(m_target_list_mutex); 319 m_selected_target_idx = m_target_list.size(); 320 m_target_list.push_back(target_sp); 321 322 323 } 324 325 return error; 326 } 327 328 bool 329 TargetList::DeleteTarget (TargetSP &target_sp) 330 { 331 Mutex::Locker locker(m_target_list_mutex); 332 collection::iterator pos, end = m_target_list.end(); 333 334 for (pos = m_target_list.begin(); pos != end; ++pos) 335 { 336 if (pos->get() == target_sp.get()) 337 { 338 m_target_list.erase(pos); 339 return true; 340 } 341 } 342 return false; 343 } 344 345 346 TargetSP 347 TargetList::FindTargetWithExecutableAndArchitecture 348 ( 349 const FileSpec &exe_file_spec, 350 const ArchSpec *exe_arch_ptr 351 ) const 352 { 353 Mutex::Locker locker (m_target_list_mutex); 354 TargetSP target_sp; 355 bool full_match = exe_file_spec.GetDirectory(); 356 357 collection::const_iterator pos, end = m_target_list.end(); 358 for (pos = m_target_list.begin(); pos != end; ++pos) 359 { 360 Module *exe_module = (*pos)->GetExecutableModulePointer(); 361 362 if (exe_module) 363 { 364 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 365 { 366 if (exe_arch_ptr) 367 { 368 if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 369 continue; 370 } 371 target_sp = *pos; 372 break; 373 } 374 } 375 } 376 return target_sp; 377 } 378 379 TargetSP 380 TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 381 { 382 Mutex::Locker locker(m_target_list_mutex); 383 TargetSP target_sp; 384 collection::const_iterator pos, end = m_target_list.end(); 385 for (pos = m_target_list.begin(); pos != end; ++pos) 386 { 387 Process* process = (*pos)->GetProcessSP().get(); 388 if (process && process->GetID() == pid) 389 { 390 target_sp = *pos; 391 break; 392 } 393 } 394 return target_sp; 395 } 396 397 398 TargetSP 399 TargetList::FindTargetWithProcess (Process *process) const 400 { 401 TargetSP target_sp; 402 if (process) 403 { 404 Mutex::Locker locker(m_target_list_mutex); 405 collection::const_iterator pos, end = m_target_list.end(); 406 for (pos = m_target_list.begin(); pos != end; ++pos) 407 { 408 if (process == (*pos)->GetProcessSP().get()) 409 { 410 target_sp = *pos; 411 break; 412 } 413 } 414 } 415 return target_sp; 416 } 417 418 TargetSP 419 TargetList::GetTargetSP (Target *target) const 420 { 421 TargetSP target_sp; 422 if (target) 423 { 424 Mutex::Locker locker(m_target_list_mutex); 425 collection::const_iterator pos, end = m_target_list.end(); 426 for (pos = m_target_list.begin(); pos != end; ++pos) 427 { 428 if (target == (*pos).get()) 429 { 430 target_sp = *pos; 431 break; 432 } 433 } 434 } 435 return target_sp; 436 } 437 438 uint32_t 439 TargetList::SendAsyncInterrupt (lldb::pid_t pid) 440 { 441 uint32_t num_async_interrupts_sent = 0; 442 443 if (pid != LLDB_INVALID_PROCESS_ID) 444 { 445 TargetSP target_sp(FindTargetWithProcessID (pid)); 446 if (target_sp.get()) 447 { 448 Process* process = target_sp->GetProcessSP().get(); 449 if (process) 450 { 451 process->SendAsyncInterrupt(); 452 ++num_async_interrupts_sent; 453 } 454 } 455 } 456 else 457 { 458 // We don't have a valid pid to broadcast to, so broadcast to the target 459 // list's async broadcaster... 460 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 461 } 462 463 return num_async_interrupts_sent; 464 } 465 466 uint32_t 467 TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 468 { 469 uint32_t num_signals_sent = 0; 470 Process *process = NULL; 471 if (pid == LLDB_INVALID_PROCESS_ID) 472 { 473 // Signal all processes with signal 474 Mutex::Locker locker(m_target_list_mutex); 475 collection::iterator pos, end = m_target_list.end(); 476 for (pos = m_target_list.begin(); pos != end; ++pos) 477 { 478 process = (*pos)->GetProcessSP().get(); 479 if (process) 480 { 481 if (process->IsAlive()) 482 { 483 ++num_signals_sent; 484 process->Signal (signo); 485 } 486 } 487 } 488 } 489 else 490 { 491 // Signal a specific process with signal 492 TargetSP target_sp(FindTargetWithProcessID (pid)); 493 if (target_sp.get()) 494 { 495 process = target_sp->GetProcessSP().get(); 496 if (process) 497 { 498 if (process->IsAlive()) 499 { 500 ++num_signals_sent; 501 process->Signal (signo); 502 } 503 } 504 } 505 } 506 return num_signals_sent; 507 } 508 509 int 510 TargetList::GetNumTargets () const 511 { 512 Mutex::Locker locker (m_target_list_mutex); 513 return m_target_list.size(); 514 } 515 516 lldb::TargetSP 517 TargetList::GetTargetAtIndex (uint32_t idx) const 518 { 519 TargetSP target_sp; 520 Mutex::Locker locker (m_target_list_mutex); 521 if (idx < m_target_list.size()) 522 target_sp = m_target_list[idx]; 523 return target_sp; 524 } 525 526 uint32_t 527 TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 528 { 529 Mutex::Locker locker (m_target_list_mutex); 530 size_t num_targets = m_target_list.size(); 531 for (size_t idx = 0; idx < num_targets; idx++) 532 { 533 if (target_sp == m_target_list[idx]) 534 return idx; 535 } 536 return UINT32_MAX; 537 } 538 539 uint32_t 540 TargetList::SetSelectedTarget (Target* target) 541 { 542 Mutex::Locker locker (m_target_list_mutex); 543 collection::const_iterator pos, 544 begin = m_target_list.begin(), 545 end = m_target_list.end(); 546 for (pos = begin; pos != end; ++pos) 547 { 548 if (pos->get() == target) 549 { 550 m_selected_target_idx = std::distance (begin, pos); 551 return m_selected_target_idx; 552 } 553 } 554 m_selected_target_idx = 0; 555 return m_selected_target_idx; 556 } 557 558 lldb::TargetSP 559 TargetList::GetSelectedTarget () 560 { 561 Mutex::Locker locker (m_target_list_mutex); 562 if (m_selected_target_idx >= m_target_list.size()) 563 m_selected_target_idx = 0; 564 return GetTargetAtIndex (m_selected_target_idx); 565 } 566