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/Host/Host.h" 19893c932aSJim Ingham #include "lldb/Host/HostInfo.h" 20b3a40ba8SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 21cac9c5f9SGreg Clayton #include "lldb/Interpreter/OptionGroupPlatform.h" 22f4d6de6aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 23e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2430fdc8d8SChris Lattner #include "lldb/Target/Process.h" 258d48cd60SZachary Turner #include "lldb/Utility/TildeExpressionResolver.h" 2638d0632eSPavel Labath #include "lldb/Utility/Timer.h" 2730fdc8d8SChris Lattner 281d5855b1SPavel Labath // Other libraries and framework includes 291d5855b1SPavel Labath #include "llvm/ADT/SmallString.h" 301d5855b1SPavel Labath #include "llvm/Support/FileSystem.h" 311d5855b1SPavel Labath 3230fdc8d8SChris Lattner using namespace lldb; 3330fdc8d8SChris Lattner using namespace lldb_private; 3430fdc8d8SChris Lattner 35b9c1b51eSKate Stone ConstString &TargetList::GetStaticBroadcasterClass() { 364bddaeb5SJim Ingham static ConstString class_name("lldb.targetList"); 374bddaeb5SJim Ingham return class_name; 384bddaeb5SJim Ingham } 3930fdc8d8SChris Lattner 4030fdc8d8SChris Lattner //---------------------------------------------------------------------- 4130fdc8d8SChris Lattner // TargetList constructor 4230fdc8d8SChris Lattner //---------------------------------------------------------------------- 4316ff8604SSaleem Abdulrasool TargetList::TargetList(Debugger &debugger) 44b9c1b51eSKate Stone : Broadcaster(debugger.GetBroadcasterManager(), 45b9c1b51eSKate Stone TargetList::GetStaticBroadcasterClass().AsCString()), 46b9c1b51eSKate Stone m_target_list(), m_target_list_mutex(), m_selected_target_idx(0) { 474bddaeb5SJim Ingham CheckInWithManager(); 4830fdc8d8SChris Lattner } 4930fdc8d8SChris Lattner 5030fdc8d8SChris Lattner //---------------------------------------------------------------------- 5130fdc8d8SChris Lattner // Destructor 5230fdc8d8SChris Lattner //---------------------------------------------------------------------- 53b9c1b51eSKate Stone TargetList::~TargetList() { 5416ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 5530fdc8d8SChris Lattner m_target_list.clear(); 5630fdc8d8SChris Lattner } 5730fdc8d8SChris Lattner 5897206d57SZachary Turner Status TargetList::CreateTarget(Debugger &debugger, 59a47464b2SZachary Turner llvm::StringRef user_exe_path, 60a47464b2SZachary Turner llvm::StringRef triple_str, 61cac9c5f9SGreg Clayton bool get_dependent_files, 62cac9c5f9SGreg Clayton const OptionGroupPlatform *platform_options, 63b9c1b51eSKate Stone TargetSP &target_sp) { 64a47464b2SZachary Turner return CreateTargetInternal(debugger, user_exe_path, triple_str, 65b9c1b51eSKate Stone get_dependent_files, platform_options, target_sp, 66893c932aSJim Ingham false); 67893c932aSJim Ingham } 68893c932aSJim Ingham 6997206d57SZachary Turner Status TargetList::CreateTarget(Debugger &debugger, 70a47464b2SZachary Turner llvm::StringRef user_exe_path, 71893c932aSJim Ingham const ArchSpec &specified_arch, 72893c932aSJim Ingham bool get_dependent_files, 73b9c1b51eSKate Stone PlatformSP &platform_sp, TargetSP &target_sp) { 74b9c1b51eSKate Stone return CreateTargetInternal(debugger, user_exe_path, specified_arch, 75b9c1b51eSKate Stone get_dependent_files, platform_sp, target_sp, 76893c932aSJim Ingham false); 77893c932aSJim Ingham } 78893c932aSJim Ingham 7997206d57SZachary Turner Status TargetList::CreateTargetInternal( 80a47464b2SZachary Turner Debugger &debugger, llvm::StringRef user_exe_path, 81a47464b2SZachary Turner llvm::StringRef triple_str, bool get_dependent_files, 82a47464b2SZachary Turner const OptionGroupPlatform *platform_options, TargetSP &target_sp, 83a47464b2SZachary Turner bool is_dummy_target) { 8497206d57SZachary Turner Status error; 85cac9c5f9SGreg Clayton PlatformSP platform_sp; 86cac9c5f9SGreg Clayton 8705097246SAdrian Prantl // This is purposely left empty unless it is specified by triple_cstr. If not 8805097246SAdrian Prantl // initialized via triple_cstr, then the currently selected platform will set 8905097246SAdrian Prantl // the architecture correctly. 90a47464b2SZachary Turner const ArchSpec arch(triple_str); 91a47464b2SZachary Turner if (!triple_str.empty()) { 92b9c1b51eSKate Stone if (!arch.IsValid()) { 93a47464b2SZachary Turner error.SetErrorStringWithFormat("invalid triple '%s'", 94a47464b2SZachary Turner triple_str.str().c_str()); 95cac9c5f9SGreg Clayton return error; 96cac9c5f9SGreg Clayton } 97cac9c5f9SGreg Clayton } 98b3a40ba8SGreg Clayton 9970512317SGreg Clayton ArchSpec platform_arch(arch); 100f4d6de6aSGreg Clayton 1013f19ada8SGreg Clayton bool prefer_platform_arch = false; 102f4d6de6aSGreg Clayton 103b0cc53cfSGreg Clayton CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 1041b5a74eeSVince Harron 105*4ebdee0aSBruce Mitchener // let's see if there is already an existing platform before we go creating 106b9c1b51eSKate Stone // another... 1071b5a74eeSVince Harron platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 1081b5a74eeSVince Harron 109b9c1b51eSKate Stone if (platform_options && platform_options->PlatformWasSpecified()) { 110ccd2a6d9SGreg Clayton // Create a new platform if it doesn't match the selected platform 111b9c1b51eSKate Stone if (!platform_options->PlatformMatches(platform_sp)) { 112b0cc53cfSGreg Clayton const bool select_platform = true; 113b9c1b51eSKate Stone platform_sp = platform_options->CreatePlatformWithOptions( 114b9c1b51eSKate Stone interpreter, arch, select_platform, error, platform_arch); 115b0cc53cfSGreg Clayton if (!platform_sp) 116b0cc53cfSGreg Clayton return error; 117b0cc53cfSGreg Clayton } 118ccd2a6d9SGreg Clayton } 119b0cc53cfSGreg Clayton 120a47464b2SZachary Turner if (!user_exe_path.empty()) { 121f4d6de6aSGreg Clayton ModuleSpecList module_specs; 122f4d6de6aSGreg Clayton ModuleSpec module_spec; 123f4d6de6aSGreg Clayton module_spec.GetFileSpec().SetFile(user_exe_path, true); 124c76fa8a3SGreg Clayton 125b9c1b51eSKate Stone // Resolve the executable in case we are given a path to a application 12605097246SAdrian Prantl // bundle 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 14205097246SAdrian Prantl // architecture so that the platform matching can be more 14305097246SAdrian Prantl // accurate 144b9c1b51eSKate Stone if (!platform_arch.TripleOSWasSpecified() || 145b9c1b51eSKate Stone !platform_arch.TripleVendorWasSpecified()) { 1463f19ada8SGreg Clayton prefer_platform_arch = true; 1473f19ada8SGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 1483f19ada8SGreg Clayton } 149b9c1b51eSKate Stone } else { 1507df337f8STodd Fiala StreamString platform_arch_strm; 1517df337f8STodd Fiala StreamString module_arch_strm; 1527df337f8STodd Fiala 1537df337f8STodd Fiala platform_arch.DumpTriple(platform_arch_strm); 154b9c1b51eSKate Stone matching_module_spec.GetArchitecture().DumpTriple( 155b9c1b51eSKate Stone module_arch_strm); 156b9c1b51eSKate Stone error.SetErrorStringWithFormat( 157b9c1b51eSKate Stone "the specified architecture '%s' is not compatible with '%s' " 158b9c1b51eSKate Stone "in '%s'", 159c156427dSZachary Turner platform_arch_strm.GetData(), module_arch_strm.GetData(), 160b5ad4ec7SGreg Clayton module_spec.GetFileSpec().GetPath().c_str()); 161f4d6de6aSGreg Clayton return error; 162f4d6de6aSGreg Clayton } 163b9c1b51eSKate Stone } else { 164f4d6de6aSGreg Clayton // Only one arch and none was specified 1653f19ada8SGreg Clayton prefer_platform_arch = true; 166f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 167f4d6de6aSGreg Clayton } 168f4d6de6aSGreg Clayton } 169b9c1b51eSKate Stone } else { 170b9c1b51eSKate Stone if (arch.IsValid()) { 171f4d6de6aSGreg Clayton module_spec.GetArchitecture() = arch; 172b9c1b51eSKate Stone if (module_specs.FindMatchingModuleSpec(module_spec, 173b9c1b51eSKate Stone matching_module_spec)) { 1743f19ada8SGreg Clayton prefer_platform_arch = true; 175f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 176f4d6de6aSGreg Clayton } 177b9c1b51eSKate Stone } else { 178b0cc53cfSGreg Clayton // No architecture specified, check if there is only one platform for 179b0cc53cfSGreg Clayton // all of the architectures. 180b0cc53cfSGreg Clayton 181b0cc53cfSGreg Clayton typedef std::vector<PlatformSP> PlatformList; 182b0cc53cfSGreg Clayton PlatformList platforms; 183615eb7e6SGreg Clayton PlatformSP host_platform_sp = Platform::GetHostPlatform(); 184b9c1b51eSKate Stone for (size_t i = 0; i < num_specs; ++i) { 185b0cc53cfSGreg Clayton ModuleSpec module_spec; 186b9c1b51eSKate Stone if (module_specs.GetModuleSpecAtIndex(i, module_spec)) { 187b0cc53cfSGreg Clayton // See if there was a selected platform and check that first 188b0cc53cfSGreg Clayton // since the user may have specified it. 189b9c1b51eSKate Stone if (platform_sp) { 190b9c1b51eSKate Stone if (platform_sp->IsCompatibleArchitecture( 191b9c1b51eSKate Stone module_spec.GetArchitecture(), false, nullptr)) { 192b0cc53cfSGreg Clayton platforms.push_back(platform_sp); 193b0cc53cfSGreg Clayton continue; 194f4d6de6aSGreg Clayton } 195f4d6de6aSGreg Clayton } 196f4d6de6aSGreg Clayton 19705097246SAdrian Prantl // Next check the host platform it if wasn't already checked 19805097246SAdrian Prantl // above 199b9c1b51eSKate Stone if (host_platform_sp && 200b9c1b51eSKate Stone (!platform_sp || 201b9c1b51eSKate Stone host_platform_sp->GetName() != platform_sp->GetName())) { 202b9c1b51eSKate Stone if (host_platform_sp->IsCompatibleArchitecture( 203b9c1b51eSKate Stone module_spec.GetArchitecture(), false, nullptr)) { 204b0cc53cfSGreg Clayton platforms.push_back(host_platform_sp); 205b0cc53cfSGreg Clayton continue; 206b0cc53cfSGreg Clayton } 207b0cc53cfSGreg Clayton } 208b0cc53cfSGreg Clayton 209b9c1b51eSKate Stone // Just find a platform that matches the architecture in the 210b9c1b51eSKate Stone // executable file 211b9c1b51eSKate Stone PlatformSP fallback_platform_sp( 212b9c1b51eSKate Stone Platform::GetPlatformForArchitecture( 213b9c1b51eSKate Stone module_spec.GetArchitecture(), nullptr)); 214b9c1b51eSKate Stone if (fallback_platform_sp) { 215e92a74ceSJason Molenda platforms.push_back(fallback_platform_sp); 216e92a74ceSJason Molenda } 217b0cc53cfSGreg Clayton } 218b0cc53cfSGreg Clayton } 219b0cc53cfSGreg Clayton 220e65b2cf2SEugene Zelenko Platform *platform_ptr = nullptr; 2219d58c728SJason Molenda bool more_than_one_platforms = false; 222b9c1b51eSKate Stone for (const auto &the_platform_sp : platforms) { 223b9c1b51eSKate Stone if (platform_ptr) { 224b9c1b51eSKate Stone if (platform_ptr->GetName() != the_platform_sp->GetName()) { 2259d58c728SJason Molenda more_than_one_platforms = true; 226e65b2cf2SEugene Zelenko platform_ptr = nullptr; 227b0cc53cfSGreg Clayton break; 228b0cc53cfSGreg Clayton } 229b9c1b51eSKate Stone } else { 230b0cc53cfSGreg Clayton platform_ptr = the_platform_sp.get(); 231b0cc53cfSGreg Clayton } 232b0cc53cfSGreg Clayton } 233b0cc53cfSGreg Clayton 234b9c1b51eSKate Stone if (platform_ptr) { 235*4ebdee0aSBruce Mitchener // All platforms for all modules in the executable match, so we can 236b9c1b51eSKate Stone // select this platform 237b0cc53cfSGreg Clayton platform_sp = platforms.front(); 238b9c1b51eSKate Stone } else if (more_than_one_platforms == false) { 2399d58c728SJason Molenda // No platforms claim to support this file 240b9c1b51eSKate Stone error.SetErrorString("No matching platforms found for this file, " 241b9c1b51eSKate Stone "specify one with the --platform option"); 2429d58c728SJason Molenda return error; 243b9c1b51eSKate Stone } else { 244b9c1b51eSKate Stone // More than one platform claims to support this file, so the 245b9c1b51eSKate Stone // --platform option must be specified 246b0cc53cfSGreg Clayton StreamString error_strm; 247b0cc53cfSGreg Clayton std::set<Platform *> platform_set; 248b9c1b51eSKate Stone error_strm.Printf( 249b9c1b51eSKate Stone "more than one platform supports this executable ("); 250b9c1b51eSKate Stone for (const auto &the_platform_sp : platforms) { 251b9c1b51eSKate Stone if (platform_set.find(the_platform_sp.get()) == 252b9c1b51eSKate Stone platform_set.end()) { 253b0cc53cfSGreg Clayton if (!platform_set.empty()) 254b0cc53cfSGreg Clayton error_strm.PutCString(", "); 255b0cc53cfSGreg Clayton error_strm.PutCString(the_platform_sp->GetName().GetCString()); 256b0cc53cfSGreg Clayton platform_set.insert(the_platform_sp.get()); 257b0cc53cfSGreg Clayton } 258b0cc53cfSGreg Clayton } 259b9c1b51eSKate Stone error_strm.Printf( 260b9c1b51eSKate Stone "), use the --platform option to specify a platform"); 261c156427dSZachary Turner error.SetErrorString(error_strm.GetString()); 262b3a40ba8SGreg Clayton return error; 263b3a40ba8SGreg Clayton } 264b3a40ba8SGreg Clayton } 265b0cc53cfSGreg Clayton } 266b0cc53cfSGreg Clayton } 267b0cc53cfSGreg Clayton } 268b3a40ba8SGreg Clayton 269869e0c1cSTed Woodward // If we have a valid architecture, make sure the current platform is 270869e0c1cSTed Woodward // compatible with that architecture 271b9c1b51eSKate Stone if (!prefer_platform_arch && arch.IsValid()) { 272b9c1b51eSKate Stone if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) { 27370512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 2748ec55a53SRobert Flack if (!is_dummy_target && platform_sp) 27595bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 27695bbdf64SGreg Clayton } 277b9c1b51eSKate Stone } else if (platform_arch.IsValid()) { 278b9c1b51eSKate Stone // if "arch" isn't valid, yet "platform_arch" is, it means we have an 27905097246SAdrian Prantl // executable file with a single architecture which should be used 2803f19ada8SGreg Clayton ArchSpec fixed_platform_arch; 281b9c1b51eSKate Stone if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, 282b9c1b51eSKate Stone &fixed_platform_arch)) { 283b9c1b51eSKate Stone platform_sp = Platform::GetPlatformForArchitecture(platform_arch, 284b9c1b51eSKate Stone &fixed_platform_arch); 2858ec55a53SRobert Flack if (!is_dummy_target && platform_sp) 28695bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 28795bbdf64SGreg Clayton } 2883f19ada8SGreg Clayton } 289b3a40ba8SGreg Clayton 29070512317SGreg Clayton if (!platform_arch.IsValid()) 29170512317SGreg Clayton platform_arch = arch; 29270512317SGreg Clayton 293b9c1b51eSKate Stone error = TargetList::CreateTargetInternal( 294b9c1b51eSKate Stone debugger, user_exe_path, platform_arch, get_dependent_files, platform_sp, 295b9c1b51eSKate Stone target_sp, is_dummy_target); 296cac9c5f9SGreg Clayton return error; 297cac9c5f9SGreg Clayton } 298cac9c5f9SGreg Clayton 299b9c1b51eSKate Stone lldb::TargetSP TargetList::GetDummyTarget(lldb_private::Debugger &debugger) { 300893c932aSJim Ingham // FIXME: Maybe the dummy target should be per-Debugger 301b9c1b51eSKate Stone if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) { 302893c932aSJim Ingham ArchSpec arch(Target::GetDefaultArchitecture()); 303893c932aSJim Ingham if (!arch.IsValid()) 304893c932aSJim Ingham arch = HostInfo::GetArchitecture(); 30597206d57SZachary Turner Status err = CreateDummyTarget( 306b9c1b51eSKate Stone debugger, arch.GetTriple().getTriple().c_str(), m_dummy_target_sp); 307893c932aSJim Ingham } 308893c932aSJim Ingham 309893c932aSJim Ingham return m_dummy_target_sp; 310893c932aSJim Ingham } 311893c932aSJim Ingham 31297206d57SZachary Turner Status TargetList::CreateDummyTarget(Debugger &debugger, 313a47464b2SZachary Turner llvm::StringRef specified_arch_name, 314b9c1b51eSKate Stone lldb::TargetSP &target_sp) { 315893c932aSJim Ingham PlatformSP host_platform_sp(Platform::GetHostPlatform()); 316b9c1b51eSKate Stone return CreateTargetInternal( 317b9c1b51eSKate Stone debugger, (const char *)nullptr, specified_arch_name, false, 318b9c1b51eSKate Stone (const OptionGroupPlatform *)nullptr, target_sp, true); 319893c932aSJim Ingham } 320893c932aSJim Ingham 32197206d57SZachary Turner Status TargetList::CreateTargetInternal(Debugger &debugger, 322a47464b2SZachary Turner llvm::StringRef user_exe_path, 32370512317SGreg Clayton const ArchSpec &specified_arch, 32430fdc8d8SChris Lattner bool get_dependent_files, 325893c932aSJim Ingham lldb::PlatformSP &platform_sp, 326893c932aSJim Ingham lldb::TargetSP &target_sp, 327b9c1b51eSKate Stone bool is_dummy_target) { 328f9d16476SPavel Labath static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 329f9d16476SPavel Labath Timer scoped_timer( 330f9d16476SPavel Labath func_cat, "TargetList::CreateTarget (file = '%s', arch = '%s')", 331f9d16476SPavel Labath user_exe_path.str().c_str(), specified_arch.GetArchitectureName()); 33297206d57SZachary Turner Status error; 3335aee162fSJim Ingham 33470512317SGreg Clayton ArchSpec arch(specified_arch); 33570512317SGreg Clayton 336b9c1b51eSKate Stone if (arch.IsValid()) { 337b9c1b51eSKate Stone if (!platform_sp || 338b9c1b51eSKate Stone !platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) 33970512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 34070512317SGreg Clayton } 34170512317SGreg Clayton 34270512317SGreg Clayton if (!platform_sp) 34370512317SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 344ded470d3SGreg Clayton 3458ae50eb4SGreg Clayton if (!arch.IsValid()) 3468ae50eb4SGreg Clayton arch = specified_arch; 3478ae50eb4SGreg Clayton 348d26206b5SJason Molenda FileSpec file(user_exe_path, false); 349a47464b2SZachary Turner if (!file.Exists() && user_exe_path.startswith("~")) { 350b9c1b51eSKate Stone // we want to expand the tilde but we don't want to resolve any symbolic 3518d48cd60SZachary Turner // links so we can't use the FileSpec constructor's resolve flag 3528d48cd60SZachary Turner llvm::SmallString<64> unglobbed_path; 3538d48cd60SZachary Turner StandardTildeExpressionResolver Resolver; 3548d48cd60SZachary Turner Resolver.ResolveFullPath(user_exe_path, unglobbed_path); 3559f822cd1SMichael Sartain 3563f559740SZachary Turner if (unglobbed_path.empty()) 3573f559740SZachary Turner file = FileSpec(user_exe_path, false); 3583f559740SZachary Turner else 3593f559740SZachary Turner file = FileSpec(unglobbed_path.c_str(), false); 360d26206b5SJason Molenda } 3619f822cd1SMichael Sartain 36282d79295SGreg Clayton bool user_exe_path_is_bundle = false; 36382d79295SGreg Clayton char resolved_bundle_exe_path[PATH_MAX]; 36482d79295SGreg Clayton resolved_bundle_exe_path[0] = '\0'; 365b9c1b51eSKate Stone if (file) { 3667d86ee5aSZachary Turner if (llvm::sys::fs::is_directory(file.GetPath())) 36782d79295SGreg Clayton user_exe_path_is_bundle = true; 36882d79295SGreg Clayton 369a47464b2SZachary Turner if (file.IsRelative() && !user_exe_path.empty()) { 3701d5855b1SPavel Labath llvm::SmallString<64> cwd; 3711d5855b1SPavel Labath if (! llvm::sys::fs::current_path(cwd)) { 372d68dbd5aSGreg Clayton FileSpec cwd_file(cwd.c_str(), false); 373d68dbd5aSGreg Clayton cwd_file.AppendPathComponent(file); 3749ff5aae5SGreg Clayton if (cwd_file.Exists()) 3759ff5aae5SGreg Clayton file = cwd_file; 376a0ca6601SGreg Clayton } 377a0ca6601SGreg Clayton } 378a0ca6601SGreg Clayton 37930fdc8d8SChris Lattner ModuleSP exe_module_sp; 380b9c1b51eSKate Stone if (platform_sp) { 381b9c1b51eSKate Stone FileSpecList executable_search_paths( 382b9c1b51eSKate Stone Target::GetDefaultExecutableSearchPaths()); 3838012cadbSGreg Clayton ModuleSpec module_spec(file, arch); 384b9c1b51eSKate Stone error = platform_sp->ResolveExecutable(module_spec, exe_module_sp, 385b9c1b51eSKate Stone executable_search_paths.GetSize() 386b9c1b51eSKate Stone ? &executable_search_paths 387b9c1b51eSKate Stone : nullptr); 388c859e2d5SGreg Clayton } 389428a9a58SCaroline Tice 390b9c1b51eSKate Stone if (error.Success() && exe_module_sp) { 391b9c1b51eSKate Stone if (exe_module_sp->GetObjectFile() == nullptr) { 392b9c1b51eSKate Stone if (arch.IsValid()) { 393b9c1b51eSKate Stone error.SetErrorStringWithFormat( 394b9c1b51eSKate Stone "\"%s\" doesn't contain architecture %s", file.GetPath().c_str(), 39564195a2cSGreg Clayton arch.GetArchitectureName()); 396b9c1b51eSKate Stone } else { 397b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("unsupported file type \"%s\"", 398b5ad4ec7SGreg Clayton file.GetPath().c_str()); 399bc5cad6cSGreg Clayton } 4005aee162fSJim Ingham return error; 4015aee162fSJim Ingham } 402893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 40330fdc8d8SChris Lattner target_sp->SetExecutableModule(exe_module_sp, get_dependent_files); 40482d79295SGreg Clayton if (user_exe_path_is_bundle) 405b9c1b51eSKate Stone exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, 406b9c1b51eSKate Stone sizeof(resolved_bundle_exe_path)); 4075aee162fSJim Ingham } 408b9c1b51eSKate Stone } else { 40905097246SAdrian Prantl // No file was specified, just create an empty target with any arch if a 41005097246SAdrian Prantl // valid arch was specified 411893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 412e996fd30SGreg Clayton } 4131559a46bSCaroline Tice 414b9c1b51eSKate Stone if (target_sp) { 41582d79295SGreg Clayton // Set argv0 with what the user typed, unless the user specified a 41682d79295SGreg Clayton // directory. If the user specified a directory, then it is probably a 41782d79295SGreg Clayton // bundle that was resolved and we need to use the resolved bundle path 418a47464b2SZachary Turner if (!user_exe_path.empty()) { 419b9c1b51eSKate Stone // Use exactly what the user typed as the first argument when we exec or 420b9c1b51eSKate Stone // posix_spawn 421b9c1b51eSKate Stone if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) { 42282d79295SGreg Clayton target_sp->SetArg0(resolved_bundle_exe_path); 423b9c1b51eSKate Stone } else { 4249f822cd1SMichael Sartain // Use resolved path 4259f822cd1SMichael Sartain target_sp->SetArg0(file.GetPath().c_str()); 426a0ca6601SGreg Clayton } 42782d79295SGreg Clayton } 428b9c1b51eSKate Stone if (file.GetDirectory()) { 429a0ca6601SGreg Clayton FileSpec file_dir; 430a0ca6601SGreg Clayton file_dir.GetDirectory() = file.GetDirectory(); 431a0ca6601SGreg Clayton target_sp->GetExecutableSearchPaths().Append(file_dir); 432a0ca6601SGreg Clayton } 433893c932aSJim Ingham 434893c932aSJim Ingham // Don't put the dummy target in the target list, it's held separately. 435b9c1b51eSKate Stone if (!is_dummy_target) { 43616ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 4372976d00aSJim Ingham m_selected_target_idx = m_target_list.size(); 43830fdc8d8SChris Lattner m_target_list.push_back(target_sp); 43933df7cd3SJim Ingham // Now prime this from the dummy target: 44033df7cd3SJim Ingham target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); 441b9c1b51eSKate Stone } else { 442893c932aSJim Ingham m_dummy_target_sp = target_sp; 443893c932aSJim Ingham } 44430fdc8d8SChris Lattner } 44530fdc8d8SChris Lattner 44630fdc8d8SChris Lattner return error; 44730fdc8d8SChris Lattner } 44830fdc8d8SChris Lattner 449b9c1b51eSKate Stone bool TargetList::DeleteTarget(TargetSP &target_sp) { 45016ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 45130fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 45230fdc8d8SChris Lattner 453b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 454b9c1b51eSKate Stone if (pos->get() == target_sp.get()) { 45530fdc8d8SChris Lattner m_target_list.erase(pos); 45630fdc8d8SChris Lattner return true; 45730fdc8d8SChris Lattner } 45830fdc8d8SChris Lattner } 45930fdc8d8SChris Lattner return false; 46030fdc8d8SChris Lattner } 46130fdc8d8SChris Lattner 462b9c1b51eSKate Stone TargetSP TargetList::FindTargetWithExecutableAndArchitecture( 463b9c1b51eSKate Stone const FileSpec &exe_file_spec, const ArchSpec *exe_arch_ptr) const { 46416ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 46530fdc8d8SChris Lattner TargetSP target_sp; 466ddd7a2a6SSean Callanan bool full_match = (bool)exe_file_spec.GetDirectory(); 46730fdc8d8SChris Lattner 46830fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 469b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 470aa149cbdSGreg Clayton Module *exe_module = (*pos)->GetExecutableModulePointer(); 47130fdc8d8SChris Lattner 472b9c1b51eSKate Stone if (exe_module) { 473b9c1b51eSKate Stone if (FileSpec::Equal(exe_file_spec, exe_module->GetFileSpec(), 474b9c1b51eSKate Stone full_match)) { 475b9c1b51eSKate Stone if (exe_arch_ptr) { 476bf4b7be6SSean Callanan if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 47730fdc8d8SChris Lattner continue; 47830fdc8d8SChris Lattner } 47930fdc8d8SChris Lattner target_sp = *pos; 48030fdc8d8SChris Lattner break; 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner } 48330fdc8d8SChris Lattner } 48430fdc8d8SChris Lattner return target_sp; 48530fdc8d8SChris Lattner } 48630fdc8d8SChris Lattner 487b9c1b51eSKate Stone TargetSP TargetList::FindTargetWithProcessID(lldb::pid_t pid) const { 48816ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 48930fdc8d8SChris Lattner TargetSP target_sp; 49030fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 491b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 49230fdc8d8SChris Lattner Process *process = (*pos)->GetProcessSP().get(); 493b9c1b51eSKate Stone if (process && process->GetID() == pid) { 49430fdc8d8SChris Lattner target_sp = *pos; 49530fdc8d8SChris Lattner break; 49630fdc8d8SChris Lattner } 49730fdc8d8SChris Lattner } 49830fdc8d8SChris Lattner return target_sp; 49930fdc8d8SChris Lattner } 50030fdc8d8SChris Lattner 501b9c1b51eSKate Stone TargetSP TargetList::FindTargetWithProcess(Process *process) const { 50230fdc8d8SChris Lattner TargetSP target_sp; 503b9c1b51eSKate Stone if (process) { 50416ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 50530fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 506b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 507b9c1b51eSKate Stone if (process == (*pos)->GetProcessSP().get()) { 50830fdc8d8SChris Lattner target_sp = *pos; 50930fdc8d8SChris Lattner break; 51030fdc8d8SChris Lattner } 51130fdc8d8SChris Lattner } 51230fdc8d8SChris Lattner } 51330fdc8d8SChris Lattner return target_sp; 51430fdc8d8SChris Lattner } 51530fdc8d8SChris Lattner 516b9c1b51eSKate Stone TargetSP TargetList::GetTargetSP(Target *target) const { 51730fdc8d8SChris Lattner TargetSP target_sp; 518b9c1b51eSKate Stone if (target) { 51916ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 52030fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 521b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 522b9c1b51eSKate Stone if (target == (*pos).get()) { 52330fdc8d8SChris Lattner target_sp = *pos; 52430fdc8d8SChris Lattner break; 52530fdc8d8SChris Lattner } 52630fdc8d8SChris Lattner } 52730fdc8d8SChris Lattner } 52830fdc8d8SChris Lattner return target_sp; 52930fdc8d8SChris Lattner } 53030fdc8d8SChris Lattner 531b9c1b51eSKate Stone uint32_t TargetList::SendAsyncInterrupt(lldb::pid_t pid) { 53230fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 53330fdc8d8SChris Lattner 534b9c1b51eSKate Stone if (pid != LLDB_INVALID_PROCESS_ID) { 53530fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID(pid)); 536b9c1b51eSKate Stone if (target_sp) { 53730fdc8d8SChris Lattner Process *process = target_sp->GetProcessSP().get(); 538b9c1b51eSKate Stone if (process) { 539cfc0935eSJim Ingham process->SendAsyncInterrupt(); 54030fdc8d8SChris Lattner ++num_async_interrupts_sent; 54130fdc8d8SChris Lattner } 54230fdc8d8SChris Lattner } 543b9c1b51eSKate Stone } else { 54430fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 54530fdc8d8SChris Lattner // list's async broadcaster... 546e65b2cf2SEugene Zelenko BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr); 54730fdc8d8SChris Lattner } 54830fdc8d8SChris Lattner 54930fdc8d8SChris Lattner return num_async_interrupts_sent; 55030fdc8d8SChris Lattner } 55130fdc8d8SChris Lattner 552b9c1b51eSKate Stone uint32_t TargetList::SignalIfRunning(lldb::pid_t pid, int signo) { 55330fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 554e65b2cf2SEugene Zelenko Process *process = nullptr; 555b9c1b51eSKate Stone if (pid == LLDB_INVALID_PROCESS_ID) { 55630fdc8d8SChris Lattner // Signal all processes with signal 55716ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 55830fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 559b9c1b51eSKate Stone for (pos = m_target_list.begin(); pos != end; ++pos) { 56030fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 561b9c1b51eSKate Stone if (process) { 562b9c1b51eSKate Stone if (process->IsAlive()) { 56330fdc8d8SChris Lattner ++num_signals_sent; 56430fdc8d8SChris Lattner process->Signal(signo); 56530fdc8d8SChris Lattner } 56630fdc8d8SChris Lattner } 56730fdc8d8SChris Lattner } 568b9c1b51eSKate Stone } else { 56930fdc8d8SChris Lattner // Signal a specific process with signal 57030fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID(pid)); 571b9c1b51eSKate Stone if (target_sp) { 57230fdc8d8SChris Lattner process = target_sp->GetProcessSP().get(); 573b9c1b51eSKate Stone if (process) { 574b9c1b51eSKate Stone if (process->IsAlive()) { 57530fdc8d8SChris Lattner ++num_signals_sent; 57630fdc8d8SChris Lattner process->Signal(signo); 57730fdc8d8SChris Lattner } 57830fdc8d8SChris Lattner } 57930fdc8d8SChris Lattner } 58030fdc8d8SChris Lattner } 58130fdc8d8SChris Lattner return num_signals_sent; 58230fdc8d8SChris Lattner } 58330fdc8d8SChris Lattner 584b9c1b51eSKate Stone int TargetList::GetNumTargets() const { 58516ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 58630fdc8d8SChris Lattner return m_target_list.size(); 58730fdc8d8SChris Lattner } 58830fdc8d8SChris Lattner 589b9c1b51eSKate Stone lldb::TargetSP TargetList::GetTargetAtIndex(uint32_t idx) const { 59030fdc8d8SChris Lattner TargetSP target_sp; 59116ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 59230fdc8d8SChris Lattner if (idx < m_target_list.size()) 59330fdc8d8SChris Lattner target_sp = m_target_list[idx]; 59430fdc8d8SChris Lattner return target_sp; 59530fdc8d8SChris Lattner } 59630fdc8d8SChris Lattner 597b9c1b51eSKate Stone uint32_t TargetList::GetIndexOfTarget(lldb::TargetSP target_sp) const { 59816ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 5998499e1a4SJim Ingham size_t num_targets = m_target_list.size(); 600b9c1b51eSKate Stone for (size_t idx = 0; idx < num_targets; idx++) { 6018499e1a4SJim Ingham if (target_sp == m_target_list[idx]) 6028499e1a4SJim Ingham return idx; 6038499e1a4SJim Ingham } 6048499e1a4SJim Ingham return UINT32_MAX; 6058499e1a4SJim Ingham } 6068499e1a4SJim Ingham 607b9c1b51eSKate Stone uint32_t TargetList::SetSelectedTarget(Target *target) { 60816ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 609b9c1b51eSKate Stone collection::const_iterator pos, begin = m_target_list.begin(), 61030fdc8d8SChris Lattner end = m_target_list.end(); 611b9c1b51eSKate Stone for (pos = begin; pos != end; ++pos) { 612b9c1b51eSKate Stone if (pos->get() == target) { 6132976d00aSJim Ingham m_selected_target_idx = std::distance(begin, pos); 6142976d00aSJim Ingham return m_selected_target_idx; 61530fdc8d8SChris Lattner } 61630fdc8d8SChris Lattner } 6172976d00aSJim Ingham m_selected_target_idx = 0; 6182976d00aSJim Ingham return m_selected_target_idx; 61930fdc8d8SChris Lattner } 62030fdc8d8SChris Lattner 621b9c1b51eSKate Stone lldb::TargetSP TargetList::GetSelectedTarget() { 62216ff8604SSaleem Abdulrasool std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); 6232976d00aSJim Ingham if (m_selected_target_idx >= m_target_list.size()) 6242976d00aSJim Ingham m_selected_target_idx = 0; 6252976d00aSJim Ingham return GetTargetAtIndex(m_selected_target_idx); 62630fdc8d8SChris Lattner } 627