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 // C Includes 1130fdc8d8SChris Lattner // C++ Includes 1230fdc8d8SChris Lattner // Other libraries and framework includes 1330fdc8d8SChris Lattner // Project includes 1430fdc8d8SChris Lattner #include "lldb/Core/Broadcaster.h" 15ded470d3SGreg Clayton #include "lldb/Core/Debugger.h" 1630fdc8d8SChris Lattner #include "lldb/Core/Event.h" 171f746071SGreg Clayton #include "lldb/Core/Module.h" 18f4d6de6aSGreg Clayton #include "lldb/Core/ModuleSpec.h" 1930fdc8d8SChris Lattner #include "lldb/Core/State.h" 2030fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 2130fdc8d8SChris Lattner #include "lldb/Host/Host.h" 22893c932aSJim Ingham #include "lldb/Host/HostInfo.h" 23b3a40ba8SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 24cac9c5f9SGreg Clayton #include "lldb/Interpreter/OptionGroupPlatform.h" 25f4d6de6aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 26e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2730fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2830fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 2930fdc8d8SChris Lattner 303f559740SZachary Turner #include "llvm/ADT/SmallString.h" 313f559740SZachary Turner 3230fdc8d8SChris Lattner using namespace lldb; 3330fdc8d8SChris Lattner using namespace lldb_private; 3430fdc8d8SChris Lattner 354bddaeb5SJim Ingham ConstString & 364bddaeb5SJim Ingham TargetList::GetStaticBroadcasterClass () 374bddaeb5SJim Ingham { 384bddaeb5SJim Ingham static ConstString class_name ("lldb.targetList"); 394bddaeb5SJim Ingham return class_name; 404bddaeb5SJim Ingham } 4130fdc8d8SChris Lattner 4230fdc8d8SChris Lattner //---------------------------------------------------------------------- 4330fdc8d8SChris Lattner // TargetList constructor 4430fdc8d8SChris Lattner //---------------------------------------------------------------------- 454bddaeb5SJim Ingham TargetList::TargetList(Debugger &debugger) : 464f465cffSJim Ingham Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()), 4730fdc8d8SChris Lattner m_target_list(), 4830fdc8d8SChris Lattner m_target_list_mutex (Mutex::eMutexTypeRecursive), 492976d00aSJim Ingham m_selected_target_idx (0) 5030fdc8d8SChris Lattner { 514bddaeb5SJim Ingham CheckInWithManager(); 5230fdc8d8SChris Lattner } 5330fdc8d8SChris Lattner 5430fdc8d8SChris Lattner //---------------------------------------------------------------------- 5530fdc8d8SChris Lattner // Destructor 5630fdc8d8SChris Lattner //---------------------------------------------------------------------- 5730fdc8d8SChris Lattner TargetList::~TargetList() 5830fdc8d8SChris Lattner { 5930fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 6030fdc8d8SChris Lattner m_target_list.clear(); 6130fdc8d8SChris Lattner } 6230fdc8d8SChris Lattner 6330fdc8d8SChris Lattner Error 64cac9c5f9SGreg Clayton TargetList::CreateTarget (Debugger &debugger, 65a0ca6601SGreg Clayton const char *user_exe_path, 66cac9c5f9SGreg Clayton const char *triple_cstr, 67cac9c5f9SGreg Clayton bool get_dependent_files, 68cac9c5f9SGreg Clayton const OptionGroupPlatform *platform_options, 69cac9c5f9SGreg Clayton TargetSP &target_sp) 70cac9c5f9SGreg Clayton { 71893c932aSJim Ingham return CreateTargetInternal (debugger, 72893c932aSJim Ingham user_exe_path, 73893c932aSJim Ingham triple_cstr, 74893c932aSJim Ingham get_dependent_files, 75893c932aSJim Ingham platform_options, 76893c932aSJim Ingham target_sp, 77893c932aSJim Ingham false); 78893c932aSJim Ingham } 79893c932aSJim Ingham 80893c932aSJim Ingham Error 81893c932aSJim Ingham TargetList::CreateTarget (Debugger &debugger, 82893c932aSJim Ingham const char *user_exe_path, 83893c932aSJim Ingham const ArchSpec& specified_arch, 84893c932aSJim Ingham bool get_dependent_files, 85893c932aSJim Ingham PlatformSP &platform_sp, 86893c932aSJim Ingham TargetSP &target_sp) 87893c932aSJim Ingham { 88893c932aSJim Ingham return CreateTargetInternal (debugger, 89893c932aSJim Ingham user_exe_path, 90893c932aSJim Ingham specified_arch, 91893c932aSJim Ingham get_dependent_files, 92893c932aSJim Ingham platform_sp, 93893c932aSJim Ingham target_sp, 94893c932aSJim Ingham false); 95893c932aSJim Ingham } 96893c932aSJim Ingham 97893c932aSJim Ingham Error 98893c932aSJim Ingham TargetList::CreateTargetInternal (Debugger &debugger, 99893c932aSJim Ingham const char *user_exe_path, 100893c932aSJim Ingham const char *triple_cstr, 101893c932aSJim Ingham bool get_dependent_files, 102893c932aSJim Ingham const OptionGroupPlatform *platform_options, 103893c932aSJim Ingham TargetSP &target_sp, 104893c932aSJim Ingham bool is_dummy_target) 105893c932aSJim Ingham { 106cac9c5f9SGreg Clayton Error error; 107cac9c5f9SGreg Clayton PlatformSP platform_sp; 108cac9c5f9SGreg Clayton 109cdc21d4cSJohnny Chen // This is purposely left empty unless it is specified by triple_cstr. 110cdc21d4cSJohnny Chen // If not initialized via triple_cstr, then the currently selected platform 111cdc21d4cSJohnny Chen // will set the architecture correctly. 11270512317SGreg Clayton const ArchSpec arch(triple_cstr); 11370512317SGreg Clayton if (triple_cstr && triple_cstr[0]) 114cac9c5f9SGreg Clayton { 115cac9c5f9SGreg Clayton if (!arch.IsValid()) 116cac9c5f9SGreg Clayton { 11786edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr); 118cac9c5f9SGreg Clayton return error; 119cac9c5f9SGreg Clayton } 120cac9c5f9SGreg Clayton } 121b3a40ba8SGreg Clayton 12270512317SGreg Clayton ArchSpec platform_arch(arch); 123f4d6de6aSGreg Clayton 1243f19ada8SGreg Clayton bool prefer_platform_arch = false; 125f4d6de6aSGreg Clayton 126b0cc53cfSGreg Clayton CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 1271b5a74eeSVince Harron 1281b5a74eeSVince Harron // let's see if there is already an existing plaform before we go creating another... 1291b5a74eeSVince Harron platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 1301b5a74eeSVince Harron 131ccd2a6d9SGreg Clayton if (platform_options && platform_options->PlatformWasSpecified ()) 132ccd2a6d9SGreg Clayton { 133ccd2a6d9SGreg Clayton // Create a new platform if it doesn't match the selected platform 134ccd2a6d9SGreg Clayton if (!platform_options->PlatformMatches(platform_sp)) 135b0cc53cfSGreg Clayton { 136b0cc53cfSGreg Clayton const bool select_platform = true; 137b0cc53cfSGreg Clayton platform_sp = platform_options->CreatePlatformWithOptions (interpreter, 138b0cc53cfSGreg Clayton arch, 139b0cc53cfSGreg Clayton select_platform, 140b0cc53cfSGreg Clayton error, 141b0cc53cfSGreg Clayton platform_arch); 142b0cc53cfSGreg Clayton if (!platform_sp) 143b0cc53cfSGreg Clayton return error; 144b0cc53cfSGreg Clayton } 145ccd2a6d9SGreg Clayton } 146b0cc53cfSGreg Clayton 147f4d6de6aSGreg Clayton if (user_exe_path && user_exe_path[0]) 148f4d6de6aSGreg Clayton { 149f4d6de6aSGreg Clayton ModuleSpecList module_specs; 150f4d6de6aSGreg Clayton ModuleSpec module_spec; 151f4d6de6aSGreg Clayton module_spec.GetFileSpec().SetFile(user_exe_path, true); 152c76fa8a3SGreg Clayton 153c76fa8a3SGreg Clayton // Resolve the executable in case we are given a path to a application bundle 154c76fa8a3SGreg Clayton // like a .app bundle on MacOSX 155c76fa8a3SGreg Clayton Host::ResolveExecutableInBundle (module_spec.GetFileSpec()); 156c76fa8a3SGreg Clayton 157f4d6de6aSGreg Clayton lldb::offset_t file_offset = 0; 1582540a8a7SGreg Clayton lldb::offset_t file_size = 0; 1592540a8a7SGreg Clayton const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); 160f4d6de6aSGreg Clayton if (num_specs > 0) 161f4d6de6aSGreg Clayton { 162f4d6de6aSGreg Clayton ModuleSpec matching_module_spec; 163f4d6de6aSGreg Clayton 164f4d6de6aSGreg Clayton if (num_specs == 1) 165f4d6de6aSGreg Clayton { 166f4d6de6aSGreg Clayton if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 167f4d6de6aSGreg Clayton { 168f4d6de6aSGreg Clayton if (platform_arch.IsValid()) 169f4d6de6aSGreg Clayton { 1703f19ada8SGreg Clayton if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) 1713f19ada8SGreg Clayton { 1723f19ada8SGreg Clayton // If the OS or vendor weren't specified, then adopt the module's 1733f19ada8SGreg Clayton // architecture so that the platform matching can be more accurate 1743f19ada8SGreg Clayton if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified()) 1753f19ada8SGreg Clayton { 1763f19ada8SGreg Clayton prefer_platform_arch = true; 1773f19ada8SGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 1783f19ada8SGreg Clayton } 1793f19ada8SGreg Clayton } 1803f19ada8SGreg Clayton else 181f4d6de6aSGreg Clayton { 182b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 183f4d6de6aSGreg Clayton platform_arch.GetTriple().str().c_str(), 184f4d6de6aSGreg Clayton matching_module_spec.GetArchitecture().GetTriple().str().c_str(), 185b5ad4ec7SGreg Clayton module_spec.GetFileSpec().GetPath().c_str()); 186f4d6de6aSGreg Clayton return error; 187f4d6de6aSGreg Clayton } 188f4d6de6aSGreg Clayton } 189f4d6de6aSGreg Clayton else 190f4d6de6aSGreg Clayton { 191f4d6de6aSGreg Clayton // Only one arch and none was specified 1923f19ada8SGreg Clayton prefer_platform_arch = true; 193f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 194f4d6de6aSGreg Clayton } 195f4d6de6aSGreg Clayton } 196f4d6de6aSGreg Clayton } 197f4d6de6aSGreg Clayton else 198f4d6de6aSGreg Clayton { 199f4d6de6aSGreg Clayton if (arch.IsValid()) 200f4d6de6aSGreg Clayton { 201f4d6de6aSGreg Clayton module_spec.GetArchitecture() = arch; 202f4d6de6aSGreg Clayton if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 203f4d6de6aSGreg Clayton { 2043f19ada8SGreg Clayton prefer_platform_arch = true; 205f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 206f4d6de6aSGreg Clayton } 207f4d6de6aSGreg Clayton } 208b0cc53cfSGreg Clayton else 209b0cc53cfSGreg Clayton { 210b0cc53cfSGreg Clayton // No architecture specified, check if there is only one platform for 211b0cc53cfSGreg Clayton // all of the architectures. 212b0cc53cfSGreg Clayton 213b0cc53cfSGreg Clayton typedef std::vector<PlatformSP> PlatformList; 214b0cc53cfSGreg Clayton PlatformList platforms; 215615eb7e6SGreg Clayton PlatformSP host_platform_sp = Platform::GetHostPlatform(); 216b0cc53cfSGreg Clayton for (size_t i=0; i<num_specs; ++i) 217b0cc53cfSGreg Clayton { 218b0cc53cfSGreg Clayton ModuleSpec module_spec; 219b0cc53cfSGreg Clayton if (module_specs.GetModuleSpecAtIndex(i, module_spec)) 220b0cc53cfSGreg Clayton { 221b0cc53cfSGreg Clayton // See if there was a selected platform and check that first 222b0cc53cfSGreg Clayton // since the user may have specified it. 223b0cc53cfSGreg Clayton if (platform_sp) 224b0cc53cfSGreg Clayton { 225b0cc53cfSGreg Clayton if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 226b0cc53cfSGreg Clayton { 227b0cc53cfSGreg Clayton platforms.push_back(platform_sp); 228b0cc53cfSGreg Clayton continue; 229f4d6de6aSGreg Clayton } 230f4d6de6aSGreg Clayton } 231f4d6de6aSGreg Clayton 232b0cc53cfSGreg Clayton // Next check the host platform it if wasn't already checked above 233b0cc53cfSGreg Clayton if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName())) 234b3a40ba8SGreg Clayton { 235b0cc53cfSGreg Clayton if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 236b3a40ba8SGreg Clayton { 237b0cc53cfSGreg Clayton platforms.push_back(host_platform_sp); 238b0cc53cfSGreg Clayton continue; 239b0cc53cfSGreg Clayton } 240b0cc53cfSGreg Clayton } 241b0cc53cfSGreg Clayton 242b0cc53cfSGreg Clayton // Just find a platform that matches the architecture in the executable file 243b0cc53cfSGreg Clayton platforms.push_back(Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr)); 244b0cc53cfSGreg Clayton } 245b0cc53cfSGreg Clayton } 246b0cc53cfSGreg Clayton 247b0cc53cfSGreg Clayton Platform *platform_ptr = NULL; 248b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 249b0cc53cfSGreg Clayton { 250b0cc53cfSGreg Clayton if (platform_ptr) 251b0cc53cfSGreg Clayton { 252b0cc53cfSGreg Clayton if (platform_ptr->GetName() != the_platform_sp->GetName()) 253b0cc53cfSGreg Clayton { 254b0cc53cfSGreg Clayton platform_ptr = NULL; 255b0cc53cfSGreg Clayton break; 256b0cc53cfSGreg Clayton } 257b0cc53cfSGreg Clayton } 258b0cc53cfSGreg Clayton else 259b0cc53cfSGreg Clayton { 260b0cc53cfSGreg Clayton platform_ptr = the_platform_sp.get(); 261b0cc53cfSGreg Clayton } 262b0cc53cfSGreg Clayton } 263b0cc53cfSGreg Clayton 264b0cc53cfSGreg Clayton if (platform_ptr) 265b0cc53cfSGreg Clayton { 266b0cc53cfSGreg Clayton // All platforms for all modules in the exectuable match, so we can select this platform 267b0cc53cfSGreg Clayton platform_sp = platforms.front(); 268b0cc53cfSGreg Clayton } 269b0cc53cfSGreg Clayton else 270b0cc53cfSGreg Clayton { 271b0cc53cfSGreg Clayton // More than one platform claims to support this file, so the --platform option must be specified 272b0cc53cfSGreg Clayton StreamString error_strm; 273b0cc53cfSGreg Clayton std::set<Platform *> platform_set; 274b0cc53cfSGreg Clayton error_strm.Printf ("more than one platform supports this executable ("); 275b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 276b0cc53cfSGreg Clayton { 277b0cc53cfSGreg Clayton if (platform_set.find(the_platform_sp.get()) == platform_set.end()) 278b0cc53cfSGreg Clayton { 279b0cc53cfSGreg Clayton if (!platform_set.empty()) 280b0cc53cfSGreg Clayton error_strm.PutCString(", "); 281b0cc53cfSGreg Clayton error_strm.PutCString(the_platform_sp->GetName().GetCString()); 282b0cc53cfSGreg Clayton platform_set.insert(the_platform_sp.get()); 283b0cc53cfSGreg Clayton } 284b0cc53cfSGreg Clayton } 285b0cc53cfSGreg Clayton error_strm.Printf("), use the --platform option to specify a platform"); 286b0cc53cfSGreg Clayton error.SetErrorString(error_strm.GetString().c_str()); 287b3a40ba8SGreg Clayton return error; 288b3a40ba8SGreg Clayton } 289b3a40ba8SGreg Clayton } 290b0cc53cfSGreg Clayton } 291b0cc53cfSGreg Clayton } 292b0cc53cfSGreg Clayton } 293b3a40ba8SGreg Clayton 294869e0c1cSTed Woodward // If we have a valid architecture, make sure the current platform is 295869e0c1cSTed Woodward // compatible with that architecture 2963f19ada8SGreg Clayton if (!prefer_platform_arch && arch.IsValid()) 297b3a40ba8SGreg Clayton { 2983f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 29995bbdf64SGreg Clayton { 30070512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 3018ec55a53SRobert Flack if (!is_dummy_target && platform_sp) 30295bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 30395bbdf64SGreg Clayton } 304b3a40ba8SGreg Clayton } 3053f19ada8SGreg Clayton else if (platform_arch.IsValid()) 3063f19ada8SGreg Clayton { 3073f19ada8SGreg Clayton // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with 3083f19ada8SGreg Clayton // a single architecture which should be used 3093f19ada8SGreg Clayton ArchSpec fixed_platform_arch; 3103f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) 31195bbdf64SGreg Clayton { 3123f19ada8SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); 3138ec55a53SRobert Flack if (!is_dummy_target && platform_sp) 31495bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 31595bbdf64SGreg Clayton } 3163f19ada8SGreg Clayton } 317b3a40ba8SGreg Clayton 31870512317SGreg Clayton if (!platform_arch.IsValid()) 31970512317SGreg Clayton platform_arch = arch; 32070512317SGreg Clayton 321893c932aSJim Ingham error = TargetList::CreateTargetInternal (debugger, 322a0ca6601SGreg Clayton user_exe_path, 32370512317SGreg Clayton platform_arch, 324cac9c5f9SGreg Clayton get_dependent_files, 325cac9c5f9SGreg Clayton platform_sp, 326893c932aSJim Ingham target_sp, 327893c932aSJim Ingham is_dummy_target); 328cac9c5f9SGreg Clayton return error; 329cac9c5f9SGreg Clayton } 330cac9c5f9SGreg Clayton 331893c932aSJim Ingham lldb::TargetSP 332893c932aSJim Ingham TargetList::GetDummyTarget (lldb_private::Debugger &debugger) 333893c932aSJim Ingham { 334893c932aSJim Ingham // FIXME: Maybe the dummy target should be per-Debugger 335893c932aSJim Ingham if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) 336893c932aSJim Ingham { 337893c932aSJim Ingham ArchSpec arch(Target::GetDefaultArchitecture()); 338893c932aSJim Ingham if (!arch.IsValid()) 339893c932aSJim Ingham arch = HostInfo::GetArchitecture(); 340893c932aSJim Ingham Error err = CreateDummyTarget(debugger, 341893c932aSJim Ingham arch.GetTriple().getTriple().c_str(), 342893c932aSJim Ingham m_dummy_target_sp); 343893c932aSJim Ingham } 344893c932aSJim Ingham 345893c932aSJim Ingham return m_dummy_target_sp; 346893c932aSJim Ingham } 347893c932aSJim Ingham 348cac9c5f9SGreg Clayton Error 349893c932aSJim Ingham TargetList::CreateDummyTarget (Debugger &debugger, 350893c932aSJim Ingham const char *specified_arch_name, 351893c932aSJim Ingham lldb::TargetSP &target_sp) 352893c932aSJim Ingham { 353893c932aSJim Ingham PlatformSP host_platform_sp(Platform::GetHostPlatform()); 354893c932aSJim Ingham return CreateTargetInternal (debugger, 355893c932aSJim Ingham (const char *) nullptr, 356893c932aSJim Ingham specified_arch_name, 357893c932aSJim Ingham false, 358893c932aSJim Ingham (const OptionGroupPlatform *) nullptr, 359893c932aSJim Ingham target_sp, 360893c932aSJim Ingham true); 361893c932aSJim Ingham } 362893c932aSJim Ingham 363893c932aSJim Ingham Error 364893c932aSJim Ingham TargetList::CreateTargetInternal (Debugger &debugger, 365a0ca6601SGreg Clayton const char *user_exe_path, 36670512317SGreg Clayton const ArchSpec& specified_arch, 36730fdc8d8SChris Lattner bool get_dependent_files, 368893c932aSJim Ingham lldb::PlatformSP &platform_sp, 369893c932aSJim Ingham lldb::TargetSP &target_sp, 370893c932aSJim Ingham bool is_dummy_target) 37130fdc8d8SChris Lattner { 372893c932aSJim Ingham 37330fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 374a0ca6601SGreg Clayton "TargetList::CreateTarget (file = '%s', arch = '%s')", 375a0ca6601SGreg Clayton user_exe_path, 37670512317SGreg Clayton specified_arch.GetArchitectureName()); 3775aee162fSJim Ingham Error error; 3785aee162fSJim Ingham 37970512317SGreg Clayton ArchSpec arch(specified_arch); 38070512317SGreg Clayton 38170512317SGreg Clayton if (arch.IsValid()) 38270512317SGreg Clayton { 383b0cc53cfSGreg Clayton if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 38470512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 38570512317SGreg Clayton } 38670512317SGreg Clayton 38770512317SGreg Clayton if (!platform_sp) 38870512317SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 389ded470d3SGreg Clayton 3908ae50eb4SGreg Clayton if (!arch.IsValid()) 3918ae50eb4SGreg Clayton arch = specified_arch; 3928ae50eb4SGreg Clayton 393d26206b5SJason Molenda FileSpec file (user_exe_path, false); 394d26206b5SJason Molenda if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 395d26206b5SJason Molenda { 3969f822cd1SMichael Sartain // we want to expand the tilde but we don't want to resolve any symbolic links 3979f822cd1SMichael Sartain // so we can't use the FileSpec constructor's resolve flag 3983f559740SZachary Turner llvm::SmallString<64> unglobbed_path(user_exe_path); 3993f559740SZachary Turner FileSpec::ResolveUsername(unglobbed_path); 4009f822cd1SMichael Sartain 4013f559740SZachary Turner if (unglobbed_path.empty()) 4023f559740SZachary Turner file = FileSpec(user_exe_path, false); 4033f559740SZachary Turner else 4043f559740SZachary Turner file = FileSpec(unglobbed_path.c_str(), false); 405d26206b5SJason Molenda } 4069f822cd1SMichael Sartain 40782d79295SGreg Clayton bool user_exe_path_is_bundle = false; 40882d79295SGreg Clayton char resolved_bundle_exe_path[PATH_MAX]; 40982d79295SGreg Clayton resolved_bundle_exe_path[0] = '\0'; 410e996fd30SGreg Clayton if (file) 4115aee162fSJim Ingham { 41282d79295SGreg Clayton if (file.GetFileType() == FileSpec::eFileTypeDirectory) 41382d79295SGreg Clayton user_exe_path_is_bundle = true; 41482d79295SGreg Clayton 415*372e9067SChaoren Lin if (file.IsRelative() && user_exe_path) 416a0ca6601SGreg Clayton { 417a0ca6601SGreg Clayton // Ignore paths that start with "./" and "../" 418a0ca6601SGreg Clayton if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 419a0ca6601SGreg Clayton (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 420a0ca6601SGreg Clayton { 421a0ca6601SGreg Clayton char cwd[PATH_MAX]; 422a0ca6601SGreg Clayton if (getcwd (cwd, sizeof(cwd))) 423a0ca6601SGreg Clayton { 424a0ca6601SGreg Clayton std::string cwd_user_exe_path (cwd); 425a0ca6601SGreg Clayton cwd_user_exe_path += '/'; 426a0ca6601SGreg Clayton cwd_user_exe_path += user_exe_path; 4279ff5aae5SGreg Clayton FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 4289ff5aae5SGreg Clayton if (cwd_file.Exists()) 4299ff5aae5SGreg Clayton file = cwd_file; 430a0ca6601SGreg Clayton } 431a0ca6601SGreg Clayton } 432a0ca6601SGreg Clayton } 433a0ca6601SGreg Clayton 43430fdc8d8SChris Lattner ModuleSP exe_module_sp; 435e996fd30SGreg Clayton if (platform_sp) 436c859e2d5SGreg Clayton { 437c859e2d5SGreg Clayton FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 4388012cadbSGreg Clayton ModuleSpec module_spec(file, arch); 4398012cadbSGreg Clayton error = platform_sp->ResolveExecutable (module_spec, 440c859e2d5SGreg Clayton exe_module_sp, 441c859e2d5SGreg Clayton executable_search_paths.GetSize() ? &executable_search_paths : NULL); 442c859e2d5SGreg Clayton } 443428a9a58SCaroline Tice 444e996fd30SGreg Clayton if (error.Success() && exe_module_sp) 44530fdc8d8SChris Lattner { 4465aee162fSJim Ingham if (exe_module_sp->GetObjectFile() == NULL) 4475aee162fSJim Ingham { 448bc5cad6cSGreg Clayton if (arch.IsValid()) 449bc5cad6cSGreg Clayton { 450b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 451b5ad4ec7SGreg Clayton file.GetPath().c_str(), 45264195a2cSGreg Clayton arch.GetArchitectureName()); 453bc5cad6cSGreg Clayton } 454bc5cad6cSGreg Clayton else 455bc5cad6cSGreg Clayton { 456b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("unsupported file type \"%s\"", 457b5ad4ec7SGreg Clayton file.GetPath().c_str()); 458bc5cad6cSGreg Clayton } 4595aee162fSJim Ingham return error; 4605aee162fSJim Ingham } 461893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 46230fdc8d8SChris Lattner target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 46382d79295SGreg Clayton if (user_exe_path_is_bundle) 46482d79295SGreg Clayton exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 4655aee162fSJim Ingham } 4665aee162fSJim Ingham } 467e996fd30SGreg Clayton else 468e996fd30SGreg Clayton { 469e996fd30SGreg Clayton // No file was specified, just create an empty target with any arch 470e996fd30SGreg Clayton // if a valid arch was specified 471893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 472e996fd30SGreg Clayton } 4731559a46bSCaroline Tice 474e996fd30SGreg Clayton if (target_sp) 475e996fd30SGreg Clayton { 47682d79295SGreg Clayton // Set argv0 with what the user typed, unless the user specified a 47782d79295SGreg Clayton // directory. If the user specified a directory, then it is probably a 47882d79295SGreg Clayton // bundle that was resolved and we need to use the resolved bundle path 479a0ca6601SGreg Clayton if (user_exe_path) 480a0ca6601SGreg Clayton { 481a0ca6601SGreg Clayton // Use exactly what the user typed as the first argument when we exec or posix_spawn 48282d79295SGreg Clayton if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 48382d79295SGreg Clayton { 48482d79295SGreg Clayton target_sp->SetArg0 (resolved_bundle_exe_path); 48582d79295SGreg Clayton } 48682d79295SGreg Clayton else 48782d79295SGreg Clayton { 4889f822cd1SMichael Sartain // Use resolved path 4899f822cd1SMichael Sartain target_sp->SetArg0 (file.GetPath().c_str()); 490a0ca6601SGreg Clayton } 49182d79295SGreg Clayton } 492a0ca6601SGreg Clayton if (file.GetDirectory()) 493a0ca6601SGreg Clayton { 494a0ca6601SGreg Clayton FileSpec file_dir; 495a0ca6601SGreg Clayton file_dir.GetDirectory() = file.GetDirectory(); 496a0ca6601SGreg Clayton target_sp->GetExecutableSearchPaths ().Append (file_dir); 497a0ca6601SGreg Clayton } 498893c932aSJim Ingham 499893c932aSJim Ingham // Don't put the dummy target in the target list, it's held separately. 500893c932aSJim Ingham if (!is_dummy_target) 501893c932aSJim Ingham { 50230fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 5032976d00aSJim Ingham m_selected_target_idx = m_target_list.size(); 50430fdc8d8SChris Lattner m_target_list.push_back(target_sp); 50533df7cd3SJim Ingham // Now prime this from the dummy target: 50633df7cd3SJim Ingham target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); 507893c932aSJim Ingham } 508893c932aSJim Ingham else 509893c932aSJim Ingham { 510893c932aSJim Ingham m_dummy_target_sp = target_sp; 511893c932aSJim Ingham } 51230fdc8d8SChris Lattner } 51330fdc8d8SChris Lattner 51430fdc8d8SChris Lattner return error; 51530fdc8d8SChris Lattner } 51630fdc8d8SChris Lattner 51730fdc8d8SChris Lattner bool 51830fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp) 51930fdc8d8SChris Lattner { 52030fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 52130fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 52230fdc8d8SChris Lattner 52330fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 52430fdc8d8SChris Lattner { 52530fdc8d8SChris Lattner if (pos->get() == target_sp.get()) 52630fdc8d8SChris Lattner { 52730fdc8d8SChris Lattner m_target_list.erase(pos); 52830fdc8d8SChris Lattner return true; 52930fdc8d8SChris Lattner } 53030fdc8d8SChris Lattner } 53130fdc8d8SChris Lattner return false; 53230fdc8d8SChris Lattner } 53330fdc8d8SChris Lattner 53430fdc8d8SChris Lattner 53530fdc8d8SChris Lattner TargetSP 53630fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture 53730fdc8d8SChris Lattner ( 53830fdc8d8SChris Lattner const FileSpec &exe_file_spec, 53930fdc8d8SChris Lattner const ArchSpec *exe_arch_ptr 54030fdc8d8SChris Lattner ) const 54130fdc8d8SChris Lattner { 54230fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 54330fdc8d8SChris Lattner TargetSP target_sp; 544ddd7a2a6SSean Callanan bool full_match = (bool)exe_file_spec.GetDirectory(); 54530fdc8d8SChris Lattner 54630fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 54730fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 54830fdc8d8SChris Lattner { 549aa149cbdSGreg Clayton Module *exe_module = (*pos)->GetExecutableModulePointer(); 55030fdc8d8SChris Lattner 551aa149cbdSGreg Clayton if (exe_module) 55230fdc8d8SChris Lattner { 553aa149cbdSGreg Clayton if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 55430fdc8d8SChris Lattner { 55530fdc8d8SChris Lattner if (exe_arch_ptr) 55630fdc8d8SChris Lattner { 557bf4b7be6SSean Callanan if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 55830fdc8d8SChris Lattner continue; 55930fdc8d8SChris Lattner } 56030fdc8d8SChris Lattner target_sp = *pos; 56130fdc8d8SChris Lattner break; 56230fdc8d8SChris Lattner } 56330fdc8d8SChris Lattner } 56430fdc8d8SChris Lattner } 56530fdc8d8SChris Lattner return target_sp; 56630fdc8d8SChris Lattner } 56730fdc8d8SChris Lattner 56830fdc8d8SChris Lattner TargetSP 56930fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 57030fdc8d8SChris Lattner { 57130fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 57230fdc8d8SChris Lattner TargetSP target_sp; 57330fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 57430fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 57530fdc8d8SChris Lattner { 57630fdc8d8SChris Lattner Process* process = (*pos)->GetProcessSP().get(); 57730fdc8d8SChris Lattner if (process && process->GetID() == pid) 57830fdc8d8SChris Lattner { 57930fdc8d8SChris Lattner target_sp = *pos; 58030fdc8d8SChris Lattner break; 58130fdc8d8SChris Lattner } 58230fdc8d8SChris Lattner } 58330fdc8d8SChris Lattner return target_sp; 58430fdc8d8SChris Lattner } 58530fdc8d8SChris Lattner 58630fdc8d8SChris Lattner 58730fdc8d8SChris Lattner TargetSP 58830fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const 58930fdc8d8SChris Lattner { 59030fdc8d8SChris Lattner TargetSP target_sp; 59130fdc8d8SChris Lattner if (process) 59230fdc8d8SChris Lattner { 59330fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 59430fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 59530fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 59630fdc8d8SChris Lattner { 59730fdc8d8SChris Lattner if (process == (*pos)->GetProcessSP().get()) 59830fdc8d8SChris Lattner { 59930fdc8d8SChris Lattner target_sp = *pos; 60030fdc8d8SChris Lattner break; 60130fdc8d8SChris Lattner } 60230fdc8d8SChris Lattner } 60330fdc8d8SChris Lattner } 60430fdc8d8SChris Lattner return target_sp; 60530fdc8d8SChris Lattner } 60630fdc8d8SChris Lattner 60730fdc8d8SChris Lattner TargetSP 60830fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const 60930fdc8d8SChris Lattner { 61030fdc8d8SChris Lattner TargetSP target_sp; 61130fdc8d8SChris Lattner if (target) 61230fdc8d8SChris Lattner { 61330fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 61430fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 61530fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 61630fdc8d8SChris Lattner { 61730fdc8d8SChris Lattner if (target == (*pos).get()) 61830fdc8d8SChris Lattner { 61930fdc8d8SChris Lattner target_sp = *pos; 62030fdc8d8SChris Lattner break; 62130fdc8d8SChris Lattner } 62230fdc8d8SChris Lattner } 62330fdc8d8SChris Lattner } 62430fdc8d8SChris Lattner return target_sp; 62530fdc8d8SChris Lattner } 62630fdc8d8SChris Lattner 62730fdc8d8SChris Lattner uint32_t 62830fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid) 62930fdc8d8SChris Lattner { 63030fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 63130fdc8d8SChris Lattner 63230fdc8d8SChris Lattner if (pid != LLDB_INVALID_PROCESS_ID) 63330fdc8d8SChris Lattner { 63430fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 63530fdc8d8SChris Lattner if (target_sp.get()) 63630fdc8d8SChris Lattner { 63730fdc8d8SChris Lattner Process* process = target_sp->GetProcessSP().get(); 63830fdc8d8SChris Lattner if (process) 63930fdc8d8SChris Lattner { 640cfc0935eSJim Ingham process->SendAsyncInterrupt(); 64130fdc8d8SChris Lattner ++num_async_interrupts_sent; 64230fdc8d8SChris Lattner } 64330fdc8d8SChris Lattner } 64430fdc8d8SChris Lattner } 64530fdc8d8SChris Lattner else 64630fdc8d8SChris Lattner { 64730fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 64830fdc8d8SChris Lattner // list's async broadcaster... 64930fdc8d8SChris Lattner BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 65030fdc8d8SChris Lattner } 65130fdc8d8SChris Lattner 65230fdc8d8SChris Lattner return num_async_interrupts_sent; 65330fdc8d8SChris Lattner } 65430fdc8d8SChris Lattner 65530fdc8d8SChris Lattner uint32_t 65630fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 65730fdc8d8SChris Lattner { 65830fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 65930fdc8d8SChris Lattner Process *process = NULL; 66030fdc8d8SChris Lattner if (pid == LLDB_INVALID_PROCESS_ID) 66130fdc8d8SChris Lattner { 66230fdc8d8SChris Lattner // Signal all processes with signal 66330fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 66430fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 66530fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 66630fdc8d8SChris Lattner { 66730fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 66830fdc8d8SChris Lattner if (process) 66930fdc8d8SChris Lattner { 67030fdc8d8SChris Lattner if (process->IsAlive()) 67130fdc8d8SChris Lattner { 67230fdc8d8SChris Lattner ++num_signals_sent; 67330fdc8d8SChris Lattner process->Signal (signo); 67430fdc8d8SChris Lattner } 67530fdc8d8SChris Lattner } 67630fdc8d8SChris Lattner } 67730fdc8d8SChris Lattner } 67830fdc8d8SChris Lattner else 67930fdc8d8SChris Lattner { 68030fdc8d8SChris Lattner // Signal a specific process with signal 68130fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 68230fdc8d8SChris Lattner if (target_sp.get()) 68330fdc8d8SChris Lattner { 68430fdc8d8SChris Lattner process = target_sp->GetProcessSP().get(); 68530fdc8d8SChris Lattner if (process) 68630fdc8d8SChris Lattner { 68730fdc8d8SChris Lattner if (process->IsAlive()) 68830fdc8d8SChris Lattner { 68930fdc8d8SChris Lattner ++num_signals_sent; 69030fdc8d8SChris Lattner process->Signal (signo); 69130fdc8d8SChris Lattner } 69230fdc8d8SChris Lattner } 69330fdc8d8SChris Lattner } 69430fdc8d8SChris Lattner } 69530fdc8d8SChris Lattner return num_signals_sent; 69630fdc8d8SChris Lattner } 69730fdc8d8SChris Lattner 69830fdc8d8SChris Lattner int 69930fdc8d8SChris Lattner TargetList::GetNumTargets () const 70030fdc8d8SChris Lattner { 70130fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 70230fdc8d8SChris Lattner return m_target_list.size(); 70330fdc8d8SChris Lattner } 70430fdc8d8SChris Lattner 70530fdc8d8SChris Lattner lldb::TargetSP 70630fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const 70730fdc8d8SChris Lattner { 70830fdc8d8SChris Lattner TargetSP target_sp; 70930fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 71030fdc8d8SChris Lattner if (idx < m_target_list.size()) 71130fdc8d8SChris Lattner target_sp = m_target_list[idx]; 71230fdc8d8SChris Lattner return target_sp; 71330fdc8d8SChris Lattner } 71430fdc8d8SChris Lattner 71530fdc8d8SChris Lattner uint32_t 7168499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 7178499e1a4SJim Ingham { 7188499e1a4SJim Ingham Mutex::Locker locker (m_target_list_mutex); 7198499e1a4SJim Ingham size_t num_targets = m_target_list.size(); 7208499e1a4SJim Ingham for (size_t idx = 0; idx < num_targets; idx++) 7218499e1a4SJim Ingham { 7228499e1a4SJim Ingham if (target_sp == m_target_list[idx]) 7238499e1a4SJim Ingham return idx; 7248499e1a4SJim Ingham } 7258499e1a4SJim Ingham return UINT32_MAX; 7268499e1a4SJim Ingham } 7278499e1a4SJim Ingham 7288499e1a4SJim Ingham uint32_t 7292976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target) 73030fdc8d8SChris Lattner { 73130fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 73230fdc8d8SChris Lattner collection::const_iterator pos, 73330fdc8d8SChris Lattner begin = m_target_list.begin(), 73430fdc8d8SChris Lattner end = m_target_list.end(); 73530fdc8d8SChris Lattner for (pos = begin; pos != end; ++pos) 73630fdc8d8SChris Lattner { 73730fdc8d8SChris Lattner if (pos->get() == target) 73830fdc8d8SChris Lattner { 7392976d00aSJim Ingham m_selected_target_idx = std::distance (begin, pos); 7402976d00aSJim Ingham return m_selected_target_idx; 74130fdc8d8SChris Lattner } 74230fdc8d8SChris Lattner } 7432976d00aSJim Ingham m_selected_target_idx = 0; 7442976d00aSJim Ingham return m_selected_target_idx; 74530fdc8d8SChris Lattner } 74630fdc8d8SChris Lattner 74730fdc8d8SChris Lattner lldb::TargetSP 7482976d00aSJim Ingham TargetList::GetSelectedTarget () 74930fdc8d8SChris Lattner { 75030fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 7512976d00aSJim Ingham if (m_selected_target_idx >= m_target_list.size()) 7522976d00aSJim Ingham m_selected_target_idx = 0; 7532976d00aSJim Ingham return GetTargetAtIndex (m_selected_target_idx); 75430fdc8d8SChris Lattner } 755