130fdc8d8SChris Lattner //===-- TargetList.cpp ------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/Core/Broadcaster.h" 17ded470d3SGreg Clayton #include "lldb/Core/Debugger.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Event.h" 191f746071SGreg Clayton #include "lldb/Core/Module.h" 20f4d6de6aSGreg Clayton #include "lldb/Core/ModuleSpec.h" 2130fdc8d8SChris Lattner #include "lldb/Core/State.h" 2230fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 2330fdc8d8SChris Lattner #include "lldb/Host/Host.h" 24b3a40ba8SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 25cac9c5f9SGreg Clayton #include "lldb/Interpreter/OptionGroupPlatform.h" 26f4d6de6aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 27e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2830fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2930fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 3030fdc8d8SChris Lattner 3130fdc8d8SChris Lattner using namespace lldb; 3230fdc8d8SChris Lattner using namespace lldb_private; 3330fdc8d8SChris Lattner 344bddaeb5SJim Ingham ConstString & 354bddaeb5SJim Ingham TargetList::GetStaticBroadcasterClass () 364bddaeb5SJim Ingham { 374bddaeb5SJim Ingham static ConstString class_name ("lldb.targetList"); 384bddaeb5SJim Ingham return class_name; 394bddaeb5SJim Ingham } 4030fdc8d8SChris Lattner 4130fdc8d8SChris Lattner //---------------------------------------------------------------------- 4230fdc8d8SChris Lattner // TargetList constructor 4330fdc8d8SChris Lattner //---------------------------------------------------------------------- 444bddaeb5SJim Ingham TargetList::TargetList(Debugger &debugger) : 454f465cffSJim Ingham Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()), 4630fdc8d8SChris Lattner m_target_list(), 4730fdc8d8SChris Lattner m_target_list_mutex (Mutex::eMutexTypeRecursive), 482976d00aSJim Ingham m_selected_target_idx (0) 4930fdc8d8SChris Lattner { 504bddaeb5SJim Ingham CheckInWithManager(); 5130fdc8d8SChris Lattner } 5230fdc8d8SChris Lattner 5330fdc8d8SChris Lattner //---------------------------------------------------------------------- 5430fdc8d8SChris Lattner // Destructor 5530fdc8d8SChris Lattner //---------------------------------------------------------------------- 5630fdc8d8SChris Lattner TargetList::~TargetList() 5730fdc8d8SChris Lattner { 5830fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 5930fdc8d8SChris Lattner m_target_list.clear(); 6030fdc8d8SChris Lattner } 6130fdc8d8SChris Lattner 6230fdc8d8SChris Lattner Error 63cac9c5f9SGreg Clayton TargetList::CreateTarget (Debugger &debugger, 64a0ca6601SGreg Clayton const char *user_exe_path, 65cac9c5f9SGreg Clayton const char *triple_cstr, 66cac9c5f9SGreg Clayton bool get_dependent_files, 67cac9c5f9SGreg Clayton const OptionGroupPlatform *platform_options, 68cac9c5f9SGreg Clayton TargetSP &target_sp) 69cac9c5f9SGreg Clayton { 70cac9c5f9SGreg Clayton Error error; 71cac9c5f9SGreg Clayton PlatformSP platform_sp; 72cac9c5f9SGreg Clayton 73cdc21d4cSJohnny Chen // This is purposely left empty unless it is specified by triple_cstr. 74cdc21d4cSJohnny Chen // If not initialized via triple_cstr, then the currently selected platform 75cdc21d4cSJohnny Chen // will set the architecture correctly. 7670512317SGreg Clayton const ArchSpec arch(triple_cstr); 7770512317SGreg Clayton if (triple_cstr && triple_cstr[0]) 78cac9c5f9SGreg Clayton { 79cac9c5f9SGreg Clayton if (!arch.IsValid()) 80cac9c5f9SGreg Clayton { 8186edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr); 82cac9c5f9SGreg Clayton return error; 83cac9c5f9SGreg Clayton } 84cac9c5f9SGreg Clayton } 85b3a40ba8SGreg Clayton 8670512317SGreg Clayton ArchSpec platform_arch(arch); 87f4d6de6aSGreg Clayton 883f19ada8SGreg Clayton bool prefer_platform_arch = false; 89f4d6de6aSGreg Clayton 90f4d6de6aSGreg Clayton if (user_exe_path && user_exe_path[0]) 91f4d6de6aSGreg Clayton { 92f4d6de6aSGreg Clayton ModuleSpecList module_specs; 93f4d6de6aSGreg Clayton ModuleSpec module_spec; 94f4d6de6aSGreg Clayton module_spec.GetFileSpec().SetFile(user_exe_path, true); 95*c76fa8a3SGreg Clayton 96*c76fa8a3SGreg Clayton // Resolve the executable in case we are given a path to a application bundle 97*c76fa8a3SGreg Clayton // like a .app bundle on MacOSX 98*c76fa8a3SGreg Clayton Host::ResolveExecutableInBundle (module_spec.GetFileSpec()); 99*c76fa8a3SGreg Clayton 100f4d6de6aSGreg Clayton lldb::offset_t file_offset = 0; 1012540a8a7SGreg Clayton lldb::offset_t file_size = 0; 1022540a8a7SGreg Clayton const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); 103f4d6de6aSGreg Clayton if (num_specs > 0) 104f4d6de6aSGreg Clayton { 105f4d6de6aSGreg Clayton ModuleSpec matching_module_spec; 106f4d6de6aSGreg Clayton 107f4d6de6aSGreg Clayton if (num_specs == 1) 108f4d6de6aSGreg Clayton { 109f4d6de6aSGreg Clayton if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 110f4d6de6aSGreg Clayton { 111f4d6de6aSGreg Clayton if (platform_arch.IsValid()) 112f4d6de6aSGreg Clayton { 1133f19ada8SGreg Clayton if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) 1143f19ada8SGreg Clayton { 1153f19ada8SGreg Clayton // If the OS or vendor weren't specified, then adopt the module's 1163f19ada8SGreg Clayton // architecture so that the platform matching can be more accurate 1173f19ada8SGreg Clayton if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified()) 1183f19ada8SGreg Clayton { 1193f19ada8SGreg Clayton prefer_platform_arch = true; 1203f19ada8SGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 1213f19ada8SGreg Clayton } 1223f19ada8SGreg Clayton } 1233f19ada8SGreg Clayton else 124f4d6de6aSGreg Clayton { 125b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 126f4d6de6aSGreg Clayton platform_arch.GetTriple().str().c_str(), 127f4d6de6aSGreg Clayton matching_module_spec.GetArchitecture().GetTriple().str().c_str(), 128b5ad4ec7SGreg Clayton module_spec.GetFileSpec().GetPath().c_str()); 129f4d6de6aSGreg Clayton return error; 130f4d6de6aSGreg Clayton } 131f4d6de6aSGreg Clayton } 132f4d6de6aSGreg Clayton else 133f4d6de6aSGreg Clayton { 134f4d6de6aSGreg Clayton // Only one arch and none was specified 1353f19ada8SGreg Clayton prefer_platform_arch = true; 136f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 137f4d6de6aSGreg Clayton } 138f4d6de6aSGreg Clayton } 139f4d6de6aSGreg Clayton } 140f4d6de6aSGreg Clayton else 141f4d6de6aSGreg Clayton { 142f4d6de6aSGreg Clayton if (arch.IsValid()) 143f4d6de6aSGreg Clayton { 144f4d6de6aSGreg Clayton module_spec.GetArchitecture() = arch; 145f4d6de6aSGreg Clayton if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 146f4d6de6aSGreg Clayton { 1473f19ada8SGreg Clayton prefer_platform_arch = true; 148f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 149f4d6de6aSGreg Clayton } 150f4d6de6aSGreg Clayton } 151f4d6de6aSGreg Clayton } 152f4d6de6aSGreg Clayton } 153f4d6de6aSGreg Clayton } 154f4d6de6aSGreg Clayton 155b3a40ba8SGreg Clayton CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 156b3a40ba8SGreg Clayton if (platform_options) 157b3a40ba8SGreg Clayton { 158b3a40ba8SGreg Clayton if (platform_options->PlatformWasSpecified ()) 159b3a40ba8SGreg Clayton { 160b3a40ba8SGreg Clayton const bool select_platform = true; 161b3a40ba8SGreg Clayton platform_sp = platform_options->CreatePlatformWithOptions (interpreter, 162b3a40ba8SGreg Clayton arch, 163b3a40ba8SGreg Clayton select_platform, 16470512317SGreg Clayton error, 16570512317SGreg Clayton platform_arch); 166b3a40ba8SGreg Clayton if (!platform_sp) 167b3a40ba8SGreg Clayton return error; 168b3a40ba8SGreg Clayton } 169b3a40ba8SGreg Clayton } 170b3a40ba8SGreg Clayton 171b3a40ba8SGreg Clayton if (!platform_sp) 172b3a40ba8SGreg Clayton { 173b3a40ba8SGreg Clayton // Get the current platform and make sure it is compatible with the 174b3a40ba8SGreg Clayton // current architecture if we have a valid architecture. 175b3a40ba8SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform (); 176b3a40ba8SGreg Clayton 1773f19ada8SGreg Clayton if (!prefer_platform_arch && arch.IsValid()) 178b3a40ba8SGreg Clayton { 1793f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 18070512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 181b3a40ba8SGreg Clayton } 1823f19ada8SGreg Clayton else if (platform_arch.IsValid()) 1833f19ada8SGreg Clayton { 1843f19ada8SGreg Clayton // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with 1853f19ada8SGreg Clayton // a single architecture which should be used 1863f19ada8SGreg Clayton ArchSpec fixed_platform_arch; 1873f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) 1883f19ada8SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); 1893f19ada8SGreg Clayton } 190b3a40ba8SGreg Clayton } 191b3a40ba8SGreg Clayton 19270512317SGreg Clayton if (!platform_arch.IsValid()) 19370512317SGreg Clayton platform_arch = arch; 19470512317SGreg Clayton 195cac9c5f9SGreg Clayton error = TargetList::CreateTarget (debugger, 196a0ca6601SGreg Clayton user_exe_path, 19770512317SGreg Clayton platform_arch, 198cac9c5f9SGreg Clayton get_dependent_files, 199cac9c5f9SGreg Clayton platform_sp, 200cac9c5f9SGreg Clayton target_sp); 201cac9c5f9SGreg Clayton return error; 202cac9c5f9SGreg Clayton } 203cac9c5f9SGreg Clayton 204cac9c5f9SGreg Clayton Error 205a0ca6601SGreg Clayton TargetList::CreateTarget (Debugger &debugger, 206a0ca6601SGreg Clayton const char *user_exe_path, 20770512317SGreg Clayton const ArchSpec& specified_arch, 20830fdc8d8SChris Lattner bool get_dependent_files, 209b3a40ba8SGreg Clayton PlatformSP &platform_sp, 210a0ca6601SGreg Clayton TargetSP &target_sp) 21130fdc8d8SChris Lattner { 21230fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 213a0ca6601SGreg Clayton "TargetList::CreateTarget (file = '%s', arch = '%s')", 214a0ca6601SGreg Clayton user_exe_path, 21570512317SGreg Clayton specified_arch.GetArchitectureName()); 2165aee162fSJim Ingham Error error; 2175aee162fSJim Ingham 21870512317SGreg Clayton ArchSpec arch(specified_arch); 21970512317SGreg Clayton 22070512317SGreg Clayton if (platform_sp) 22170512317SGreg Clayton { 22270512317SGreg Clayton if (arch.IsValid()) 22370512317SGreg Clayton { 2241e0c8840SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 22570512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 22670512317SGreg Clayton } 22770512317SGreg Clayton } 22870512317SGreg Clayton else if (arch.IsValid()) 22970512317SGreg Clayton { 23070512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 23170512317SGreg Clayton } 23270512317SGreg Clayton 23370512317SGreg Clayton if (!platform_sp) 23470512317SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 235ded470d3SGreg Clayton 2368ae50eb4SGreg Clayton if (!arch.IsValid()) 2378ae50eb4SGreg Clayton arch = specified_arch; 2388ae50eb4SGreg Clayton 239d26206b5SJason Molenda FileSpec file (user_exe_path, false); 240d26206b5SJason Molenda if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 241d26206b5SJason Molenda { 2429f822cd1SMichael Sartain // we want to expand the tilde but we don't want to resolve any symbolic links 2439f822cd1SMichael Sartain // so we can't use the FileSpec constructor's resolve flag 2449f822cd1SMichael Sartain char unglobbed_path[PATH_MAX]; 2459f822cd1SMichael Sartain unglobbed_path[0] = '\0'; 2469f822cd1SMichael Sartain 2479f822cd1SMichael Sartain size_t return_count = FileSpec::ResolveUsername(user_exe_path, unglobbed_path, sizeof(unglobbed_path)); 2489f822cd1SMichael Sartain 2499f822cd1SMichael Sartain if (return_count == 0 || return_count >= sizeof(unglobbed_path)) 2509f822cd1SMichael Sartain ::snprintf (unglobbed_path, sizeof(unglobbed_path), "%s", user_exe_path); 2519f822cd1SMichael Sartain 2529f822cd1SMichael Sartain file = FileSpec(unglobbed_path, false); 253d26206b5SJason Molenda } 2549f822cd1SMichael Sartain 25582d79295SGreg Clayton bool user_exe_path_is_bundle = false; 25682d79295SGreg Clayton char resolved_bundle_exe_path[PATH_MAX]; 25782d79295SGreg Clayton resolved_bundle_exe_path[0] = '\0'; 258e996fd30SGreg Clayton if (file) 2595aee162fSJim Ingham { 26082d79295SGreg Clayton if (file.GetFileType() == FileSpec::eFileTypeDirectory) 26182d79295SGreg Clayton user_exe_path_is_bundle = true; 26282d79295SGreg Clayton 263a0ca6601SGreg Clayton if (file.IsRelativeToCurrentWorkingDirectory()) 264a0ca6601SGreg Clayton { 265a0ca6601SGreg Clayton // Ignore paths that start with "./" and "../" 266a0ca6601SGreg Clayton if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 267a0ca6601SGreg Clayton (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 268a0ca6601SGreg Clayton { 269a0ca6601SGreg Clayton char cwd[PATH_MAX]; 270a0ca6601SGreg Clayton if (getcwd (cwd, sizeof(cwd))) 271a0ca6601SGreg Clayton { 272a0ca6601SGreg Clayton std::string cwd_user_exe_path (cwd); 273a0ca6601SGreg Clayton cwd_user_exe_path += '/'; 274a0ca6601SGreg Clayton cwd_user_exe_path += user_exe_path; 2759ff5aae5SGreg Clayton FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 2769ff5aae5SGreg Clayton if (cwd_file.Exists()) 2779ff5aae5SGreg Clayton file = cwd_file; 278a0ca6601SGreg Clayton } 279a0ca6601SGreg Clayton } 280a0ca6601SGreg Clayton } 281a0ca6601SGreg Clayton 28230fdc8d8SChris Lattner ModuleSP exe_module_sp; 283e996fd30SGreg Clayton if (platform_sp) 284c859e2d5SGreg Clayton { 285c859e2d5SGreg Clayton FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 28670512317SGreg Clayton error = platform_sp->ResolveExecutable (file, 28770512317SGreg Clayton arch, 288c859e2d5SGreg Clayton exe_module_sp, 289c859e2d5SGreg Clayton executable_search_paths.GetSize() ? &executable_search_paths : NULL); 290c859e2d5SGreg Clayton } 291428a9a58SCaroline Tice 292e996fd30SGreg Clayton if (error.Success() && exe_module_sp) 29330fdc8d8SChris Lattner { 2945aee162fSJim Ingham if (exe_module_sp->GetObjectFile() == NULL) 2955aee162fSJim Ingham { 296bc5cad6cSGreg Clayton if (arch.IsValid()) 297bc5cad6cSGreg Clayton { 298b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 299b5ad4ec7SGreg Clayton file.GetPath().c_str(), 30064195a2cSGreg Clayton arch.GetArchitectureName()); 301bc5cad6cSGreg Clayton } 302bc5cad6cSGreg Clayton else 303bc5cad6cSGreg Clayton { 304b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("unsupported file type \"%s\"", 305b5ad4ec7SGreg Clayton file.GetPath().c_str()); 306bc5cad6cSGreg Clayton } 3075aee162fSJim Ingham return error; 3085aee162fSJim Ingham } 30932e0a750SGreg Clayton target_sp.reset(new Target(debugger, arch, platform_sp)); 31030fdc8d8SChris Lattner target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 31182d79295SGreg Clayton if (user_exe_path_is_bundle) 31282d79295SGreg Clayton exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 3135aee162fSJim Ingham } 3145aee162fSJim Ingham } 315e996fd30SGreg Clayton else 316e996fd30SGreg Clayton { 317e996fd30SGreg Clayton // No file was specified, just create an empty target with any arch 318e996fd30SGreg Clayton // if a valid arch was specified 31932e0a750SGreg Clayton target_sp.reset(new Target(debugger, arch, platform_sp)); 320e996fd30SGreg Clayton } 3211559a46bSCaroline Tice 322e996fd30SGreg Clayton if (target_sp) 323e996fd30SGreg Clayton { 32482d79295SGreg Clayton // Set argv0 with what the user typed, unless the user specified a 32582d79295SGreg Clayton // directory. If the user specified a directory, then it is probably a 32682d79295SGreg Clayton // bundle that was resolved and we need to use the resolved bundle path 327a0ca6601SGreg Clayton if (user_exe_path) 328a0ca6601SGreg Clayton { 329a0ca6601SGreg Clayton // Use exactly what the user typed as the first argument when we exec or posix_spawn 33082d79295SGreg Clayton if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 33182d79295SGreg Clayton { 33282d79295SGreg Clayton target_sp->SetArg0 (resolved_bundle_exe_path); 33382d79295SGreg Clayton } 33482d79295SGreg Clayton else 33582d79295SGreg Clayton { 3369f822cd1SMichael Sartain // Use resolved path 3379f822cd1SMichael Sartain target_sp->SetArg0 (file.GetPath().c_str()); 338a0ca6601SGreg Clayton } 33982d79295SGreg Clayton } 340a0ca6601SGreg Clayton if (file.GetDirectory()) 341a0ca6601SGreg Clayton { 342a0ca6601SGreg Clayton FileSpec file_dir; 343a0ca6601SGreg Clayton file_dir.GetDirectory() = file.GetDirectory(); 344a0ca6601SGreg Clayton target_sp->GetExecutableSearchPaths ().Append (file_dir); 345a0ca6601SGreg Clayton } 34630fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 3472976d00aSJim Ingham m_selected_target_idx = m_target_list.size(); 34830fdc8d8SChris Lattner m_target_list.push_back(target_sp); 349a0ca6601SGreg Clayton 350a0ca6601SGreg Clayton 35130fdc8d8SChris Lattner } 35230fdc8d8SChris Lattner 35330fdc8d8SChris Lattner return error; 35430fdc8d8SChris Lattner } 35530fdc8d8SChris Lattner 35630fdc8d8SChris Lattner bool 35730fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp) 35830fdc8d8SChris Lattner { 35930fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 36030fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 36130fdc8d8SChris Lattner 36230fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 36330fdc8d8SChris Lattner { 36430fdc8d8SChris Lattner if (pos->get() == target_sp.get()) 36530fdc8d8SChris Lattner { 36630fdc8d8SChris Lattner m_target_list.erase(pos); 36730fdc8d8SChris Lattner return true; 36830fdc8d8SChris Lattner } 36930fdc8d8SChris Lattner } 37030fdc8d8SChris Lattner return false; 37130fdc8d8SChris Lattner } 37230fdc8d8SChris Lattner 37330fdc8d8SChris Lattner 37430fdc8d8SChris Lattner TargetSP 37530fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture 37630fdc8d8SChris Lattner ( 37730fdc8d8SChris Lattner const FileSpec &exe_file_spec, 37830fdc8d8SChris Lattner const ArchSpec *exe_arch_ptr 37930fdc8d8SChris Lattner ) const 38030fdc8d8SChris Lattner { 38130fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 38230fdc8d8SChris Lattner TargetSP target_sp; 383ddd7a2a6SSean Callanan bool full_match = (bool)exe_file_spec.GetDirectory(); 38430fdc8d8SChris Lattner 38530fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 38630fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 38730fdc8d8SChris Lattner { 388aa149cbdSGreg Clayton Module *exe_module = (*pos)->GetExecutableModulePointer(); 38930fdc8d8SChris Lattner 390aa149cbdSGreg Clayton if (exe_module) 39130fdc8d8SChris Lattner { 392aa149cbdSGreg Clayton if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 39330fdc8d8SChris Lattner { 39430fdc8d8SChris Lattner if (exe_arch_ptr) 39530fdc8d8SChris Lattner { 396bf4b7be6SSean Callanan if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 39730fdc8d8SChris Lattner continue; 39830fdc8d8SChris Lattner } 39930fdc8d8SChris Lattner target_sp = *pos; 40030fdc8d8SChris Lattner break; 40130fdc8d8SChris Lattner } 40230fdc8d8SChris Lattner } 40330fdc8d8SChris Lattner } 40430fdc8d8SChris Lattner return target_sp; 40530fdc8d8SChris Lattner } 40630fdc8d8SChris Lattner 40730fdc8d8SChris Lattner TargetSP 40830fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 40930fdc8d8SChris Lattner { 41030fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 41130fdc8d8SChris Lattner TargetSP target_sp; 41230fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 41330fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 41430fdc8d8SChris Lattner { 41530fdc8d8SChris Lattner Process* process = (*pos)->GetProcessSP().get(); 41630fdc8d8SChris Lattner if (process && process->GetID() == pid) 41730fdc8d8SChris Lattner { 41830fdc8d8SChris Lattner target_sp = *pos; 41930fdc8d8SChris Lattner break; 42030fdc8d8SChris Lattner } 42130fdc8d8SChris Lattner } 42230fdc8d8SChris Lattner return target_sp; 42330fdc8d8SChris Lattner } 42430fdc8d8SChris Lattner 42530fdc8d8SChris Lattner 42630fdc8d8SChris Lattner TargetSP 42730fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const 42830fdc8d8SChris Lattner { 42930fdc8d8SChris Lattner TargetSP target_sp; 43030fdc8d8SChris Lattner if (process) 43130fdc8d8SChris Lattner { 43230fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 43330fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 43430fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 43530fdc8d8SChris Lattner { 43630fdc8d8SChris Lattner if (process == (*pos)->GetProcessSP().get()) 43730fdc8d8SChris Lattner { 43830fdc8d8SChris Lattner target_sp = *pos; 43930fdc8d8SChris Lattner break; 44030fdc8d8SChris Lattner } 44130fdc8d8SChris Lattner } 44230fdc8d8SChris Lattner } 44330fdc8d8SChris Lattner return target_sp; 44430fdc8d8SChris Lattner } 44530fdc8d8SChris Lattner 44630fdc8d8SChris Lattner TargetSP 44730fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const 44830fdc8d8SChris Lattner { 44930fdc8d8SChris Lattner TargetSP target_sp; 45030fdc8d8SChris Lattner if (target) 45130fdc8d8SChris Lattner { 45230fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 45330fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 45430fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner if (target == (*pos).get()) 45730fdc8d8SChris Lattner { 45830fdc8d8SChris Lattner target_sp = *pos; 45930fdc8d8SChris Lattner break; 46030fdc8d8SChris Lattner } 46130fdc8d8SChris Lattner } 46230fdc8d8SChris Lattner } 46330fdc8d8SChris Lattner return target_sp; 46430fdc8d8SChris Lattner } 46530fdc8d8SChris Lattner 46630fdc8d8SChris Lattner uint32_t 46730fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid) 46830fdc8d8SChris Lattner { 46930fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 47030fdc8d8SChris Lattner 47130fdc8d8SChris Lattner if (pid != LLDB_INVALID_PROCESS_ID) 47230fdc8d8SChris Lattner { 47330fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 47430fdc8d8SChris Lattner if (target_sp.get()) 47530fdc8d8SChris Lattner { 47630fdc8d8SChris Lattner Process* process = target_sp->GetProcessSP().get(); 47730fdc8d8SChris Lattner if (process) 47830fdc8d8SChris Lattner { 479cfc0935eSJim Ingham process->SendAsyncInterrupt(); 48030fdc8d8SChris Lattner ++num_async_interrupts_sent; 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner } 48330fdc8d8SChris Lattner } 48430fdc8d8SChris Lattner else 48530fdc8d8SChris Lattner { 48630fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 48730fdc8d8SChris Lattner // list's async broadcaster... 48830fdc8d8SChris Lattner BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 48930fdc8d8SChris Lattner } 49030fdc8d8SChris Lattner 49130fdc8d8SChris Lattner return num_async_interrupts_sent; 49230fdc8d8SChris Lattner } 49330fdc8d8SChris Lattner 49430fdc8d8SChris Lattner uint32_t 49530fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 49630fdc8d8SChris Lattner { 49730fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 49830fdc8d8SChris Lattner Process *process = NULL; 49930fdc8d8SChris Lattner if (pid == LLDB_INVALID_PROCESS_ID) 50030fdc8d8SChris Lattner { 50130fdc8d8SChris Lattner // Signal all processes with signal 50230fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 50330fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 50430fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 50530fdc8d8SChris Lattner { 50630fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 50730fdc8d8SChris Lattner if (process) 50830fdc8d8SChris Lattner { 50930fdc8d8SChris Lattner if (process->IsAlive()) 51030fdc8d8SChris Lattner { 51130fdc8d8SChris Lattner ++num_signals_sent; 51230fdc8d8SChris Lattner process->Signal (signo); 51330fdc8d8SChris Lattner } 51430fdc8d8SChris Lattner } 51530fdc8d8SChris Lattner } 51630fdc8d8SChris Lattner } 51730fdc8d8SChris Lattner else 51830fdc8d8SChris Lattner { 51930fdc8d8SChris Lattner // Signal a specific process with signal 52030fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 52130fdc8d8SChris Lattner if (target_sp.get()) 52230fdc8d8SChris Lattner { 52330fdc8d8SChris Lattner process = target_sp->GetProcessSP().get(); 52430fdc8d8SChris Lattner if (process) 52530fdc8d8SChris Lattner { 52630fdc8d8SChris Lattner if (process->IsAlive()) 52730fdc8d8SChris Lattner { 52830fdc8d8SChris Lattner ++num_signals_sent; 52930fdc8d8SChris Lattner process->Signal (signo); 53030fdc8d8SChris Lattner } 53130fdc8d8SChris Lattner } 53230fdc8d8SChris Lattner } 53330fdc8d8SChris Lattner } 53430fdc8d8SChris Lattner return num_signals_sent; 53530fdc8d8SChris Lattner } 53630fdc8d8SChris Lattner 53730fdc8d8SChris Lattner int 53830fdc8d8SChris Lattner TargetList::GetNumTargets () const 53930fdc8d8SChris Lattner { 54030fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 54130fdc8d8SChris Lattner return m_target_list.size(); 54230fdc8d8SChris Lattner } 54330fdc8d8SChris Lattner 54430fdc8d8SChris Lattner lldb::TargetSP 54530fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const 54630fdc8d8SChris Lattner { 54730fdc8d8SChris Lattner TargetSP target_sp; 54830fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 54930fdc8d8SChris Lattner if (idx < m_target_list.size()) 55030fdc8d8SChris Lattner target_sp = m_target_list[idx]; 55130fdc8d8SChris Lattner return target_sp; 55230fdc8d8SChris Lattner } 55330fdc8d8SChris Lattner 55430fdc8d8SChris Lattner uint32_t 5558499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 5568499e1a4SJim Ingham { 5578499e1a4SJim Ingham Mutex::Locker locker (m_target_list_mutex); 5588499e1a4SJim Ingham size_t num_targets = m_target_list.size(); 5598499e1a4SJim Ingham for (size_t idx = 0; idx < num_targets; idx++) 5608499e1a4SJim Ingham { 5618499e1a4SJim Ingham if (target_sp == m_target_list[idx]) 5628499e1a4SJim Ingham return idx; 5638499e1a4SJim Ingham } 5648499e1a4SJim Ingham return UINT32_MAX; 5658499e1a4SJim Ingham } 5668499e1a4SJim Ingham 5678499e1a4SJim Ingham uint32_t 5682976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target) 56930fdc8d8SChris Lattner { 57030fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 57130fdc8d8SChris Lattner collection::const_iterator pos, 57230fdc8d8SChris Lattner begin = m_target_list.begin(), 57330fdc8d8SChris Lattner end = m_target_list.end(); 57430fdc8d8SChris Lattner for (pos = begin; pos != end; ++pos) 57530fdc8d8SChris Lattner { 57630fdc8d8SChris Lattner if (pos->get() == target) 57730fdc8d8SChris Lattner { 5782976d00aSJim Ingham m_selected_target_idx = std::distance (begin, pos); 5792976d00aSJim Ingham return m_selected_target_idx; 58030fdc8d8SChris Lattner } 58130fdc8d8SChris Lattner } 5822976d00aSJim Ingham m_selected_target_idx = 0; 5832976d00aSJim Ingham return m_selected_target_idx; 58430fdc8d8SChris Lattner } 58530fdc8d8SChris Lattner 58630fdc8d8SChris Lattner lldb::TargetSP 5872976d00aSJim Ingham TargetList::GetSelectedTarget () 58830fdc8d8SChris Lattner { 58930fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 5902976d00aSJim Ingham if (m_selected_target_idx >= m_target_list.size()) 5912976d00aSJim Ingham m_selected_target_idx = 0; 5922976d00aSJim Ingham return GetTargetAtIndex (m_selected_target_idx); 59330fdc8d8SChris Lattner } 594