130fdc8d8SChris Lattner //===-- TargetList.cpp ------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/Core/Broadcaster.h" 17ded470d3SGreg Clayton #include "lldb/Core/Debugger.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Event.h" 191f746071SGreg Clayton #include "lldb/Core/Module.h" 20f4d6de6aSGreg Clayton #include "lldb/Core/ModuleSpec.h" 2130fdc8d8SChris Lattner #include "lldb/Core/State.h" 2230fdc8d8SChris Lattner #include "lldb/Core/Timer.h" 2330fdc8d8SChris Lattner #include "lldb/Host/Host.h" 24893c932aSJim Ingham #include "lldb/Host/HostInfo.h" 25b3a40ba8SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 26cac9c5f9SGreg Clayton #include "lldb/Interpreter/OptionGroupPlatform.h" 27f4d6de6aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 28e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2930fdc8d8SChris Lattner #include "lldb/Target/Process.h" 3030fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 3130fdc8d8SChris Lattner 323f559740SZachary Turner #include "llvm/ADT/SmallString.h" 333f559740SZachary Turner 3430fdc8d8SChris Lattner using namespace lldb; 3530fdc8d8SChris Lattner using namespace lldb_private; 3630fdc8d8SChris Lattner 374bddaeb5SJim Ingham ConstString & 384bddaeb5SJim Ingham TargetList::GetStaticBroadcasterClass () 394bddaeb5SJim Ingham { 404bddaeb5SJim Ingham static ConstString class_name ("lldb.targetList"); 414bddaeb5SJim Ingham return class_name; 424bddaeb5SJim Ingham } 4330fdc8d8SChris Lattner 4430fdc8d8SChris Lattner //---------------------------------------------------------------------- 4530fdc8d8SChris Lattner // TargetList constructor 4630fdc8d8SChris Lattner //---------------------------------------------------------------------- 474bddaeb5SJim Ingham TargetList::TargetList(Debugger &debugger) : 484f465cffSJim Ingham Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()), 4930fdc8d8SChris Lattner m_target_list(), 5030fdc8d8SChris Lattner m_target_list_mutex (Mutex::eMutexTypeRecursive), 512976d00aSJim Ingham m_selected_target_idx (0) 5230fdc8d8SChris Lattner { 534bddaeb5SJim Ingham CheckInWithManager(); 5430fdc8d8SChris Lattner } 5530fdc8d8SChris Lattner 5630fdc8d8SChris Lattner //---------------------------------------------------------------------- 5730fdc8d8SChris Lattner // Destructor 5830fdc8d8SChris Lattner //---------------------------------------------------------------------- 5930fdc8d8SChris Lattner TargetList::~TargetList() 6030fdc8d8SChris Lattner { 6130fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 6230fdc8d8SChris Lattner m_target_list.clear(); 6330fdc8d8SChris Lattner } 6430fdc8d8SChris Lattner 6530fdc8d8SChris Lattner Error 66cac9c5f9SGreg Clayton TargetList::CreateTarget (Debugger &debugger, 67a0ca6601SGreg Clayton const char *user_exe_path, 68cac9c5f9SGreg Clayton const char *triple_cstr, 69cac9c5f9SGreg Clayton bool get_dependent_files, 70cac9c5f9SGreg Clayton const OptionGroupPlatform *platform_options, 71cac9c5f9SGreg Clayton TargetSP &target_sp) 72cac9c5f9SGreg Clayton { 73893c932aSJim Ingham return CreateTargetInternal (debugger, 74893c932aSJim Ingham user_exe_path, 75893c932aSJim Ingham triple_cstr, 76893c932aSJim Ingham get_dependent_files, 77893c932aSJim Ingham platform_options, 78893c932aSJim Ingham target_sp, 79893c932aSJim Ingham false); 80893c932aSJim Ingham } 81893c932aSJim Ingham 82893c932aSJim Ingham Error 83893c932aSJim Ingham TargetList::CreateTarget (Debugger &debugger, 84893c932aSJim Ingham const char *user_exe_path, 85893c932aSJim Ingham const ArchSpec& specified_arch, 86893c932aSJim Ingham bool get_dependent_files, 87893c932aSJim Ingham PlatformSP &platform_sp, 88893c932aSJim Ingham TargetSP &target_sp) 89893c932aSJim Ingham { 90893c932aSJim Ingham return CreateTargetInternal (debugger, 91893c932aSJim Ingham user_exe_path, 92893c932aSJim Ingham specified_arch, 93893c932aSJim Ingham get_dependent_files, 94893c932aSJim Ingham platform_sp, 95893c932aSJim Ingham target_sp, 96893c932aSJim Ingham false); 97893c932aSJim Ingham } 98893c932aSJim Ingham 99893c932aSJim Ingham Error 100893c932aSJim Ingham TargetList::CreateTargetInternal (Debugger &debugger, 101893c932aSJim Ingham const char *user_exe_path, 102893c932aSJim Ingham const char *triple_cstr, 103893c932aSJim Ingham bool get_dependent_files, 104893c932aSJim Ingham const OptionGroupPlatform *platform_options, 105893c932aSJim Ingham TargetSP &target_sp, 106893c932aSJim Ingham bool is_dummy_target) 107893c932aSJim Ingham { 108cac9c5f9SGreg Clayton Error error; 109cac9c5f9SGreg Clayton PlatformSP platform_sp; 110cac9c5f9SGreg Clayton 111cdc21d4cSJohnny Chen // This is purposely left empty unless it is specified by triple_cstr. 112cdc21d4cSJohnny Chen // If not initialized via triple_cstr, then the currently selected platform 113cdc21d4cSJohnny Chen // will set the architecture correctly. 11470512317SGreg Clayton const ArchSpec arch(triple_cstr); 11570512317SGreg Clayton if (triple_cstr && triple_cstr[0]) 116cac9c5f9SGreg Clayton { 117cac9c5f9SGreg Clayton if (!arch.IsValid()) 118cac9c5f9SGreg Clayton { 11986edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr); 120cac9c5f9SGreg Clayton return error; 121cac9c5f9SGreg Clayton } 122cac9c5f9SGreg Clayton } 123b3a40ba8SGreg Clayton 12470512317SGreg Clayton ArchSpec platform_arch(arch); 125f4d6de6aSGreg Clayton 1263f19ada8SGreg Clayton bool prefer_platform_arch = false; 127f4d6de6aSGreg Clayton 128b0cc53cfSGreg Clayton CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 1291b5a74eeSVince Harron 1301b5a74eeSVince Harron // let's see if there is already an existing plaform before we go creating another... 1311b5a74eeSVince Harron platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 1321b5a74eeSVince Harron 133*ccd2a6d9SGreg Clayton if (platform_options && platform_options->PlatformWasSpecified ()) 134*ccd2a6d9SGreg Clayton { 135*ccd2a6d9SGreg Clayton // Create a new platform if it doesn't match the selected platform 136*ccd2a6d9SGreg Clayton if (!platform_options->PlatformMatches(platform_sp)) 137b0cc53cfSGreg Clayton { 138b0cc53cfSGreg Clayton const bool select_platform = true; 139b0cc53cfSGreg Clayton platform_sp = platform_options->CreatePlatformWithOptions (interpreter, 140b0cc53cfSGreg Clayton arch, 141b0cc53cfSGreg Clayton select_platform, 142b0cc53cfSGreg Clayton error, 143b0cc53cfSGreg Clayton platform_arch); 144b0cc53cfSGreg Clayton if (!platform_sp) 145b0cc53cfSGreg Clayton return error; 146b0cc53cfSGreg Clayton } 147*ccd2a6d9SGreg Clayton } 148b0cc53cfSGreg Clayton 149f4d6de6aSGreg Clayton if (user_exe_path && user_exe_path[0]) 150f4d6de6aSGreg Clayton { 151f4d6de6aSGreg Clayton ModuleSpecList module_specs; 152f4d6de6aSGreg Clayton ModuleSpec module_spec; 153f4d6de6aSGreg Clayton module_spec.GetFileSpec().SetFile(user_exe_path, true); 154c76fa8a3SGreg Clayton 155c76fa8a3SGreg Clayton // Resolve the executable in case we are given a path to a application bundle 156c76fa8a3SGreg Clayton // like a .app bundle on MacOSX 157c76fa8a3SGreg Clayton Host::ResolveExecutableInBundle (module_spec.GetFileSpec()); 158c76fa8a3SGreg Clayton 159f4d6de6aSGreg Clayton lldb::offset_t file_offset = 0; 1602540a8a7SGreg Clayton lldb::offset_t file_size = 0; 1612540a8a7SGreg Clayton const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); 162f4d6de6aSGreg Clayton if (num_specs > 0) 163f4d6de6aSGreg Clayton { 164f4d6de6aSGreg Clayton ModuleSpec matching_module_spec; 165f4d6de6aSGreg Clayton 166f4d6de6aSGreg Clayton if (num_specs == 1) 167f4d6de6aSGreg Clayton { 168f4d6de6aSGreg Clayton if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 169f4d6de6aSGreg Clayton { 170f4d6de6aSGreg Clayton if (platform_arch.IsValid()) 171f4d6de6aSGreg Clayton { 1723f19ada8SGreg Clayton if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) 1733f19ada8SGreg Clayton { 1743f19ada8SGreg Clayton // If the OS or vendor weren't specified, then adopt the module's 1753f19ada8SGreg Clayton // architecture so that the platform matching can be more accurate 1763f19ada8SGreg Clayton if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified()) 1773f19ada8SGreg Clayton { 1783f19ada8SGreg Clayton prefer_platform_arch = true; 1793f19ada8SGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 1803f19ada8SGreg Clayton } 1813f19ada8SGreg Clayton } 1823f19ada8SGreg Clayton else 183f4d6de6aSGreg Clayton { 184b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 185f4d6de6aSGreg Clayton platform_arch.GetTriple().str().c_str(), 186f4d6de6aSGreg Clayton matching_module_spec.GetArchitecture().GetTriple().str().c_str(), 187b5ad4ec7SGreg Clayton module_spec.GetFileSpec().GetPath().c_str()); 188f4d6de6aSGreg Clayton return error; 189f4d6de6aSGreg Clayton } 190f4d6de6aSGreg Clayton } 191f4d6de6aSGreg Clayton else 192f4d6de6aSGreg Clayton { 193f4d6de6aSGreg Clayton // Only one arch and none was specified 1943f19ada8SGreg Clayton prefer_platform_arch = true; 195f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 196f4d6de6aSGreg Clayton } 197f4d6de6aSGreg Clayton } 198f4d6de6aSGreg Clayton } 199f4d6de6aSGreg Clayton else 200f4d6de6aSGreg Clayton { 201f4d6de6aSGreg Clayton if (arch.IsValid()) 202f4d6de6aSGreg Clayton { 203f4d6de6aSGreg Clayton module_spec.GetArchitecture() = arch; 204f4d6de6aSGreg Clayton if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 205f4d6de6aSGreg Clayton { 2063f19ada8SGreg Clayton prefer_platform_arch = true; 207f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 208f4d6de6aSGreg Clayton } 209f4d6de6aSGreg Clayton } 210b0cc53cfSGreg Clayton else 211b0cc53cfSGreg Clayton { 212b0cc53cfSGreg Clayton // No architecture specified, check if there is only one platform for 213b0cc53cfSGreg Clayton // all of the architectures. 214b0cc53cfSGreg Clayton 215b0cc53cfSGreg Clayton typedef std::vector<PlatformSP> PlatformList; 216b0cc53cfSGreg Clayton PlatformList platforms; 217615eb7e6SGreg Clayton PlatformSP host_platform_sp = Platform::GetHostPlatform(); 218b0cc53cfSGreg Clayton for (size_t i=0; i<num_specs; ++i) 219b0cc53cfSGreg Clayton { 220b0cc53cfSGreg Clayton ModuleSpec module_spec; 221b0cc53cfSGreg Clayton if (module_specs.GetModuleSpecAtIndex(i, module_spec)) 222b0cc53cfSGreg Clayton { 223b0cc53cfSGreg Clayton // See if there was a selected platform and check that first 224b0cc53cfSGreg Clayton // since the user may have specified it. 225b0cc53cfSGreg Clayton if (platform_sp) 226b0cc53cfSGreg Clayton { 227b0cc53cfSGreg Clayton if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 228b0cc53cfSGreg Clayton { 229b0cc53cfSGreg Clayton platforms.push_back(platform_sp); 230b0cc53cfSGreg Clayton continue; 231f4d6de6aSGreg Clayton } 232f4d6de6aSGreg Clayton } 233f4d6de6aSGreg Clayton 234b0cc53cfSGreg Clayton // Next check the host platform it if wasn't already checked above 235b0cc53cfSGreg Clayton if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName())) 236b3a40ba8SGreg Clayton { 237b0cc53cfSGreg Clayton if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 238b3a40ba8SGreg Clayton { 239b0cc53cfSGreg Clayton platforms.push_back(host_platform_sp); 240b0cc53cfSGreg Clayton continue; 241b0cc53cfSGreg Clayton } 242b0cc53cfSGreg Clayton } 243b0cc53cfSGreg Clayton 244b0cc53cfSGreg Clayton // Just find a platform that matches the architecture in the executable file 245b0cc53cfSGreg Clayton platforms.push_back(Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr)); 246b0cc53cfSGreg Clayton } 247b0cc53cfSGreg Clayton } 248b0cc53cfSGreg Clayton 249b0cc53cfSGreg Clayton Platform *platform_ptr = NULL; 250b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 251b0cc53cfSGreg Clayton { 252b0cc53cfSGreg Clayton if (platform_ptr) 253b0cc53cfSGreg Clayton { 254b0cc53cfSGreg Clayton if (platform_ptr->GetName() != the_platform_sp->GetName()) 255b0cc53cfSGreg Clayton { 256b0cc53cfSGreg Clayton platform_ptr = NULL; 257b0cc53cfSGreg Clayton break; 258b0cc53cfSGreg Clayton } 259b0cc53cfSGreg Clayton } 260b0cc53cfSGreg Clayton else 261b0cc53cfSGreg Clayton { 262b0cc53cfSGreg Clayton platform_ptr = the_platform_sp.get(); 263b0cc53cfSGreg Clayton } 264b0cc53cfSGreg Clayton } 265b0cc53cfSGreg Clayton 266b0cc53cfSGreg Clayton if (platform_ptr) 267b0cc53cfSGreg Clayton { 268b0cc53cfSGreg Clayton // All platforms for all modules in the exectuable match, so we can select this platform 269b0cc53cfSGreg Clayton platform_sp = platforms.front(); 270b0cc53cfSGreg Clayton } 271b0cc53cfSGreg Clayton else 272b0cc53cfSGreg Clayton { 273b0cc53cfSGreg Clayton // More than one platform claims to support this file, so the --platform option must be specified 274b0cc53cfSGreg Clayton StreamString error_strm; 275b0cc53cfSGreg Clayton std::set<Platform *> platform_set; 276b0cc53cfSGreg Clayton error_strm.Printf ("more than one platform supports this executable ("); 277b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 278b0cc53cfSGreg Clayton { 279b0cc53cfSGreg Clayton if (platform_set.find(the_platform_sp.get()) == platform_set.end()) 280b0cc53cfSGreg Clayton { 281b0cc53cfSGreg Clayton if (!platform_set.empty()) 282b0cc53cfSGreg Clayton error_strm.PutCString(", "); 283b0cc53cfSGreg Clayton error_strm.PutCString(the_platform_sp->GetName().GetCString()); 284b0cc53cfSGreg Clayton platform_set.insert(the_platform_sp.get()); 285b0cc53cfSGreg Clayton } 286b0cc53cfSGreg Clayton } 287b0cc53cfSGreg Clayton error_strm.Printf("), use the --platform option to specify a platform"); 288b0cc53cfSGreg Clayton error.SetErrorString(error_strm.GetString().c_str()); 289b3a40ba8SGreg Clayton return error; 290b3a40ba8SGreg Clayton } 291b3a40ba8SGreg Clayton } 292b0cc53cfSGreg Clayton } 293b0cc53cfSGreg Clayton } 294b0cc53cfSGreg Clayton } 295b3a40ba8SGreg Clayton 296b3a40ba8SGreg Clayton if (!platform_sp) 297b3a40ba8SGreg Clayton { 298b3a40ba8SGreg Clayton // Get the current platform and make sure it is compatible with the 299b3a40ba8SGreg Clayton // current architecture if we have a valid architecture. 300b3a40ba8SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform (); 301b3a40ba8SGreg Clayton 3023f19ada8SGreg Clayton if (!prefer_platform_arch && arch.IsValid()) 303b3a40ba8SGreg Clayton { 3043f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 30595bbdf64SGreg Clayton { 30670512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 30795bbdf64SGreg Clayton if (platform_sp) 30895bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 30995bbdf64SGreg Clayton } 310b3a40ba8SGreg Clayton } 3113f19ada8SGreg Clayton else if (platform_arch.IsValid()) 3123f19ada8SGreg Clayton { 3133f19ada8SGreg Clayton // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with 3143f19ada8SGreg Clayton // a single architecture which should be used 3153f19ada8SGreg Clayton ArchSpec fixed_platform_arch; 3163f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) 31795bbdf64SGreg Clayton { 3183f19ada8SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); 31995bbdf64SGreg Clayton if (platform_sp) 32095bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 32195bbdf64SGreg Clayton } 3223f19ada8SGreg Clayton } 323b3a40ba8SGreg Clayton } 324b3a40ba8SGreg Clayton 32570512317SGreg Clayton if (!platform_arch.IsValid()) 32670512317SGreg Clayton platform_arch = arch; 32770512317SGreg Clayton 328893c932aSJim Ingham error = TargetList::CreateTargetInternal (debugger, 329a0ca6601SGreg Clayton user_exe_path, 33070512317SGreg Clayton platform_arch, 331cac9c5f9SGreg Clayton get_dependent_files, 332cac9c5f9SGreg Clayton platform_sp, 333893c932aSJim Ingham target_sp, 334893c932aSJim Ingham is_dummy_target); 335cac9c5f9SGreg Clayton return error; 336cac9c5f9SGreg Clayton } 337cac9c5f9SGreg Clayton 338893c932aSJim Ingham lldb::TargetSP 339893c932aSJim Ingham TargetList::GetDummyTarget (lldb_private::Debugger &debugger) 340893c932aSJim Ingham { 341893c932aSJim Ingham // FIXME: Maybe the dummy target should be per-Debugger 342893c932aSJim Ingham if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) 343893c932aSJim Ingham { 344893c932aSJim Ingham ArchSpec arch(Target::GetDefaultArchitecture()); 345893c932aSJim Ingham if (!arch.IsValid()) 346893c932aSJim Ingham arch = HostInfo::GetArchitecture(); 347893c932aSJim Ingham Error err = CreateDummyTarget(debugger, 348893c932aSJim Ingham arch.GetTriple().getTriple().c_str(), 349893c932aSJim Ingham m_dummy_target_sp); 350893c932aSJim Ingham } 351893c932aSJim Ingham 352893c932aSJim Ingham return m_dummy_target_sp; 353893c932aSJim Ingham } 354893c932aSJim Ingham 355cac9c5f9SGreg Clayton Error 356893c932aSJim Ingham TargetList::CreateDummyTarget (Debugger &debugger, 357893c932aSJim Ingham const char *specified_arch_name, 358893c932aSJim Ingham lldb::TargetSP &target_sp) 359893c932aSJim Ingham { 360893c932aSJim Ingham PlatformSP host_platform_sp(Platform::GetHostPlatform()); 361893c932aSJim Ingham return CreateTargetInternal (debugger, 362893c932aSJim Ingham (const char *) nullptr, 363893c932aSJim Ingham specified_arch_name, 364893c932aSJim Ingham false, 365893c932aSJim Ingham (const OptionGroupPlatform *) nullptr, 366893c932aSJim Ingham target_sp, 367893c932aSJim Ingham true); 368893c932aSJim Ingham } 369893c932aSJim Ingham 370893c932aSJim Ingham Error 371893c932aSJim Ingham TargetList::CreateTargetInternal (Debugger &debugger, 372a0ca6601SGreg Clayton const char *user_exe_path, 37370512317SGreg Clayton const ArchSpec& specified_arch, 37430fdc8d8SChris Lattner bool get_dependent_files, 375893c932aSJim Ingham lldb::PlatformSP &platform_sp, 376893c932aSJim Ingham lldb::TargetSP &target_sp, 377893c932aSJim Ingham bool is_dummy_target) 37830fdc8d8SChris Lattner { 379893c932aSJim Ingham 38030fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 381a0ca6601SGreg Clayton "TargetList::CreateTarget (file = '%s', arch = '%s')", 382a0ca6601SGreg Clayton user_exe_path, 38370512317SGreg Clayton specified_arch.GetArchitectureName()); 3845aee162fSJim Ingham Error error; 3855aee162fSJim Ingham 38670512317SGreg Clayton ArchSpec arch(specified_arch); 38770512317SGreg Clayton 38870512317SGreg Clayton if (arch.IsValid()) 38970512317SGreg Clayton { 390b0cc53cfSGreg Clayton if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 39170512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 39270512317SGreg Clayton } 39370512317SGreg Clayton 39470512317SGreg Clayton if (!platform_sp) 39570512317SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 396ded470d3SGreg Clayton 3978ae50eb4SGreg Clayton if (!arch.IsValid()) 3988ae50eb4SGreg Clayton arch = specified_arch; 3998ae50eb4SGreg Clayton 400d26206b5SJason Molenda FileSpec file (user_exe_path, false); 401d26206b5SJason Molenda if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 402d26206b5SJason Molenda { 4039f822cd1SMichael Sartain // we want to expand the tilde but we don't want to resolve any symbolic links 4049f822cd1SMichael Sartain // so we can't use the FileSpec constructor's resolve flag 4053f559740SZachary Turner llvm::SmallString<64> unglobbed_path(user_exe_path); 4063f559740SZachary Turner FileSpec::ResolveUsername(unglobbed_path); 4079f822cd1SMichael Sartain 4083f559740SZachary Turner if (unglobbed_path.empty()) 4093f559740SZachary Turner file = FileSpec(user_exe_path, false); 4103f559740SZachary Turner else 4113f559740SZachary Turner file = FileSpec(unglobbed_path.c_str(), false); 412d26206b5SJason Molenda } 4139f822cd1SMichael Sartain 41482d79295SGreg Clayton bool user_exe_path_is_bundle = false; 41582d79295SGreg Clayton char resolved_bundle_exe_path[PATH_MAX]; 41682d79295SGreg Clayton resolved_bundle_exe_path[0] = '\0'; 417e996fd30SGreg Clayton if (file) 4185aee162fSJim Ingham { 41982d79295SGreg Clayton if (file.GetFileType() == FileSpec::eFileTypeDirectory) 42082d79295SGreg Clayton user_exe_path_is_bundle = true; 42182d79295SGreg Clayton 42214468812SJason Molenda if (file.IsRelativeToCurrentWorkingDirectory() && user_exe_path) 423a0ca6601SGreg Clayton { 424a0ca6601SGreg Clayton // Ignore paths that start with "./" and "../" 425a0ca6601SGreg Clayton if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 426a0ca6601SGreg Clayton (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 427a0ca6601SGreg Clayton { 428a0ca6601SGreg Clayton char cwd[PATH_MAX]; 429a0ca6601SGreg Clayton if (getcwd (cwd, sizeof(cwd))) 430a0ca6601SGreg Clayton { 431a0ca6601SGreg Clayton std::string cwd_user_exe_path (cwd); 432a0ca6601SGreg Clayton cwd_user_exe_path += '/'; 433a0ca6601SGreg Clayton cwd_user_exe_path += user_exe_path; 4349ff5aae5SGreg Clayton FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 4359ff5aae5SGreg Clayton if (cwd_file.Exists()) 4369ff5aae5SGreg Clayton file = cwd_file; 437a0ca6601SGreg Clayton } 438a0ca6601SGreg Clayton } 439a0ca6601SGreg Clayton } 440a0ca6601SGreg Clayton 44130fdc8d8SChris Lattner ModuleSP exe_module_sp; 442e996fd30SGreg Clayton if (platform_sp) 443c859e2d5SGreg Clayton { 444c859e2d5SGreg Clayton FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 4458012cadbSGreg Clayton ModuleSpec module_spec(file, arch); 4468012cadbSGreg Clayton error = platform_sp->ResolveExecutable (module_spec, 447c859e2d5SGreg Clayton exe_module_sp, 448c859e2d5SGreg Clayton executable_search_paths.GetSize() ? &executable_search_paths : NULL); 449c859e2d5SGreg Clayton } 450428a9a58SCaroline Tice 451e996fd30SGreg Clayton if (error.Success() && exe_module_sp) 45230fdc8d8SChris Lattner { 4535aee162fSJim Ingham if (exe_module_sp->GetObjectFile() == NULL) 4545aee162fSJim Ingham { 455bc5cad6cSGreg Clayton if (arch.IsValid()) 456bc5cad6cSGreg Clayton { 457b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 458b5ad4ec7SGreg Clayton file.GetPath().c_str(), 45964195a2cSGreg Clayton arch.GetArchitectureName()); 460bc5cad6cSGreg Clayton } 461bc5cad6cSGreg Clayton else 462bc5cad6cSGreg Clayton { 463b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("unsupported file type \"%s\"", 464b5ad4ec7SGreg Clayton file.GetPath().c_str()); 465bc5cad6cSGreg Clayton } 4665aee162fSJim Ingham return error; 4675aee162fSJim Ingham } 468893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 46930fdc8d8SChris Lattner target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 47082d79295SGreg Clayton if (user_exe_path_is_bundle) 47182d79295SGreg Clayton exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 4725aee162fSJim Ingham } 4735aee162fSJim Ingham } 474e996fd30SGreg Clayton else 475e996fd30SGreg Clayton { 476e996fd30SGreg Clayton // No file was specified, just create an empty target with any arch 477e996fd30SGreg Clayton // if a valid arch was specified 478893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 479e996fd30SGreg Clayton } 4801559a46bSCaroline Tice 481e996fd30SGreg Clayton if (target_sp) 482e996fd30SGreg Clayton { 48382d79295SGreg Clayton // Set argv0 with what the user typed, unless the user specified a 48482d79295SGreg Clayton // directory. If the user specified a directory, then it is probably a 48582d79295SGreg Clayton // bundle that was resolved and we need to use the resolved bundle path 486a0ca6601SGreg Clayton if (user_exe_path) 487a0ca6601SGreg Clayton { 488a0ca6601SGreg Clayton // Use exactly what the user typed as the first argument when we exec or posix_spawn 48982d79295SGreg Clayton if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 49082d79295SGreg Clayton { 49182d79295SGreg Clayton target_sp->SetArg0 (resolved_bundle_exe_path); 49282d79295SGreg Clayton } 49382d79295SGreg Clayton else 49482d79295SGreg Clayton { 4959f822cd1SMichael Sartain // Use resolved path 4969f822cd1SMichael Sartain target_sp->SetArg0 (file.GetPath().c_str()); 497a0ca6601SGreg Clayton } 49882d79295SGreg Clayton } 499a0ca6601SGreg Clayton if (file.GetDirectory()) 500a0ca6601SGreg Clayton { 501a0ca6601SGreg Clayton FileSpec file_dir; 502a0ca6601SGreg Clayton file_dir.GetDirectory() = file.GetDirectory(); 503a0ca6601SGreg Clayton target_sp->GetExecutableSearchPaths ().Append (file_dir); 504a0ca6601SGreg Clayton } 505893c932aSJim Ingham 506893c932aSJim Ingham // Don't put the dummy target in the target list, it's held separately. 507893c932aSJim Ingham if (!is_dummy_target) 508893c932aSJim Ingham { 50930fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 5102976d00aSJim Ingham m_selected_target_idx = m_target_list.size(); 51130fdc8d8SChris Lattner m_target_list.push_back(target_sp); 51233df7cd3SJim Ingham // Now prime this from the dummy target: 51333df7cd3SJim Ingham target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); 514893c932aSJim Ingham } 515893c932aSJim Ingham else 516893c932aSJim Ingham { 517893c932aSJim Ingham m_dummy_target_sp = target_sp; 518893c932aSJim Ingham } 51930fdc8d8SChris Lattner } 52030fdc8d8SChris Lattner 52130fdc8d8SChris Lattner return error; 52230fdc8d8SChris Lattner } 52330fdc8d8SChris Lattner 52430fdc8d8SChris Lattner bool 52530fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp) 52630fdc8d8SChris Lattner { 52730fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 52830fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 52930fdc8d8SChris Lattner 53030fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 53130fdc8d8SChris Lattner { 53230fdc8d8SChris Lattner if (pos->get() == target_sp.get()) 53330fdc8d8SChris Lattner { 53430fdc8d8SChris Lattner m_target_list.erase(pos); 53530fdc8d8SChris Lattner return true; 53630fdc8d8SChris Lattner } 53730fdc8d8SChris Lattner } 53830fdc8d8SChris Lattner return false; 53930fdc8d8SChris Lattner } 54030fdc8d8SChris Lattner 54130fdc8d8SChris Lattner 54230fdc8d8SChris Lattner TargetSP 54330fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture 54430fdc8d8SChris Lattner ( 54530fdc8d8SChris Lattner const FileSpec &exe_file_spec, 54630fdc8d8SChris Lattner const ArchSpec *exe_arch_ptr 54730fdc8d8SChris Lattner ) const 54830fdc8d8SChris Lattner { 54930fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 55030fdc8d8SChris Lattner TargetSP target_sp; 551ddd7a2a6SSean Callanan bool full_match = (bool)exe_file_spec.GetDirectory(); 55230fdc8d8SChris Lattner 55330fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 55430fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 55530fdc8d8SChris Lattner { 556aa149cbdSGreg Clayton Module *exe_module = (*pos)->GetExecutableModulePointer(); 55730fdc8d8SChris Lattner 558aa149cbdSGreg Clayton if (exe_module) 55930fdc8d8SChris Lattner { 560aa149cbdSGreg Clayton if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 56130fdc8d8SChris Lattner { 56230fdc8d8SChris Lattner if (exe_arch_ptr) 56330fdc8d8SChris Lattner { 564bf4b7be6SSean Callanan if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 56530fdc8d8SChris Lattner continue; 56630fdc8d8SChris Lattner } 56730fdc8d8SChris Lattner target_sp = *pos; 56830fdc8d8SChris Lattner break; 56930fdc8d8SChris Lattner } 57030fdc8d8SChris Lattner } 57130fdc8d8SChris Lattner } 57230fdc8d8SChris Lattner return target_sp; 57330fdc8d8SChris Lattner } 57430fdc8d8SChris Lattner 57530fdc8d8SChris Lattner TargetSP 57630fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 57730fdc8d8SChris Lattner { 57830fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 57930fdc8d8SChris Lattner TargetSP target_sp; 58030fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 58130fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 58230fdc8d8SChris Lattner { 58330fdc8d8SChris Lattner Process* process = (*pos)->GetProcessSP().get(); 58430fdc8d8SChris Lattner if (process && process->GetID() == pid) 58530fdc8d8SChris Lattner { 58630fdc8d8SChris Lattner target_sp = *pos; 58730fdc8d8SChris Lattner break; 58830fdc8d8SChris Lattner } 58930fdc8d8SChris Lattner } 59030fdc8d8SChris Lattner return target_sp; 59130fdc8d8SChris Lattner } 59230fdc8d8SChris Lattner 59330fdc8d8SChris Lattner 59430fdc8d8SChris Lattner TargetSP 59530fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const 59630fdc8d8SChris Lattner { 59730fdc8d8SChris Lattner TargetSP target_sp; 59830fdc8d8SChris Lattner if (process) 59930fdc8d8SChris Lattner { 60030fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 60130fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 60230fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 60330fdc8d8SChris Lattner { 60430fdc8d8SChris Lattner if (process == (*pos)->GetProcessSP().get()) 60530fdc8d8SChris Lattner { 60630fdc8d8SChris Lattner target_sp = *pos; 60730fdc8d8SChris Lattner break; 60830fdc8d8SChris Lattner } 60930fdc8d8SChris Lattner } 61030fdc8d8SChris Lattner } 61130fdc8d8SChris Lattner return target_sp; 61230fdc8d8SChris Lattner } 61330fdc8d8SChris Lattner 61430fdc8d8SChris Lattner TargetSP 61530fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const 61630fdc8d8SChris Lattner { 61730fdc8d8SChris Lattner TargetSP target_sp; 61830fdc8d8SChris Lattner if (target) 61930fdc8d8SChris Lattner { 62030fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 62130fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 62230fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 62330fdc8d8SChris Lattner { 62430fdc8d8SChris Lattner if (target == (*pos).get()) 62530fdc8d8SChris Lattner { 62630fdc8d8SChris Lattner target_sp = *pos; 62730fdc8d8SChris Lattner break; 62830fdc8d8SChris Lattner } 62930fdc8d8SChris Lattner } 63030fdc8d8SChris Lattner } 63130fdc8d8SChris Lattner return target_sp; 63230fdc8d8SChris Lattner } 63330fdc8d8SChris Lattner 63430fdc8d8SChris Lattner uint32_t 63530fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid) 63630fdc8d8SChris Lattner { 63730fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 63830fdc8d8SChris Lattner 63930fdc8d8SChris Lattner if (pid != LLDB_INVALID_PROCESS_ID) 64030fdc8d8SChris Lattner { 64130fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 64230fdc8d8SChris Lattner if (target_sp.get()) 64330fdc8d8SChris Lattner { 64430fdc8d8SChris Lattner Process* process = target_sp->GetProcessSP().get(); 64530fdc8d8SChris Lattner if (process) 64630fdc8d8SChris Lattner { 647cfc0935eSJim Ingham process->SendAsyncInterrupt(); 64830fdc8d8SChris Lattner ++num_async_interrupts_sent; 64930fdc8d8SChris Lattner } 65030fdc8d8SChris Lattner } 65130fdc8d8SChris Lattner } 65230fdc8d8SChris Lattner else 65330fdc8d8SChris Lattner { 65430fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 65530fdc8d8SChris Lattner // list's async broadcaster... 65630fdc8d8SChris Lattner BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 65730fdc8d8SChris Lattner } 65830fdc8d8SChris Lattner 65930fdc8d8SChris Lattner return num_async_interrupts_sent; 66030fdc8d8SChris Lattner } 66130fdc8d8SChris Lattner 66230fdc8d8SChris Lattner uint32_t 66330fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 66430fdc8d8SChris Lattner { 66530fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 66630fdc8d8SChris Lattner Process *process = NULL; 66730fdc8d8SChris Lattner if (pid == LLDB_INVALID_PROCESS_ID) 66830fdc8d8SChris Lattner { 66930fdc8d8SChris Lattner // Signal all processes with signal 67030fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 67130fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 67230fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 67330fdc8d8SChris Lattner { 67430fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 67530fdc8d8SChris Lattner if (process) 67630fdc8d8SChris Lattner { 67730fdc8d8SChris Lattner if (process->IsAlive()) 67830fdc8d8SChris Lattner { 67930fdc8d8SChris Lattner ++num_signals_sent; 68030fdc8d8SChris Lattner process->Signal (signo); 68130fdc8d8SChris Lattner } 68230fdc8d8SChris Lattner } 68330fdc8d8SChris Lattner } 68430fdc8d8SChris Lattner } 68530fdc8d8SChris Lattner else 68630fdc8d8SChris Lattner { 68730fdc8d8SChris Lattner // Signal a specific process with signal 68830fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 68930fdc8d8SChris Lattner if (target_sp.get()) 69030fdc8d8SChris Lattner { 69130fdc8d8SChris Lattner process = target_sp->GetProcessSP().get(); 69230fdc8d8SChris Lattner if (process) 69330fdc8d8SChris Lattner { 69430fdc8d8SChris Lattner if (process->IsAlive()) 69530fdc8d8SChris Lattner { 69630fdc8d8SChris Lattner ++num_signals_sent; 69730fdc8d8SChris Lattner process->Signal (signo); 69830fdc8d8SChris Lattner } 69930fdc8d8SChris Lattner } 70030fdc8d8SChris Lattner } 70130fdc8d8SChris Lattner } 70230fdc8d8SChris Lattner return num_signals_sent; 70330fdc8d8SChris Lattner } 70430fdc8d8SChris Lattner 70530fdc8d8SChris Lattner int 70630fdc8d8SChris Lattner TargetList::GetNumTargets () const 70730fdc8d8SChris Lattner { 70830fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 70930fdc8d8SChris Lattner return m_target_list.size(); 71030fdc8d8SChris Lattner } 71130fdc8d8SChris Lattner 71230fdc8d8SChris Lattner lldb::TargetSP 71330fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const 71430fdc8d8SChris Lattner { 71530fdc8d8SChris Lattner TargetSP target_sp; 71630fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 71730fdc8d8SChris Lattner if (idx < m_target_list.size()) 71830fdc8d8SChris Lattner target_sp = m_target_list[idx]; 71930fdc8d8SChris Lattner return target_sp; 72030fdc8d8SChris Lattner } 72130fdc8d8SChris Lattner 72230fdc8d8SChris Lattner uint32_t 7238499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 7248499e1a4SJim Ingham { 7258499e1a4SJim Ingham Mutex::Locker locker (m_target_list_mutex); 7268499e1a4SJim Ingham size_t num_targets = m_target_list.size(); 7278499e1a4SJim Ingham for (size_t idx = 0; idx < num_targets; idx++) 7288499e1a4SJim Ingham { 7298499e1a4SJim Ingham if (target_sp == m_target_list[idx]) 7308499e1a4SJim Ingham return idx; 7318499e1a4SJim Ingham } 7328499e1a4SJim Ingham return UINT32_MAX; 7338499e1a4SJim Ingham } 7348499e1a4SJim Ingham 7358499e1a4SJim Ingham uint32_t 7362976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target) 73730fdc8d8SChris Lattner { 73830fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 73930fdc8d8SChris Lattner collection::const_iterator pos, 74030fdc8d8SChris Lattner begin = m_target_list.begin(), 74130fdc8d8SChris Lattner end = m_target_list.end(); 74230fdc8d8SChris Lattner for (pos = begin; pos != end; ++pos) 74330fdc8d8SChris Lattner { 74430fdc8d8SChris Lattner if (pos->get() == target) 74530fdc8d8SChris Lattner { 7462976d00aSJim Ingham m_selected_target_idx = std::distance (begin, pos); 7472976d00aSJim Ingham return m_selected_target_idx; 74830fdc8d8SChris Lattner } 74930fdc8d8SChris Lattner } 7502976d00aSJim Ingham m_selected_target_idx = 0; 7512976d00aSJim Ingham return m_selected_target_idx; 75230fdc8d8SChris Lattner } 75330fdc8d8SChris Lattner 75430fdc8d8SChris Lattner lldb::TargetSP 7552976d00aSJim Ingham TargetList::GetSelectedTarget () 75630fdc8d8SChris Lattner { 75730fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 7582976d00aSJim Ingham if (m_selected_target_idx >= m_target_list.size()) 7592976d00aSJim Ingham m_selected_target_idx = 0; 7602976d00aSJim Ingham return GetTargetAtIndex (m_selected_target_idx); 76130fdc8d8SChris Lattner } 762