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 88f4d6de6aSGreg Clayton 89f4d6de6aSGreg Clayton if (user_exe_path && user_exe_path[0]) 90f4d6de6aSGreg Clayton { 91f4d6de6aSGreg Clayton ModuleSpecList module_specs; 92f4d6de6aSGreg Clayton ModuleSpec module_spec; 93f4d6de6aSGreg Clayton module_spec.GetFileSpec().SetFile(user_exe_path, true); 94f4d6de6aSGreg Clayton lldb::offset_t file_offset = 0; 952540a8a7SGreg Clayton lldb::offset_t file_size = 0; 962540a8a7SGreg Clayton const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); 97f4d6de6aSGreg Clayton if (num_specs > 0) 98f4d6de6aSGreg Clayton { 99f4d6de6aSGreg Clayton ModuleSpec matching_module_spec; 100f4d6de6aSGreg Clayton 101f4d6de6aSGreg Clayton if (num_specs == 1) 102f4d6de6aSGreg Clayton { 103f4d6de6aSGreg Clayton if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 104f4d6de6aSGreg Clayton { 105f4d6de6aSGreg Clayton if (platform_arch.IsValid()) 106f4d6de6aSGreg Clayton { 107f4d6de6aSGreg Clayton if (!platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) 108f4d6de6aSGreg Clayton { 109b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 110f4d6de6aSGreg Clayton platform_arch.GetTriple().str().c_str(), 111f4d6de6aSGreg Clayton matching_module_spec.GetArchitecture().GetTriple().str().c_str(), 112b5ad4ec7SGreg Clayton module_spec.GetFileSpec().GetPath().c_str()); 113f4d6de6aSGreg Clayton return error; 114f4d6de6aSGreg Clayton } 115f4d6de6aSGreg Clayton } 116f4d6de6aSGreg Clayton else 117f4d6de6aSGreg Clayton { 118f4d6de6aSGreg Clayton // Only one arch and none was specified 119f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 120f4d6de6aSGreg Clayton } 121f4d6de6aSGreg Clayton } 122f4d6de6aSGreg Clayton } 123f4d6de6aSGreg Clayton else 124f4d6de6aSGreg Clayton { 125f4d6de6aSGreg Clayton if (arch.IsValid()) 126f4d6de6aSGreg Clayton { 127f4d6de6aSGreg Clayton module_spec.GetArchitecture() = arch; 128f4d6de6aSGreg Clayton if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 129f4d6de6aSGreg Clayton { 130f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 131f4d6de6aSGreg Clayton } 132f4d6de6aSGreg Clayton } 133b23b1130SGreg Clayton // Don't just select the first architecture, we want to let the platform select 134b23b1130SGreg Clayton // the best architecture first when there are multiple archs. 135b23b1130SGreg Clayton // else 136b23b1130SGreg Clayton // { 137b23b1130SGreg Clayton // // No arch specified, select the first arch 138b23b1130SGreg Clayton // if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 139b23b1130SGreg Clayton // { 140b23b1130SGreg Clayton // platform_arch = matching_module_spec.GetArchitecture(); 141b23b1130SGreg Clayton // } 142b23b1130SGreg Clayton // } 143f4d6de6aSGreg Clayton } 144f4d6de6aSGreg Clayton } 145f4d6de6aSGreg Clayton } 146f4d6de6aSGreg Clayton 147b3a40ba8SGreg Clayton CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 148b3a40ba8SGreg Clayton if (platform_options) 149b3a40ba8SGreg Clayton { 150b3a40ba8SGreg Clayton if (platform_options->PlatformWasSpecified ()) 151b3a40ba8SGreg Clayton { 152b3a40ba8SGreg Clayton const bool select_platform = true; 153b3a40ba8SGreg Clayton platform_sp = platform_options->CreatePlatformWithOptions (interpreter, 154b3a40ba8SGreg Clayton arch, 155b3a40ba8SGreg Clayton select_platform, 15670512317SGreg Clayton error, 15770512317SGreg Clayton platform_arch); 158b3a40ba8SGreg Clayton if (!platform_sp) 159b3a40ba8SGreg Clayton return error; 160b3a40ba8SGreg Clayton } 161b3a40ba8SGreg Clayton } 162b3a40ba8SGreg Clayton 163b3a40ba8SGreg Clayton if (!platform_sp) 164b3a40ba8SGreg Clayton { 165b3a40ba8SGreg Clayton // Get the current platform and make sure it is compatible with the 166b3a40ba8SGreg Clayton // current architecture if we have a valid architecture. 167b3a40ba8SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform (); 168b3a40ba8SGreg Clayton 1691e0c8840SGreg Clayton if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 170b3a40ba8SGreg Clayton { 17170512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 172b3a40ba8SGreg Clayton } 173b3a40ba8SGreg Clayton } 174b3a40ba8SGreg Clayton 17570512317SGreg Clayton if (!platform_arch.IsValid()) 17670512317SGreg Clayton platform_arch = arch; 17770512317SGreg Clayton 178cac9c5f9SGreg Clayton error = TargetList::CreateTarget (debugger, 179a0ca6601SGreg Clayton user_exe_path, 18070512317SGreg Clayton platform_arch, 181cac9c5f9SGreg Clayton get_dependent_files, 182cac9c5f9SGreg Clayton platform_sp, 183cac9c5f9SGreg Clayton target_sp); 184cac9c5f9SGreg Clayton return error; 185cac9c5f9SGreg Clayton } 186cac9c5f9SGreg Clayton 187cac9c5f9SGreg Clayton Error 188a0ca6601SGreg Clayton TargetList::CreateTarget (Debugger &debugger, 189a0ca6601SGreg Clayton const char *user_exe_path, 19070512317SGreg Clayton const ArchSpec& specified_arch, 19130fdc8d8SChris Lattner bool get_dependent_files, 192b3a40ba8SGreg Clayton PlatformSP &platform_sp, 193a0ca6601SGreg Clayton TargetSP &target_sp) 19430fdc8d8SChris Lattner { 19530fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 196a0ca6601SGreg Clayton "TargetList::CreateTarget (file = '%s', arch = '%s')", 197a0ca6601SGreg Clayton user_exe_path, 19870512317SGreg Clayton specified_arch.GetArchitectureName()); 1995aee162fSJim Ingham Error error; 2005aee162fSJim Ingham 20170512317SGreg Clayton ArchSpec arch(specified_arch); 20270512317SGreg Clayton 20370512317SGreg Clayton if (platform_sp) 20470512317SGreg Clayton { 20570512317SGreg Clayton if (arch.IsValid()) 20670512317SGreg Clayton { 2071e0c8840SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 20870512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 20970512317SGreg Clayton } 21070512317SGreg Clayton } 21170512317SGreg Clayton else if (arch.IsValid()) 21270512317SGreg Clayton { 21370512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 21470512317SGreg Clayton } 21570512317SGreg Clayton 21670512317SGreg Clayton if (!platform_sp) 21770512317SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 218ded470d3SGreg Clayton 2198ae50eb4SGreg Clayton if (!arch.IsValid()) 2208ae50eb4SGreg Clayton arch = specified_arch; 2218ae50eb4SGreg Clayton 222d26206b5SJason Molenda FileSpec file (user_exe_path, false); 223d26206b5SJason Molenda if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 224d26206b5SJason Molenda { 2259f822cd1SMichael Sartain // we want to expand the tilde but we don't want to resolve any symbolic links 2269f822cd1SMichael Sartain // so we can't use the FileSpec constructor's resolve flag 2279f822cd1SMichael Sartain char unglobbed_path[PATH_MAX]; 2289f822cd1SMichael Sartain unglobbed_path[0] = '\0'; 2299f822cd1SMichael Sartain 2309f822cd1SMichael Sartain size_t return_count = FileSpec::ResolveUsername(user_exe_path, unglobbed_path, sizeof(unglobbed_path)); 2319f822cd1SMichael Sartain 2329f822cd1SMichael Sartain if (return_count == 0 || return_count >= sizeof(unglobbed_path)) 2339f822cd1SMichael Sartain ::snprintf (unglobbed_path, sizeof(unglobbed_path), "%s", user_exe_path); 2349f822cd1SMichael Sartain 2359f822cd1SMichael Sartain file = FileSpec(unglobbed_path, false); 236d26206b5SJason Molenda } 2379f822cd1SMichael Sartain 23882d79295SGreg Clayton bool user_exe_path_is_bundle = false; 23982d79295SGreg Clayton char resolved_bundle_exe_path[PATH_MAX]; 24082d79295SGreg Clayton resolved_bundle_exe_path[0] = '\0'; 241e996fd30SGreg Clayton if (file) 2425aee162fSJim Ingham { 24382d79295SGreg Clayton if (file.GetFileType() == FileSpec::eFileTypeDirectory) 24482d79295SGreg Clayton user_exe_path_is_bundle = true; 24582d79295SGreg Clayton 246a0ca6601SGreg Clayton if (file.IsRelativeToCurrentWorkingDirectory()) 247a0ca6601SGreg Clayton { 248a0ca6601SGreg Clayton // Ignore paths that start with "./" and "../" 249a0ca6601SGreg Clayton if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 250a0ca6601SGreg Clayton (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 251a0ca6601SGreg Clayton { 252a0ca6601SGreg Clayton char cwd[PATH_MAX]; 253a0ca6601SGreg Clayton if (getcwd (cwd, sizeof(cwd))) 254a0ca6601SGreg Clayton { 255a0ca6601SGreg Clayton std::string cwd_user_exe_path (cwd); 256a0ca6601SGreg Clayton cwd_user_exe_path += '/'; 257a0ca6601SGreg Clayton cwd_user_exe_path += user_exe_path; 2589ff5aae5SGreg Clayton FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 2599ff5aae5SGreg Clayton if (cwd_file.Exists()) 2609ff5aae5SGreg Clayton file = cwd_file; 261a0ca6601SGreg Clayton } 262a0ca6601SGreg Clayton } 263a0ca6601SGreg Clayton } 264a0ca6601SGreg Clayton 26530fdc8d8SChris Lattner ModuleSP exe_module_sp; 266e996fd30SGreg Clayton if (platform_sp) 267c859e2d5SGreg Clayton { 268c859e2d5SGreg Clayton FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 26970512317SGreg Clayton error = platform_sp->ResolveExecutable (file, 27070512317SGreg Clayton arch, 271c859e2d5SGreg Clayton exe_module_sp, 272c859e2d5SGreg Clayton executable_search_paths.GetSize() ? &executable_search_paths : NULL); 273c859e2d5SGreg Clayton } 274428a9a58SCaroline Tice 275e996fd30SGreg Clayton if (error.Success() && exe_module_sp) 27630fdc8d8SChris Lattner { 2775aee162fSJim Ingham if (exe_module_sp->GetObjectFile() == NULL) 2785aee162fSJim Ingham { 279bc5cad6cSGreg Clayton if (arch.IsValid()) 280bc5cad6cSGreg Clayton { 281b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 282b5ad4ec7SGreg Clayton file.GetPath().c_str(), 28364195a2cSGreg Clayton arch.GetArchitectureName()); 284bc5cad6cSGreg Clayton } 285bc5cad6cSGreg Clayton else 286bc5cad6cSGreg Clayton { 287b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("unsupported file type \"%s\"", 288b5ad4ec7SGreg Clayton file.GetPath().c_str()); 289bc5cad6cSGreg Clayton } 2905aee162fSJim Ingham return error; 2915aee162fSJim Ingham } 29232e0a750SGreg Clayton target_sp.reset(new Target(debugger, arch, platform_sp)); 29330fdc8d8SChris Lattner target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 29482d79295SGreg Clayton if (user_exe_path_is_bundle) 29582d79295SGreg Clayton exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 2965aee162fSJim Ingham } 2975aee162fSJim Ingham } 298e996fd30SGreg Clayton else 299e996fd30SGreg Clayton { 300e996fd30SGreg Clayton // No file was specified, just create an empty target with any arch 301e996fd30SGreg Clayton // if a valid arch was specified 30232e0a750SGreg Clayton target_sp.reset(new Target(debugger, arch, platform_sp)); 303e996fd30SGreg Clayton } 3041559a46bSCaroline Tice 305e996fd30SGreg Clayton if (target_sp) 306e996fd30SGreg Clayton { 30782d79295SGreg Clayton // Set argv0 with what the user typed, unless the user specified a 30882d79295SGreg Clayton // directory. If the user specified a directory, then it is probably a 30982d79295SGreg Clayton // bundle that was resolved and we need to use the resolved bundle path 310a0ca6601SGreg Clayton if (user_exe_path) 311a0ca6601SGreg Clayton { 312a0ca6601SGreg Clayton // Use exactly what the user typed as the first argument when we exec or posix_spawn 31382d79295SGreg Clayton if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 31482d79295SGreg Clayton { 31582d79295SGreg Clayton target_sp->SetArg0 (resolved_bundle_exe_path); 31682d79295SGreg Clayton } 31782d79295SGreg Clayton else 31882d79295SGreg Clayton { 3199f822cd1SMichael Sartain // Use resolved path 3209f822cd1SMichael Sartain target_sp->SetArg0 (file.GetPath().c_str()); 321a0ca6601SGreg Clayton } 32282d79295SGreg Clayton } 323a0ca6601SGreg Clayton if (file.GetDirectory()) 324a0ca6601SGreg Clayton { 325a0ca6601SGreg Clayton FileSpec file_dir; 326a0ca6601SGreg Clayton file_dir.GetDirectory() = file.GetDirectory(); 327a0ca6601SGreg Clayton target_sp->GetExecutableSearchPaths ().Append (file_dir); 328a0ca6601SGreg Clayton } 32930fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 3302976d00aSJim Ingham m_selected_target_idx = m_target_list.size(); 33130fdc8d8SChris Lattner m_target_list.push_back(target_sp); 332a0ca6601SGreg Clayton 333a0ca6601SGreg Clayton 33430fdc8d8SChris Lattner } 33530fdc8d8SChris Lattner 33630fdc8d8SChris Lattner return error; 33730fdc8d8SChris Lattner } 33830fdc8d8SChris Lattner 33930fdc8d8SChris Lattner bool 34030fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp) 34130fdc8d8SChris Lattner { 34230fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 34330fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 34430fdc8d8SChris Lattner 34530fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 34630fdc8d8SChris Lattner { 34730fdc8d8SChris Lattner if (pos->get() == target_sp.get()) 34830fdc8d8SChris Lattner { 34930fdc8d8SChris Lattner m_target_list.erase(pos); 35030fdc8d8SChris Lattner return true; 35130fdc8d8SChris Lattner } 35230fdc8d8SChris Lattner } 35330fdc8d8SChris Lattner return false; 35430fdc8d8SChris Lattner } 35530fdc8d8SChris Lattner 35630fdc8d8SChris Lattner 35730fdc8d8SChris Lattner TargetSP 35830fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture 35930fdc8d8SChris Lattner ( 36030fdc8d8SChris Lattner const FileSpec &exe_file_spec, 36130fdc8d8SChris Lattner const ArchSpec *exe_arch_ptr 36230fdc8d8SChris Lattner ) const 36330fdc8d8SChris Lattner { 36430fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 36530fdc8d8SChris Lattner TargetSP target_sp; 366*ddd7a2a6SSean Callanan bool full_match = (bool)exe_file_spec.GetDirectory(); 36730fdc8d8SChris Lattner 36830fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 36930fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 37030fdc8d8SChris Lattner { 371aa149cbdSGreg Clayton Module *exe_module = (*pos)->GetExecutableModulePointer(); 37230fdc8d8SChris Lattner 373aa149cbdSGreg Clayton if (exe_module) 37430fdc8d8SChris Lattner { 375aa149cbdSGreg Clayton if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 37630fdc8d8SChris Lattner { 37730fdc8d8SChris Lattner if (exe_arch_ptr) 37830fdc8d8SChris Lattner { 379bf4b7be6SSean Callanan if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 38030fdc8d8SChris Lattner continue; 38130fdc8d8SChris Lattner } 38230fdc8d8SChris Lattner target_sp = *pos; 38330fdc8d8SChris Lattner break; 38430fdc8d8SChris Lattner } 38530fdc8d8SChris Lattner } 38630fdc8d8SChris Lattner } 38730fdc8d8SChris Lattner return target_sp; 38830fdc8d8SChris Lattner } 38930fdc8d8SChris Lattner 39030fdc8d8SChris Lattner TargetSP 39130fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 39230fdc8d8SChris Lattner { 39330fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 39430fdc8d8SChris Lattner TargetSP target_sp; 39530fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 39630fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 39730fdc8d8SChris Lattner { 39830fdc8d8SChris Lattner Process* process = (*pos)->GetProcessSP().get(); 39930fdc8d8SChris Lattner if (process && process->GetID() == pid) 40030fdc8d8SChris Lattner { 40130fdc8d8SChris Lattner target_sp = *pos; 40230fdc8d8SChris Lattner break; 40330fdc8d8SChris Lattner } 40430fdc8d8SChris Lattner } 40530fdc8d8SChris Lattner return target_sp; 40630fdc8d8SChris Lattner } 40730fdc8d8SChris Lattner 40830fdc8d8SChris Lattner 40930fdc8d8SChris Lattner TargetSP 41030fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const 41130fdc8d8SChris Lattner { 41230fdc8d8SChris Lattner TargetSP target_sp; 41330fdc8d8SChris Lattner if (process) 41430fdc8d8SChris Lattner { 41530fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 41630fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 41730fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 41830fdc8d8SChris Lattner { 41930fdc8d8SChris Lattner if (process == (*pos)->GetProcessSP().get()) 42030fdc8d8SChris Lattner { 42130fdc8d8SChris Lattner target_sp = *pos; 42230fdc8d8SChris Lattner break; 42330fdc8d8SChris Lattner } 42430fdc8d8SChris Lattner } 42530fdc8d8SChris Lattner } 42630fdc8d8SChris Lattner return target_sp; 42730fdc8d8SChris Lattner } 42830fdc8d8SChris Lattner 42930fdc8d8SChris Lattner TargetSP 43030fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const 43130fdc8d8SChris Lattner { 43230fdc8d8SChris Lattner TargetSP target_sp; 43330fdc8d8SChris Lattner if (target) 43430fdc8d8SChris Lattner { 43530fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 43630fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 43730fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 43830fdc8d8SChris Lattner { 43930fdc8d8SChris Lattner if (target == (*pos).get()) 44030fdc8d8SChris Lattner { 44130fdc8d8SChris Lattner target_sp = *pos; 44230fdc8d8SChris Lattner break; 44330fdc8d8SChris Lattner } 44430fdc8d8SChris Lattner } 44530fdc8d8SChris Lattner } 44630fdc8d8SChris Lattner return target_sp; 44730fdc8d8SChris Lattner } 44830fdc8d8SChris Lattner 44930fdc8d8SChris Lattner uint32_t 45030fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid) 45130fdc8d8SChris Lattner { 45230fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 45330fdc8d8SChris Lattner 45430fdc8d8SChris Lattner if (pid != LLDB_INVALID_PROCESS_ID) 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 45730fdc8d8SChris Lattner if (target_sp.get()) 45830fdc8d8SChris Lattner { 45930fdc8d8SChris Lattner Process* process = target_sp->GetProcessSP().get(); 46030fdc8d8SChris Lattner if (process) 46130fdc8d8SChris Lattner { 462cfc0935eSJim Ingham process->SendAsyncInterrupt(); 46330fdc8d8SChris Lattner ++num_async_interrupts_sent; 46430fdc8d8SChris Lattner } 46530fdc8d8SChris Lattner } 46630fdc8d8SChris Lattner } 46730fdc8d8SChris Lattner else 46830fdc8d8SChris Lattner { 46930fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 47030fdc8d8SChris Lattner // list's async broadcaster... 47130fdc8d8SChris Lattner BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 47230fdc8d8SChris Lattner } 47330fdc8d8SChris Lattner 47430fdc8d8SChris Lattner return num_async_interrupts_sent; 47530fdc8d8SChris Lattner } 47630fdc8d8SChris Lattner 47730fdc8d8SChris Lattner uint32_t 47830fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 47930fdc8d8SChris Lattner { 48030fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 48130fdc8d8SChris Lattner Process *process = NULL; 48230fdc8d8SChris Lattner if (pid == LLDB_INVALID_PROCESS_ID) 48330fdc8d8SChris Lattner { 48430fdc8d8SChris Lattner // Signal all processes with signal 48530fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 48630fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 48730fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 48830fdc8d8SChris Lattner { 48930fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 49030fdc8d8SChris Lattner if (process) 49130fdc8d8SChris Lattner { 49230fdc8d8SChris Lattner if (process->IsAlive()) 49330fdc8d8SChris Lattner { 49430fdc8d8SChris Lattner ++num_signals_sent; 49530fdc8d8SChris Lattner process->Signal (signo); 49630fdc8d8SChris Lattner } 49730fdc8d8SChris Lattner } 49830fdc8d8SChris Lattner } 49930fdc8d8SChris Lattner } 50030fdc8d8SChris Lattner else 50130fdc8d8SChris Lattner { 50230fdc8d8SChris Lattner // Signal a specific process with signal 50330fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 50430fdc8d8SChris Lattner if (target_sp.get()) 50530fdc8d8SChris Lattner { 50630fdc8d8SChris Lattner process = target_sp->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 return num_signals_sent; 51830fdc8d8SChris Lattner } 51930fdc8d8SChris Lattner 52030fdc8d8SChris Lattner int 52130fdc8d8SChris Lattner TargetList::GetNumTargets () const 52230fdc8d8SChris Lattner { 52330fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 52430fdc8d8SChris Lattner return m_target_list.size(); 52530fdc8d8SChris Lattner } 52630fdc8d8SChris Lattner 52730fdc8d8SChris Lattner lldb::TargetSP 52830fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const 52930fdc8d8SChris Lattner { 53030fdc8d8SChris Lattner TargetSP target_sp; 53130fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 53230fdc8d8SChris Lattner if (idx < m_target_list.size()) 53330fdc8d8SChris Lattner target_sp = m_target_list[idx]; 53430fdc8d8SChris Lattner return target_sp; 53530fdc8d8SChris Lattner } 53630fdc8d8SChris Lattner 53730fdc8d8SChris Lattner uint32_t 5388499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 5398499e1a4SJim Ingham { 5408499e1a4SJim Ingham Mutex::Locker locker (m_target_list_mutex); 5418499e1a4SJim Ingham size_t num_targets = m_target_list.size(); 5428499e1a4SJim Ingham for (size_t idx = 0; idx < num_targets; idx++) 5438499e1a4SJim Ingham { 5448499e1a4SJim Ingham if (target_sp == m_target_list[idx]) 5458499e1a4SJim Ingham return idx; 5468499e1a4SJim Ingham } 5478499e1a4SJim Ingham return UINT32_MAX; 5488499e1a4SJim Ingham } 5498499e1a4SJim Ingham 5508499e1a4SJim Ingham uint32_t 5512976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target) 55230fdc8d8SChris Lattner { 55330fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 55430fdc8d8SChris Lattner collection::const_iterator pos, 55530fdc8d8SChris Lattner begin = m_target_list.begin(), 55630fdc8d8SChris Lattner end = m_target_list.end(); 55730fdc8d8SChris Lattner for (pos = begin; pos != end; ++pos) 55830fdc8d8SChris Lattner { 55930fdc8d8SChris Lattner if (pos->get() == target) 56030fdc8d8SChris Lattner { 5612976d00aSJim Ingham m_selected_target_idx = std::distance (begin, pos); 5622976d00aSJim Ingham return m_selected_target_idx; 56330fdc8d8SChris Lattner } 56430fdc8d8SChris Lattner } 5652976d00aSJim Ingham m_selected_target_idx = 0; 5662976d00aSJim Ingham return m_selected_target_idx; 56730fdc8d8SChris Lattner } 56830fdc8d8SChris Lattner 56930fdc8d8SChris Lattner lldb::TargetSP 5702976d00aSJim Ingham TargetList::GetSelectedTarget () 57130fdc8d8SChris Lattner { 57230fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 5732976d00aSJim Ingham if (m_selected_target_idx >= m_target_list.size()) 5742976d00aSJim Ingham m_selected_target_idx = 0; 5752976d00aSJim Ingham return GetTargetAtIndex (m_selected_target_idx); 57630fdc8d8SChris Lattner } 577