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 // we want to expand the tilde but we don't want to resolve any symbolic links 226 // so we can't use the FileSpec constructor's resolve flag 227 char unglobbed_path[PATH_MAX]; 228 unglobbed_path[0] = '\0'; 229 230 size_t return_count = FileSpec::ResolveUsername(user_exe_path, unglobbed_path, sizeof(unglobbed_path)); 231 232 if (return_count == 0 || return_count >= sizeof(unglobbed_path)) 233 ::snprintf (unglobbed_path, sizeof(unglobbed_path), "%s", user_exe_path); 234 235 file = FileSpec(unglobbed_path, false); 236 } 237 238 bool user_exe_path_is_bundle = false; 239 char resolved_bundle_exe_path[PATH_MAX]; 240 resolved_bundle_exe_path[0] = '\0'; 241 if (file) 242 { 243 if (file.GetFileType() == FileSpec::eFileTypeDirectory) 244 user_exe_path_is_bundle = true; 245 246 if (file.IsRelativeToCurrentWorkingDirectory()) 247 { 248 // Ignore paths that start with "./" and "../" 249 if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 250 (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 251 { 252 char cwd[PATH_MAX]; 253 if (getcwd (cwd, sizeof(cwd))) 254 { 255 std::string cwd_user_exe_path (cwd); 256 cwd_user_exe_path += '/'; 257 cwd_user_exe_path += user_exe_path; 258 FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 259 if (cwd_file.Exists()) 260 file = cwd_file; 261 } 262 } 263 } 264 265 ModuleSP exe_module_sp; 266 if (platform_sp) 267 { 268 FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 269 error = platform_sp->ResolveExecutable (file, 270 arch, 271 exe_module_sp, 272 executable_search_paths.GetSize() ? &executable_search_paths : NULL); 273 } 274 275 if (error.Success() && exe_module_sp) 276 { 277 if (exe_module_sp->GetObjectFile() == NULL) 278 { 279 if (arch.IsValid()) 280 { 281 error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 282 file.GetPath().c_str(), 283 arch.GetArchitectureName()); 284 } 285 else 286 { 287 error.SetErrorStringWithFormat("unsupported file type \"%s\"", 288 file.GetPath().c_str()); 289 } 290 return error; 291 } 292 target_sp.reset(new Target(debugger, arch, platform_sp)); 293 target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 294 if (user_exe_path_is_bundle) 295 exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 296 } 297 } 298 else 299 { 300 // No file was specified, just create an empty target with any arch 301 // if a valid arch was specified 302 target_sp.reset(new Target(debugger, arch, platform_sp)); 303 } 304 305 if (target_sp) 306 { 307 // Set argv0 with what the user typed, unless the user specified a 308 // directory. If the user specified a directory, then it is probably a 309 // bundle that was resolved and we need to use the resolved bundle path 310 if (user_exe_path) 311 { 312 // Use exactly what the user typed as the first argument when we exec or posix_spawn 313 if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 314 { 315 target_sp->SetArg0 (resolved_bundle_exe_path); 316 } 317 else 318 { 319 // Use resolved path 320 target_sp->SetArg0 (file.GetPath().c_str()); 321 } 322 } 323 if (file.GetDirectory()) 324 { 325 FileSpec file_dir; 326 file_dir.GetDirectory() = file.GetDirectory(); 327 target_sp->GetExecutableSearchPaths ().Append (file_dir); 328 } 329 Mutex::Locker locker(m_target_list_mutex); 330 m_selected_target_idx = m_target_list.size(); 331 m_target_list.push_back(target_sp); 332 333 334 } 335 336 return error; 337 } 338 339 bool 340 TargetList::DeleteTarget (TargetSP &target_sp) 341 { 342 Mutex::Locker locker(m_target_list_mutex); 343 collection::iterator pos, end = m_target_list.end(); 344 345 for (pos = m_target_list.begin(); pos != end; ++pos) 346 { 347 if (pos->get() == target_sp.get()) 348 { 349 m_target_list.erase(pos); 350 return true; 351 } 352 } 353 return false; 354 } 355 356 357 TargetSP 358 TargetList::FindTargetWithExecutableAndArchitecture 359 ( 360 const FileSpec &exe_file_spec, 361 const ArchSpec *exe_arch_ptr 362 ) const 363 { 364 Mutex::Locker locker (m_target_list_mutex); 365 TargetSP target_sp; 366 bool full_match = exe_file_spec.GetDirectory(); 367 368 collection::const_iterator pos, end = m_target_list.end(); 369 for (pos = m_target_list.begin(); pos != end; ++pos) 370 { 371 Module *exe_module = (*pos)->GetExecutableModulePointer(); 372 373 if (exe_module) 374 { 375 if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 376 { 377 if (exe_arch_ptr) 378 { 379 if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 380 continue; 381 } 382 target_sp = *pos; 383 break; 384 } 385 } 386 } 387 return target_sp; 388 } 389 390 TargetSP 391 TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 392 { 393 Mutex::Locker locker(m_target_list_mutex); 394 TargetSP target_sp; 395 collection::const_iterator pos, end = m_target_list.end(); 396 for (pos = m_target_list.begin(); pos != end; ++pos) 397 { 398 Process* process = (*pos)->GetProcessSP().get(); 399 if (process && process->GetID() == pid) 400 { 401 target_sp = *pos; 402 break; 403 } 404 } 405 return target_sp; 406 } 407 408 409 TargetSP 410 TargetList::FindTargetWithProcess (Process *process) const 411 { 412 TargetSP target_sp; 413 if (process) 414 { 415 Mutex::Locker locker(m_target_list_mutex); 416 collection::const_iterator pos, end = m_target_list.end(); 417 for (pos = m_target_list.begin(); pos != end; ++pos) 418 { 419 if (process == (*pos)->GetProcessSP().get()) 420 { 421 target_sp = *pos; 422 break; 423 } 424 } 425 } 426 return target_sp; 427 } 428 429 TargetSP 430 TargetList::GetTargetSP (Target *target) const 431 { 432 TargetSP target_sp; 433 if (target) 434 { 435 Mutex::Locker locker(m_target_list_mutex); 436 collection::const_iterator pos, end = m_target_list.end(); 437 for (pos = m_target_list.begin(); pos != end; ++pos) 438 { 439 if (target == (*pos).get()) 440 { 441 target_sp = *pos; 442 break; 443 } 444 } 445 } 446 return target_sp; 447 } 448 449 uint32_t 450 TargetList::SendAsyncInterrupt (lldb::pid_t pid) 451 { 452 uint32_t num_async_interrupts_sent = 0; 453 454 if (pid != LLDB_INVALID_PROCESS_ID) 455 { 456 TargetSP target_sp(FindTargetWithProcessID (pid)); 457 if (target_sp.get()) 458 { 459 Process* process = target_sp->GetProcessSP().get(); 460 if (process) 461 { 462 process->SendAsyncInterrupt(); 463 ++num_async_interrupts_sent; 464 } 465 } 466 } 467 else 468 { 469 // We don't have a valid pid to broadcast to, so broadcast to the target 470 // list's async broadcaster... 471 BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 472 } 473 474 return num_async_interrupts_sent; 475 } 476 477 uint32_t 478 TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 479 { 480 uint32_t num_signals_sent = 0; 481 Process *process = NULL; 482 if (pid == LLDB_INVALID_PROCESS_ID) 483 { 484 // Signal all processes with signal 485 Mutex::Locker locker(m_target_list_mutex); 486 collection::iterator pos, end = m_target_list.end(); 487 for (pos = m_target_list.begin(); pos != end; ++pos) 488 { 489 process = (*pos)->GetProcessSP().get(); 490 if (process) 491 { 492 if (process->IsAlive()) 493 { 494 ++num_signals_sent; 495 process->Signal (signo); 496 } 497 } 498 } 499 } 500 else 501 { 502 // Signal a specific process with signal 503 TargetSP target_sp(FindTargetWithProcessID (pid)); 504 if (target_sp.get()) 505 { 506 process = target_sp->GetProcessSP().get(); 507 if (process) 508 { 509 if (process->IsAlive()) 510 { 511 ++num_signals_sent; 512 process->Signal (signo); 513 } 514 } 515 } 516 } 517 return num_signals_sent; 518 } 519 520 int 521 TargetList::GetNumTargets () const 522 { 523 Mutex::Locker locker (m_target_list_mutex); 524 return m_target_list.size(); 525 } 526 527 lldb::TargetSP 528 TargetList::GetTargetAtIndex (uint32_t idx) const 529 { 530 TargetSP target_sp; 531 Mutex::Locker locker (m_target_list_mutex); 532 if (idx < m_target_list.size()) 533 target_sp = m_target_list[idx]; 534 return target_sp; 535 } 536 537 uint32_t 538 TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 539 { 540 Mutex::Locker locker (m_target_list_mutex); 541 size_t num_targets = m_target_list.size(); 542 for (size_t idx = 0; idx < num_targets; idx++) 543 { 544 if (target_sp == m_target_list[idx]) 545 return idx; 546 } 547 return UINT32_MAX; 548 } 549 550 uint32_t 551 TargetList::SetSelectedTarget (Target* target) 552 { 553 Mutex::Locker locker (m_target_list_mutex); 554 collection::const_iterator pos, 555 begin = m_target_list.begin(), 556 end = m_target_list.end(); 557 for (pos = begin; pos != end; ++pos) 558 { 559 if (pos->get() == target) 560 { 561 m_selected_target_idx = std::distance (begin, pos); 562 return m_selected_target_idx; 563 } 564 } 565 m_selected_target_idx = 0; 566 return m_selected_target_idx; 567 } 568 569 lldb::TargetSP 570 TargetList::GetSelectedTarget () 571 { 572 Mutex::Locker locker (m_target_list_mutex); 573 if (m_selected_target_idx >= m_target_list.size()) 574 m_selected_target_idx = 0; 575 return GetTargetAtIndex (m_selected_target_idx); 576 } 577