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 1030fdc8d8SChris Lattner // Project includes 11fb1a0a0dSZachary Turner #include "lldb/Target/TargetList.h" 1230fdc8d8SChris Lattner #include "lldb/Core/Broadcaster.h" 13ded470d3SGreg Clayton #include "lldb/Core/Debugger.h" 1430fdc8d8SChris Lattner #include "lldb/Core/Event.h" 151f746071SGreg Clayton #include "lldb/Core/Module.h" 16f4d6de6aSGreg Clayton #include "lldb/Core/ModuleSpec.h" 1730fdc8d8SChris Lattner #include "lldb/Core/State.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 1930fdc8d8SChris Lattner #include "lldb/Host/Host.h" 20893c932aSJim Ingham #include "lldb/Host/HostInfo.h" 21b3a40ba8SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 22cac9c5f9SGreg Clayton #include "lldb/Interpreter/OptionGroupPlatform.h" 23f4d6de6aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 24e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2530fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2630fdc8d8SChris Lattner 271d5855b1SPavel Labath // Other libraries and framework includes 281d5855b1SPavel Labath #include "llvm/ADT/SmallString.h" 291d5855b1SPavel Labath #include "llvm/Support/FileSystem.h" 301d5855b1SPavel Labath 3130fdc8d8SChris Lattner using namespace lldb; 3230fdc8d8SChris Lattner using namespace lldb_private; 3330fdc8d8SChris Lattner 34b9c1b51eSKate Stone ConstString &TargetList::GetStaticBroadcasterClass() { 354bddaeb5SJim Ingham static ConstString class_name("lldb.targetList"); 364bddaeb5SJim Ingham return class_name; 374bddaeb5SJim Ingham } 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner //---------------------------------------------------------------------- 4030fdc8d8SChris Lattner // TargetList constructor 4130fdc8d8SChris Lattner //---------------------------------------------------------------------- 4216ff8604SSaleem Abdulrasool TargetList::TargetList(Debugger &debugger) 43b9c1b51eSKate Stone : Broadcaster(debugger.GetBroadcasterManager(), 44b9c1b51eSKate Stone TargetList::GetStaticBroadcasterClass().AsCString()), 45b9c1b51eSKate Stone m_target_list(), m_target_list_mutex(), m_selected_target_idx(0) { 464bddaeb5SJim Ingham CheckInWithManager(); 4730fdc8d8SChris Lattner } 4830fdc8d8SChris Lattner 4930fdc8d8SChris Lattner //---------------------------------------------------------------------- 5030fdc8d8SChris Lattner // Destructor 5130fdc8d8SChris Lattner //---------------------------------------------------------------------- 52b9c1b51eSKate Stone TargetList::~TargetList() { 5316ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 5430fdc8d8SChris Lattner m_target_list.clear(); 5530fdc8d8SChris Lattner } 5630fdc8d8SChris Lattner 57a47464b2SZachary Turner Error TargetList::CreateTarget(Debugger &debugger, 58a47464b2SZachary Turner llvm::StringRef user_exe_path, 59a47464b2SZachary Turner llvm::StringRef triple_str, 60cac9c5f9SGreg Clayton bool get_dependent_files, 61cac9c5f9SGreg Clayton const OptionGroupPlatform *platform_options, 62b9c1b51eSKate Stone TargetSP &target_sp) { 63a47464b2SZachary Turner return CreateTargetInternal(debugger, user_exe_path, triple_str, 64b9c1b51eSKate Stone get_dependent_files, platform_options, target_sp, 65893c932aSJim Ingham false); 66893c932aSJim Ingham } 67893c932aSJim Ingham 68a47464b2SZachary Turner Error TargetList::CreateTarget(Debugger &debugger, 69a47464b2SZachary Turner llvm::StringRef user_exe_path, 70893c932aSJim Ingham const ArchSpec &specified_arch, 71893c932aSJim Ingham bool get_dependent_files, 72b9c1b51eSKate Stone PlatformSP &platform_sp, TargetSP &target_sp) { 73b9c1b51eSKate Stone return CreateTargetInternal(debugger, user_exe_path, specified_arch, 74b9c1b51eSKate Stone get_dependent_files, platform_sp, target_sp, 75893c932aSJim Ingham false); 76893c932aSJim Ingham } 77893c932aSJim Ingham 78b9c1b51eSKate Stone Error TargetList::CreateTargetInternal( 79a47464b2SZachary Turner Debugger &debugger, llvm::StringRef user_exe_path, 80a47464b2SZachary Turner llvm::StringRef triple_str, bool get_dependent_files, 81a47464b2SZachary Turner const OptionGroupPlatform *platform_options, TargetSP &target_sp, 82a47464b2SZachary Turner bool is_dummy_target) { 83cac9c5f9SGreg Clayton Error error; 84cac9c5f9SGreg Clayton PlatformSP platform_sp; 85cac9c5f9SGreg Clayton 86cdc21d4cSJohnny Chen // This is purposely left empty unless it is specified by triple_cstr. 87cdc21d4cSJohnny Chen // If not initialized via triple_cstr, then the currently selected platform 88cdc21d4cSJohnny Chen // will set the architecture correctly. 89a47464b2SZachary Turner const ArchSpec arch(triple_str); 90a47464b2SZachary Turner if (!triple_str.empty()) { 91b9c1b51eSKate Stone if (!arch.IsValid()) { 92a47464b2SZachary Turner error.SetErrorStringWithFormat("invalid triple '%s'", 93a47464b2SZachary Turner triple_str.str().c_str()); 94cac9c5f9SGreg Clayton return error; 95cac9c5f9SGreg Clayton } 96cac9c5f9SGreg Clayton } 97b3a40ba8SGreg Clayton 9870512317SGreg Clayton ArchSpec platform_arch(arch); 99f4d6de6aSGreg Clayton 1003f19ada8SGreg Clayton bool prefer_platform_arch = false; 101f4d6de6aSGreg Clayton 102b0cc53cfSGreg Clayton CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 1031b5a74eeSVince Harron 104b9c1b51eSKate Stone // let's see if there is already an existing plaform before we go creating 105b9c1b51eSKate Stone // another... 1061b5a74eeSVince Harron platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 1071b5a74eeSVince Harron 108b9c1b51eSKate Stone if (platform_options && platform_options->PlatformWasSpecified()) { 109ccd2a6d9SGreg Clayton // Create a new platform if it doesn't match the selected platform 110b9c1b51eSKate Stone if (!platform_options->PlatformMatches(platform_sp)) { 111b0cc53cfSGreg Clayton const bool select_platform = true; 112b9c1b51eSKate Stone platform_sp = platform_options->CreatePlatformWithOptions( 113b9c1b51eSKate Stone interpreter, arch, select_platform, error, platform_arch); 114b0cc53cfSGreg Clayton if (!platform_sp) 115b0cc53cfSGreg Clayton return error; 116b0cc53cfSGreg Clayton } 117ccd2a6d9SGreg Clayton } 118b0cc53cfSGreg Clayton 119a47464b2SZachary Turner if (!user_exe_path.empty()) { 120f4d6de6aSGreg Clayton ModuleSpecList module_specs; 121f4d6de6aSGreg Clayton ModuleSpec module_spec; 122f4d6de6aSGreg Clayton module_spec.GetFileSpec().SetFile(user_exe_path, true); 123c76fa8a3SGreg Clayton 124b9c1b51eSKate Stone // Resolve the executable in case we are given a path to a application 125b9c1b51eSKate Stone // bundle 126c76fa8a3SGreg Clayton // like a .app bundle on MacOSX 127c76fa8a3SGreg Clayton Host::ResolveExecutableInBundle(module_spec.GetFileSpec()); 128c76fa8a3SGreg Clayton 129f4d6de6aSGreg Clayton lldb::offset_t file_offset = 0; 1302540a8a7SGreg Clayton lldb::offset_t file_size = 0; 131b9c1b51eSKate Stone const size_t num_specs = ObjectFile::GetModuleSpecifications( 132b9c1b51eSKate Stone module_spec.GetFileSpec(), file_offset, file_size, module_specs); 133b9c1b51eSKate Stone if (num_specs > 0) { 134f4d6de6aSGreg Clayton ModuleSpec matching_module_spec; 135f4d6de6aSGreg Clayton 136b9c1b51eSKate Stone if (num_specs == 1) { 137b9c1b51eSKate Stone if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) { 138b9c1b51eSKate Stone if (platform_arch.IsValid()) { 139b9c1b51eSKate Stone if (platform_arch.IsCompatibleMatch( 140b9c1b51eSKate Stone matching_module_spec.GetArchitecture())) { 1413f19ada8SGreg Clayton // If the OS or vendor weren't specified, then adopt the module's 1423f19ada8SGreg Clayton // architecture so that the platform matching can be more accurate 143b9c1b51eSKate Stone if (!platform_arch.TripleOSWasSpecified() || 144b9c1b51eSKate Stone !platform_arch.TripleVendorWasSpecified()) { 1453f19ada8SGreg Clayton prefer_platform_arch = true; 1463f19ada8SGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 1473f19ada8SGreg Clayton } 148b9c1b51eSKate Stone } else { 1497df337f8STodd Fiala StreamString platform_arch_strm; 1507df337f8STodd Fiala StreamString module_arch_strm; 1517df337f8STodd Fiala 1527df337f8STodd Fiala platform_arch.DumpTriple(platform_arch_strm); 153b9c1b51eSKate Stone matching_module_spec.GetArchitecture().DumpTriple( 154b9c1b51eSKate Stone module_arch_strm); 155b9c1b51eSKate Stone error.SetErrorStringWithFormat( 156b9c1b51eSKate Stone "the specified architecture '%s' is not compatible with '%s' " 157b9c1b51eSKate Stone "in '%s'", 158c156427dSZachary Turner platform_arch_strm.GetData(), module_arch_strm.GetData(), 159b5ad4ec7SGreg Clayton module_spec.GetFileSpec().GetPath().c_str()); 160f4d6de6aSGreg Clayton return error; 161f4d6de6aSGreg Clayton } 162b9c1b51eSKate Stone } else { 163f4d6de6aSGreg Clayton // Only one arch and none was specified 1643f19ada8SGreg Clayton prefer_platform_arch = true; 165f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 166f4d6de6aSGreg Clayton } 167f4d6de6aSGreg Clayton } 168b9c1b51eSKate Stone } else { 169b9c1b51eSKate Stone if (arch.IsValid()) { 170f4d6de6aSGreg Clayton module_spec.GetArchitecture() = arch; 171b9c1b51eSKate Stone if (module_specs.FindMatchingModuleSpec(module_spec, 172b9c1b51eSKate Stone matching_module_spec)) { 1733f19ada8SGreg Clayton prefer_platform_arch = true; 174f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 175f4d6de6aSGreg Clayton } 176b9c1b51eSKate Stone } else { 177b0cc53cfSGreg Clayton // No architecture specified, check if there is only one platform for 178b0cc53cfSGreg Clayton // all of the architectures. 179b0cc53cfSGreg Clayton 180b0cc53cfSGreg Clayton typedef std::vector<PlatformSP> PlatformList; 181b0cc53cfSGreg Clayton PlatformList platforms; 182615eb7e6SGreg Clayton PlatformSP host_platform_sp = Platform::GetHostPlatform(); 183b9c1b51eSKate Stone for (size_t i = 0; i < num_specs; ++i) { 184b0cc53cfSGreg Clayton ModuleSpec module_spec; 185b9c1b51eSKate Stone if (module_specs.GetModuleSpecAtIndex(i, module_spec)) { 186b0cc53cfSGreg Clayton // See if there was a selected platform and check that first 187b0cc53cfSGreg Clayton // since the user may have specified it. 188b9c1b51eSKate Stone if (platform_sp) { 189b9c1b51eSKate Stone if (platform_sp->IsCompatibleArchitecture( 190b9c1b51eSKate Stone module_spec.GetArchitecture(), false, nullptr)) { 191b0cc53cfSGreg Clayton platforms.push_back(platform_sp); 192b0cc53cfSGreg Clayton continue; 193f4d6de6aSGreg Clayton } 194f4d6de6aSGreg Clayton } 195f4d6de6aSGreg Clayton 196b0cc53cfSGreg Clayton // Next check the host platform it if wasn't already checked above 197b9c1b51eSKate Stone if (host_platform_sp && 198b9c1b51eSKate Stone (!platform_sp || 199b9c1b51eSKate Stone host_platform_sp->GetName() != platform_sp->GetName())) { 200b9c1b51eSKate Stone if (host_platform_sp->IsCompatibleArchitecture( 201b9c1b51eSKate Stone module_spec.GetArchitecture(), false, nullptr)) { 202b0cc53cfSGreg Clayton platforms.push_back(host_platform_sp); 203b0cc53cfSGreg Clayton continue; 204b0cc53cfSGreg Clayton } 205b0cc53cfSGreg Clayton } 206b0cc53cfSGreg Clayton 207b9c1b51eSKate Stone // Just find a platform that matches the architecture in the 208b9c1b51eSKate Stone // executable file 209b9c1b51eSKate Stone PlatformSP fallback_platform_sp( 210b9c1b51eSKate Stone Platform::GetPlatformForArchitecture( 211b9c1b51eSKate Stone module_spec.GetArchitecture(), nullptr)); 212b9c1b51eSKate Stone if (fallback_platform_sp) { 213e92a74ceSJason Molenda platforms.push_back(fallback_platform_sp); 214e92a74ceSJason Molenda } 215b0cc53cfSGreg Clayton } 216b0cc53cfSGreg Clayton } 217b0cc53cfSGreg Clayton 218e65b2cf2SEugene Zelenko Platform *platform_ptr = nullptr; 2199d58c728SJason Molenda bool more_than_one_platforms = false; 220b9c1b51eSKate Stone for (const auto &the_platform_sp : platforms) { 221b9c1b51eSKate Stone if (platform_ptr) { 222b9c1b51eSKate Stone if (platform_ptr->GetName() != the_platform_sp->GetName()) { 2239d58c728SJason Molenda more_than_one_platforms = true; 224e65b2cf2SEugene Zelenko platform_ptr = nullptr; 225b0cc53cfSGreg Clayton break; 226b0cc53cfSGreg Clayton } 227b9c1b51eSKate Stone } else { 228b0cc53cfSGreg Clayton platform_ptr = the_platform_sp.get(); 229b0cc53cfSGreg Clayton } 230b0cc53cfSGreg Clayton } 231b0cc53cfSGreg Clayton 232b9c1b51eSKate Stone if (platform_ptr) { 233b9c1b51eSKate Stone // All platforms for all modules in the exectuable match, so we can 234b9c1b51eSKate Stone // select this platform 235b0cc53cfSGreg Clayton platform_sp = platforms.front(); 236b9c1b51eSKate Stone } else if (more_than_one_platforms == false) { 2379d58c728SJason Molenda // No platforms claim to support this file 238b9c1b51eSKate Stone error.SetErrorString("No matching platforms found for this file, " 239b9c1b51eSKate Stone "specify one with the --platform option"); 2409d58c728SJason Molenda return error; 241b9c1b51eSKate Stone } else { 242b9c1b51eSKate Stone // More than one platform claims to support this file, so the 243b9c1b51eSKate Stone // --platform option must be specified 244b0cc53cfSGreg Clayton StreamString error_strm; 245b0cc53cfSGreg Clayton std::set<Platform *> platform_set; 246b9c1b51eSKate Stone error_strm.Printf( 247b9c1b51eSKate Stone "more than one platform supports this executable ("); 248b9c1b51eSKate Stone for (const auto &the_platform_sp : platforms) { 249b9c1b51eSKate Stone if (platform_set.find(the_platform_sp.get()) == 250b9c1b51eSKate Stone platform_set.end()) { 251b0cc53cfSGreg Clayton if (!platform_set.empty()) 252b0cc53cfSGreg Clayton error_strm.PutCString(", "); 253b0cc53cfSGreg Clayton error_strm.PutCString(the_platform_sp->GetName().GetCString()); 254b0cc53cfSGreg Clayton platform_set.insert(the_platform_sp.get()); 255b0cc53cfSGreg Clayton } 256b0cc53cfSGreg Clayton } 257b9c1b51eSKate Stone error_strm.Printf( 258b9c1b51eSKate Stone "), use the --platform option to specify a platform"); 259c156427dSZachary Turner error.SetErrorString(error_strm.GetString()); 260b3a40ba8SGreg Clayton return error; 261b3a40ba8SGreg Clayton } 262b3a40ba8SGreg Clayton } 263b0cc53cfSGreg Clayton } 264b0cc53cfSGreg Clayton } 265b0cc53cfSGreg Clayton } 266b3a40ba8SGreg Clayton 267869e0c1cSTed Woodward // If we have a valid architecture, make sure the current platform is 268869e0c1cSTed Woodward // compatible with that architecture 269b9c1b51eSKate Stone if (!prefer_platform_arch && arch.IsValid()) { 270b9c1b51eSKate Stone if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) { 27170512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 2728ec55a53SRobert Flack if (!is_dummy_target && platform_sp) 27395bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 27495bbdf64SGreg Clayton } 275b9c1b51eSKate Stone } else if (platform_arch.IsValid()) { 276b9c1b51eSKate Stone // if "arch" isn't valid, yet "platform_arch" is, it means we have an 277b9c1b51eSKate Stone // executable file with 2783f19ada8SGreg Clayton // a single architecture which should be used 2793f19ada8SGreg Clayton ArchSpec fixed_platform_arch; 280b9c1b51eSKate Stone if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, 281b9c1b51eSKate Stone &fixed_platform_arch)) { 282b9c1b51eSKate Stone platform_sp = Platform::GetPlatformForArchitecture(platform_arch, 283b9c1b51eSKate Stone &fixed_platform_arch); 2848ec55a53SRobert Flack if (!is_dummy_target && platform_sp) 28595bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 28695bbdf64SGreg Clayton } 2873f19ada8SGreg Clayton } 288b3a40ba8SGreg Clayton 28970512317SGreg Clayton if (!platform_arch.IsValid()) 29070512317SGreg Clayton platform_arch = arch; 29170512317SGreg Clayton 292b9c1b51eSKate Stone error = TargetList::CreateTargetInternal( 293b9c1b51eSKate Stone debugger, user_exe_path, platform_arch, get_dependent_files, platform_sp, 294b9c1b51eSKate Stone target_sp, is_dummy_target); 295cac9c5f9SGreg Clayton return error; 296cac9c5f9SGreg Clayton } 297cac9c5f9SGreg Clayton 298b9c1b51eSKate Stone lldb::TargetSP TargetList::GetDummyTarget(lldb_private::Debugger &debugger) { 299893c932aSJim Ingham // FIXME: Maybe the dummy target should be per-Debugger 300b9c1b51eSKate Stone if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) { 301893c932aSJim Ingham ArchSpec arch(Target::GetDefaultArchitecture()); 302893c932aSJim Ingham if (!arch.IsValid()) 303893c932aSJim Ingham arch = HostInfo::GetArchitecture(); 304b9c1b51eSKate Stone Error err = CreateDummyTarget( 305b9c1b51eSKate Stone debugger, arch.GetTriple().getTriple().c_str(), m_dummy_target_sp); 306893c932aSJim Ingham } 307893c932aSJim Ingham 308893c932aSJim Ingham return m_dummy_target_sp; 309893c932aSJim Ingham } 310893c932aSJim Ingham 311b9c1b51eSKate Stone Error TargetList::CreateDummyTarget(Debugger &debugger, 312a47464b2SZachary Turner llvm::StringRef specified_arch_name, 313b9c1b51eSKate Stone lldb::TargetSP &target_sp) { 314893c932aSJim Ingham PlatformSP host_platform_sp(Platform::GetHostPlatform()); 315b9c1b51eSKate Stone return CreateTargetInternal( 316b9c1b51eSKate Stone debugger, (const char *)nullptr, specified_arch_name, false, 317b9c1b51eSKate Stone (const OptionGroupPlatform *)nullptr, target_sp, true); 318893c932aSJim Ingham } 319893c932aSJim Ingham 320b9c1b51eSKate Stone Error TargetList::CreateTargetInternal(Debugger &debugger, 321a47464b2SZachary Turner llvm::StringRef user_exe_path, 32270512317SGreg Clayton const ArchSpec &specified_arch, 32330fdc8d8SChris Lattner bool get_dependent_files, 324893c932aSJim Ingham lldb::PlatformSP &platform_sp, 325893c932aSJim Ingham lldb::TargetSP &target_sp, 326b9c1b51eSKate Stone bool is_dummy_target) { 327f343968fSZachary Turner Timer scoped_timer(LLVM_PRETTY_FUNCTION, 328a0ca6601SGreg Clayton "TargetList::CreateTarget (file = '%s', arch = '%s')", 32972f4997cSZachary Turner user_exe_path.str().c_str(), 33072f4997cSZachary Turner specified_arch.GetArchitectureName()); 3315aee162fSJim Ingham Error error; 3325aee162fSJim Ingham 33370512317SGreg Clayton ArchSpec arch(specified_arch); 33470512317SGreg Clayton 335b9c1b51eSKate Stone if (arch.IsValid()) { 336b9c1b51eSKate Stone if (!platform_sp || 337b9c1b51eSKate Stone !platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) 33870512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 33970512317SGreg Clayton } 34070512317SGreg Clayton 34170512317SGreg Clayton if (!platform_sp) 34270512317SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 343ded470d3SGreg Clayton 3448ae50eb4SGreg Clayton if (!arch.IsValid()) 3458ae50eb4SGreg Clayton arch = specified_arch; 3468ae50eb4SGreg Clayton 347d26206b5SJason Molenda FileSpec file(user_exe_path, false); 348a47464b2SZachary Turner if (!file.Exists() && user_exe_path.startswith("~")) { 349b9c1b51eSKate Stone // we want to expand the tilde but we don't want to resolve any symbolic 350b9c1b51eSKate Stone // links 3519f822cd1SMichael Sartain // so we can't use the FileSpec constructor's resolve flag 3523f559740SZachary Turner llvm::SmallString<64> unglobbed_path(user_exe_path); 3533f559740SZachary Turner FileSpec::ResolveUsername(unglobbed_path); 3549f822cd1SMichael Sartain 3553f559740SZachary Turner if (unglobbed_path.empty()) 3563f559740SZachary Turner file = FileSpec(user_exe_path, false); 3573f559740SZachary Turner else 3583f559740SZachary Turner file = FileSpec(unglobbed_path.c_str(), false); 359d26206b5SJason Molenda } 3609f822cd1SMichael Sartain 36182d79295SGreg Clayton bool user_exe_path_is_bundle = false; 36282d79295SGreg Clayton char resolved_bundle_exe_path[PATH_MAX]; 36382d79295SGreg Clayton resolved_bundle_exe_path[0] = '\0'; 364b9c1b51eSKate Stone if (file) { 365*7d86ee5aSZachary Turner if (llvm::sys::fs::is_directory(file.GetPath())) 36682d79295SGreg Clayton user_exe_path_is_bundle = true; 36782d79295SGreg Clayton 368a47464b2SZachary Turner if (file.IsRelative() && !user_exe_path.empty()) { 369a0ca6601SGreg Clayton // Ignore paths that start with "./" and "../" 370a47464b2SZachary Turner if (!user_exe_path.startswith("./") && !user_exe_path.startswith("../")) { 3711d5855b1SPavel Labath llvm::SmallString<64> cwd; 3721d5855b1SPavel Labath if (! llvm::sys::fs::current_path(cwd)) { 3731d5855b1SPavel Labath cwd += '/'; 3741d5855b1SPavel Labath cwd += user_exe_path; 3751d5855b1SPavel Labath FileSpec cwd_file(cwd, false); 3769ff5aae5SGreg Clayton if (cwd_file.Exists()) 3779ff5aae5SGreg Clayton file = cwd_file; 378a0ca6601SGreg Clayton } 379a0ca6601SGreg Clayton } 380a0ca6601SGreg Clayton } 381a0ca6601SGreg Clayton 38230fdc8d8SChris Lattner ModuleSP exe_module_sp; 383b9c1b51eSKate Stone if (platform_sp) { 384b9c1b51eSKate Stone FileSpecList executable_search_paths( 385b9c1b51eSKate Stone Target::GetDefaultExecutableSearchPaths()); 3868012cadbSGreg Clayton ModuleSpec module_spec(file, arch); 387b9c1b51eSKate Stone error = platform_sp->ResolveExecutable(module_spec, exe_module_sp, 388b9c1b51eSKate Stone executable_search_paths.GetSize() 389b9c1b51eSKate Stone ? &executable_search_paths 390b9c1b51eSKate Stone : nullptr); 391c859e2d5SGreg Clayton } 392428a9a58SCaroline Tice 393b9c1b51eSKate Stone if (error.Success() && exe_module_sp) { 394b9c1b51eSKate Stone if (exe_module_sp->GetObjectFile() == nullptr) { 395b9c1b51eSKate Stone if (arch.IsValid()) { 396b9c1b51eSKate Stone error.SetErrorStringWithFormat( 397b9c1b51eSKate Stone "\"%s\" doesn't contain architecture %s", file.GetPath().c_str(), 39864195a2cSGreg Clayton arch.GetArchitectureName()); 399b9c1b51eSKate Stone } else { 400b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("unsupported file type \"%s\"", 401b5ad4ec7SGreg Clayton file.GetPath().c_str()); 402bc5cad6cSGreg Clayton } 4035aee162fSJim Ingham return error; 4045aee162fSJim Ingham } 405893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 40630fdc8d8SChris Lattner target_sp->SetExecutableModule(exe_module_sp, get_dependent_files); 40782d79295SGreg Clayton if (user_exe_path_is_bundle) 408b9c1b51eSKate Stone exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, 409b9c1b51eSKate Stone sizeof(resolved_bundle_exe_path)); 4105aee162fSJim Ingham } 411b9c1b51eSKate Stone } else { 412e996fd30SGreg Clayton // No file was specified, just create an empty target with any arch 413e996fd30SGreg Clayton // if a valid arch was specified 414893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 415e996fd30SGreg Clayton } 4161559a46bSCaroline Tice 417b9c1b51eSKate Stone if (target_sp) { 41882d79295SGreg Clayton // Set argv0 with what the user typed, unless the user specified a 41982d79295SGreg Clayton // directory. If the user specified a directory, then it is probably a 42082d79295SGreg Clayton // bundle that was resolved and we need to use the resolved bundle path 421a47464b2SZachary Turner if (!user_exe_path.empty()) { 422b9c1b51eSKate Stone // Use exactly what the user typed as the first argument when we exec or 423b9c1b51eSKate Stone // posix_spawn 424b9c1b51eSKate Stone if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) { 42582d79295SGreg Clayton target_sp->SetArg0(resolved_bundle_exe_path); 426b9c1b51eSKate Stone } else { 4279f822cd1SMichael Sartain // Use resolved path 4289f822cd1SMichael Sartain target_sp->SetArg0(file.GetPath().c_str()); 429a0ca6601SGreg Clayton } 43082d79295SGreg Clayton } 431b9c1b51eSKate Stone if (file.GetDirectory()) { 432a0ca6601SGreg Clayton FileSpec file_dir; 433a0ca6601SGreg Clayton file_dir.GetDirectory() = file.GetDirectory(); 434a0ca6601SGreg Clayton target_sp->GetExecutableSearchPaths().Append(file_dir); 435a0ca6601SGreg Clayton } 436893c932aSJim Ingham 437893c932aSJim Ingham // Don't put the dummy target in the target list, it's held separately. 438b9c1b51eSKate Stone if (!is_dummy_target) { 43916ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 4402976d00aSJim Ingham m_selected_target_idx = m_target_list.size(); 44130fdc8d8SChris Lattner m_target_list.push_back(target_sp); 44233df7cd3SJim Ingham // Now prime this from the dummy target: 44333df7cd3SJim Ingham target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); 444b9c1b51eSKate Stone } else { 445893c932aSJim Ingham m_dummy_target_sp = target_sp; 446893c932aSJim Ingham } 44730fdc8d8SChris Lattner } 44830fdc8d8SChris Lattner 44930fdc8d8SChris Lattner return error; 45030fdc8d8SChris Lattner } 45130fdc8d8SChris Lattner 452b9c1b51eSKate Stone bool TargetList::DeleteTarget(TargetSP &target_sp) { 45316ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 45430fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 45530fdc8d8SChris Lattner 456b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 457b9c1b51eSKate Stone if (pos->get() == target_sp.get()) { 45830fdc8d8SChris Lattner m_target_list.erase(pos); 45930fdc8d8SChris Lattner return true; 46030fdc8d8SChris Lattner } 46130fdc8d8SChris Lattner } 46230fdc8d8SChris Lattner return false; 46330fdc8d8SChris Lattner } 46430fdc8d8SChris Lattner 465b9c1b51eSKate Stone TargetSP TargetList::FindTargetWithExecutableAndArchitecture( 466b9c1b51eSKate Stone const FileSpec &exe_file_spec, const ArchSpec *exe_arch_ptr) const { 46716ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 46830fdc8d8SChris Lattner TargetSP target_sp; 469ddd7a2a6SSean Callanan bool full_match = (bool)exe_file_spec.GetDirectory(); 47030fdc8d8SChris Lattner 47130fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 472b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 473aa149cbdSGreg Clayton Module *exe_module = (*pos)->GetExecutableModulePointer(); 47430fdc8d8SChris Lattner 475b9c1b51eSKate Stone if (exe_module) { 476b9c1b51eSKate Stone if (FileSpec::Equal(exe_file_spec, exe_module->GetFileSpec(), 477b9c1b51eSKate Stone full_match)) { 478b9c1b51eSKate Stone if (exe_arch_ptr) { 479bf4b7be6SSean Callanan if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 48030fdc8d8SChris Lattner continue; 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner target_sp = *pos; 48330fdc8d8SChris Lattner break; 48430fdc8d8SChris Lattner } 48530fdc8d8SChris Lattner } 48630fdc8d8SChris Lattner } 48730fdc8d8SChris Lattner return target_sp; 48830fdc8d8SChris Lattner } 48930fdc8d8SChris Lattner 490b9c1b51eSKate Stone TargetSP TargetList::FindTargetWithProcessID(lldb::pid_t pid) const { 49116ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 49230fdc8d8SChris Lattner TargetSP target_sp; 49330fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 494b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 49530fdc8d8SChris Lattner Process *process = (*pos)->GetProcessSP().get(); 496b9c1b51eSKate Stone if (process && process->GetID() == pid) { 49730fdc8d8SChris Lattner target_sp = *pos; 49830fdc8d8SChris Lattner break; 49930fdc8d8SChris Lattner } 50030fdc8d8SChris Lattner } 50130fdc8d8SChris Lattner return target_sp; 50230fdc8d8SChris Lattner } 50330fdc8d8SChris Lattner 504b9c1b51eSKate Stone TargetSP TargetList::FindTargetWithProcess(Process *process) const { 50530fdc8d8SChris Lattner TargetSP target_sp; 506b9c1b51eSKate Stone if (process) { 50716ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 50830fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 509b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 510b9c1b51eSKate Stone if (process == (*pos)->GetProcessSP().get()) { 51130fdc8d8SChris Lattner target_sp = *pos; 51230fdc8d8SChris Lattner break; 51330fdc8d8SChris Lattner } 51430fdc8d8SChris Lattner } 51530fdc8d8SChris Lattner } 51630fdc8d8SChris Lattner return target_sp; 51730fdc8d8SChris Lattner } 51830fdc8d8SChris Lattner 519b9c1b51eSKate Stone TargetSP TargetList::GetTargetSP(Target *target) const { 52030fdc8d8SChris Lattner TargetSP target_sp; 521b9c1b51eSKate Stone if (target) { 52216ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 52330fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 524b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 525b9c1b51eSKate Stone if (target == (*pos).get()) { 52630fdc8d8SChris Lattner target_sp = *pos; 52730fdc8d8SChris Lattner break; 52830fdc8d8SChris Lattner } 52930fdc8d8SChris Lattner } 53030fdc8d8SChris Lattner } 53130fdc8d8SChris Lattner return target_sp; 53230fdc8d8SChris Lattner } 53330fdc8d8SChris Lattner 534b9c1b51eSKate Stone uint32_t TargetList::SendAsyncInterrupt(lldb::pid_t pid) { 53530fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 53630fdc8d8SChris Lattner 537b9c1b51eSKate Stone if (pid != LLDB_INVALID_PROCESS_ID) { 53830fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID(pid)); 539b9c1b51eSKate Stone if (target_sp) { 54030fdc8d8SChris Lattner Process *process = target_sp->GetProcessSP().get(); 541b9c1b51eSKate Stone if (process) { 542cfc0935eSJim Ingham process->SendAsyncInterrupt(); 54330fdc8d8SChris Lattner ++num_async_interrupts_sent; 54430fdc8d8SChris Lattner } 54530fdc8d8SChris Lattner } 546b9c1b51eSKate Stone } else { 54730fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 54830fdc8d8SChris Lattner // list's async broadcaster... 549e65b2cf2SEugene Zelenko BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr); 55030fdc8d8SChris Lattner } 55130fdc8d8SChris Lattner 55230fdc8d8SChris Lattner return num_async_interrupts_sent; 55330fdc8d8SChris Lattner } 55430fdc8d8SChris Lattner 555b9c1b51eSKate Stone uint32_t TargetList::SignalIfRunning(lldb::pid_t pid, int signo) { 55630fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 557e65b2cf2SEugene Zelenko Process *process = nullptr; 558b9c1b51eSKate Stone if (pid == LLDB_INVALID_PROCESS_ID) { 55930fdc8d8SChris Lattner // Signal all processes with signal 56016ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 56130fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 562b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 56330fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 564b9c1b51eSKate Stone if (process) { 565b9c1b51eSKate Stone if (process->IsAlive()) { 56630fdc8d8SChris Lattner ++num_signals_sent; 56730fdc8d8SChris Lattner process->Signal(signo); 56830fdc8d8SChris Lattner } 56930fdc8d8SChris Lattner } 57030fdc8d8SChris Lattner } 571b9c1b51eSKate Stone } else { 57230fdc8d8SChris Lattner // Signal a specific process with signal 57330fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID(pid)); 574b9c1b51eSKate Stone if (target_sp) { 57530fdc8d8SChris Lattner process = target_sp->GetProcessSP().get(); 576b9c1b51eSKate Stone if (process) { 577b9c1b51eSKate Stone if (process->IsAlive()) { 57830fdc8d8SChris Lattner ++num_signals_sent; 57930fdc8d8SChris Lattner process->Signal(signo); 58030fdc8d8SChris Lattner } 58130fdc8d8SChris Lattner } 58230fdc8d8SChris Lattner } 58330fdc8d8SChris Lattner } 58430fdc8d8SChris Lattner return num_signals_sent; 58530fdc8d8SChris Lattner } 58630fdc8d8SChris Lattner 587b9c1b51eSKate Stone int TargetList::GetNumTargets() const { 58816ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 58930fdc8d8SChris Lattner return m_target_list.size(); 59030fdc8d8SChris Lattner } 59130fdc8d8SChris Lattner 592b9c1b51eSKate Stone lldb::TargetSP TargetList::GetTargetAtIndex(uint32_t idx) const { 59330fdc8d8SChris Lattner TargetSP target_sp; 59416ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 59530fdc8d8SChris Lattner if (idx < m_target_list.size()) 59630fdc8d8SChris Lattner target_sp = m_target_list[idx]; 59730fdc8d8SChris Lattner return target_sp; 59830fdc8d8SChris Lattner } 59930fdc8d8SChris Lattner 600b9c1b51eSKate Stone uint32_t TargetList::GetIndexOfTarget(lldb::TargetSP target_sp) const { 60116ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 6028499e1a4SJim Ingham size_t num_targets = m_target_list.size(); 603b9c1b51eSKate Stone for (size_t idx = 0; idx < num_targets; idx++) { 6048499e1a4SJim Ingham if (target_sp == m_target_list[idx]) 6058499e1a4SJim Ingham return idx; 6068499e1a4SJim Ingham } 6078499e1a4SJim Ingham return UINT32_MAX; 6088499e1a4SJim Ingham } 6098499e1a4SJim Ingham 610b9c1b51eSKate Stone uint32_t TargetList::SetSelectedTarget(Target *target) { 61116ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 612b9c1b51eSKate Stone collection::const_iterator pos, begin = m_target_list.begin(), 61330fdc8d8SChris Lattner end = m_target_list.end(); 614b9c1b51eSKate Stone for (pos = begin; pos != end; ++pos) { 615b9c1b51eSKate Stone if (pos->get() == target) { 6162976d00aSJim Ingham m_selected_target_idx = std::distance(begin, pos); 6172976d00aSJim Ingham return m_selected_target_idx; 61830fdc8d8SChris Lattner } 61930fdc8d8SChris Lattner } 6202976d00aSJim Ingham m_selected_target_idx = 0; 6212976d00aSJim Ingham return m_selected_target_idx; 62230fdc8d8SChris Lattner } 62330fdc8d8SChris Lattner 624b9c1b51eSKate Stone lldb::TargetSP TargetList::GetSelectedTarget() { 62516ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 6262976d00aSJim Ingham if (m_selected_target_idx >= m_target_list.size()) 6272976d00aSJim Ingham m_selected_target_idx = 0; 6282976d00aSJim Ingham return GetTargetAtIndex(m_selected_target_idx); 62930fdc8d8SChris Lattner } 630