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 13*e65b2cf2SEugene Zelenko #include "llvm/ADT/SmallString.h" 14*e65b2cf2SEugene Zelenko 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 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 { 1827df337f8STodd Fiala StreamString platform_arch_strm; 1837df337f8STodd Fiala StreamString module_arch_strm; 1847df337f8STodd Fiala 1857df337f8STodd Fiala platform_arch.DumpTriple(platform_arch_strm); 1867df337f8STodd Fiala matching_module_spec.GetArchitecture().DumpTriple(module_arch_strm); 187b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 1887df337f8STodd Fiala platform_arch_strm.GetString().c_str(), 1897df337f8STodd Fiala module_arch_strm.GetString().c_str(), 190b5ad4ec7SGreg Clayton module_spec.GetFileSpec().GetPath().c_str()); 191f4d6de6aSGreg Clayton return error; 192f4d6de6aSGreg Clayton } 193f4d6de6aSGreg Clayton } 194f4d6de6aSGreg Clayton else 195f4d6de6aSGreg Clayton { 196f4d6de6aSGreg Clayton // Only one arch and none was specified 1973f19ada8SGreg Clayton prefer_platform_arch = true; 198f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 199f4d6de6aSGreg Clayton } 200f4d6de6aSGreg Clayton } 201f4d6de6aSGreg Clayton } 202f4d6de6aSGreg Clayton else 203f4d6de6aSGreg Clayton { 204f4d6de6aSGreg Clayton if (arch.IsValid()) 205f4d6de6aSGreg Clayton { 206f4d6de6aSGreg Clayton module_spec.GetArchitecture() = arch; 207f4d6de6aSGreg Clayton if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 208f4d6de6aSGreg Clayton { 2093f19ada8SGreg Clayton prefer_platform_arch = true; 210f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 211f4d6de6aSGreg Clayton } 212f4d6de6aSGreg Clayton } 213b0cc53cfSGreg Clayton else 214b0cc53cfSGreg Clayton { 215b0cc53cfSGreg Clayton // No architecture specified, check if there is only one platform for 216b0cc53cfSGreg Clayton // all of the architectures. 217b0cc53cfSGreg Clayton 218b0cc53cfSGreg Clayton typedef std::vector<PlatformSP> PlatformList; 219b0cc53cfSGreg Clayton PlatformList platforms; 220615eb7e6SGreg Clayton PlatformSP host_platform_sp = Platform::GetHostPlatform(); 221b0cc53cfSGreg Clayton for (size_t i=0; i<num_specs; ++i) 222b0cc53cfSGreg Clayton { 223b0cc53cfSGreg Clayton ModuleSpec module_spec; 224b0cc53cfSGreg Clayton if (module_specs.GetModuleSpecAtIndex(i, module_spec)) 225b0cc53cfSGreg Clayton { 226b0cc53cfSGreg Clayton // See if there was a selected platform and check that first 227b0cc53cfSGreg Clayton // since the user may have specified it. 228b0cc53cfSGreg Clayton if (platform_sp) 229b0cc53cfSGreg Clayton { 230*e65b2cf2SEugene Zelenko if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, nullptr)) 231b0cc53cfSGreg Clayton { 232b0cc53cfSGreg Clayton platforms.push_back(platform_sp); 233b0cc53cfSGreg Clayton continue; 234f4d6de6aSGreg Clayton } 235f4d6de6aSGreg Clayton } 236f4d6de6aSGreg Clayton 237b0cc53cfSGreg Clayton // Next check the host platform it if wasn't already checked above 238b0cc53cfSGreg Clayton if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName())) 239b3a40ba8SGreg Clayton { 240*e65b2cf2SEugene Zelenko if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, nullptr)) 241b3a40ba8SGreg Clayton { 242b0cc53cfSGreg Clayton platforms.push_back(host_platform_sp); 243b0cc53cfSGreg Clayton continue; 244b0cc53cfSGreg Clayton } 245b0cc53cfSGreg Clayton } 246b0cc53cfSGreg Clayton 247b0cc53cfSGreg Clayton // Just find a platform that matches the architecture in the executable file 248e92a74ceSJason Molenda PlatformSP fallback_platform_sp (Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr)); 249e92a74ceSJason Molenda if (fallback_platform_sp) 250e92a74ceSJason Molenda { 251e92a74ceSJason Molenda platforms.push_back(fallback_platform_sp); 252e92a74ceSJason Molenda } 253b0cc53cfSGreg Clayton } 254b0cc53cfSGreg Clayton } 255b0cc53cfSGreg Clayton 256*e65b2cf2SEugene Zelenko Platform *platform_ptr = nullptr; 2579d58c728SJason Molenda bool more_than_one_platforms = false; 258b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 259b0cc53cfSGreg Clayton { 260b0cc53cfSGreg Clayton if (platform_ptr) 261b0cc53cfSGreg Clayton { 262b0cc53cfSGreg Clayton if (platform_ptr->GetName() != the_platform_sp->GetName()) 263b0cc53cfSGreg Clayton { 2649d58c728SJason Molenda more_than_one_platforms = true; 265*e65b2cf2SEugene Zelenko platform_ptr = nullptr; 266b0cc53cfSGreg Clayton break; 267b0cc53cfSGreg Clayton } 268b0cc53cfSGreg Clayton } 269b0cc53cfSGreg Clayton else 270b0cc53cfSGreg Clayton { 271b0cc53cfSGreg Clayton platform_ptr = the_platform_sp.get(); 272b0cc53cfSGreg Clayton } 273b0cc53cfSGreg Clayton } 274b0cc53cfSGreg Clayton 275b0cc53cfSGreg Clayton if (platform_ptr) 276b0cc53cfSGreg Clayton { 277b0cc53cfSGreg Clayton // All platforms for all modules in the exectuable match, so we can select this platform 278b0cc53cfSGreg Clayton platform_sp = platforms.front(); 279b0cc53cfSGreg Clayton } 2809d58c728SJason Molenda else if (more_than_one_platforms == false) 2819d58c728SJason Molenda { 2829d58c728SJason Molenda // No platforms claim to support this file 2839d58c728SJason Molenda error.SetErrorString ("No matching platforms found for this file, specify one with the --platform option"); 2849d58c728SJason Molenda return error; 2859d58c728SJason Molenda } 286b0cc53cfSGreg Clayton else 287b0cc53cfSGreg Clayton { 288b0cc53cfSGreg Clayton // More than one platform claims to support this file, so the --platform option must be specified 289b0cc53cfSGreg Clayton StreamString error_strm; 290b0cc53cfSGreg Clayton std::set<Platform *> platform_set; 291b0cc53cfSGreg Clayton error_strm.Printf ("more than one platform supports this executable ("); 292b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 293b0cc53cfSGreg Clayton { 294b0cc53cfSGreg Clayton if (platform_set.find(the_platform_sp.get()) == platform_set.end()) 295b0cc53cfSGreg Clayton { 296b0cc53cfSGreg Clayton if (!platform_set.empty()) 297b0cc53cfSGreg Clayton error_strm.PutCString(", "); 298b0cc53cfSGreg Clayton error_strm.PutCString(the_platform_sp->GetName().GetCString()); 299b0cc53cfSGreg Clayton platform_set.insert(the_platform_sp.get()); 300b0cc53cfSGreg Clayton } 301b0cc53cfSGreg Clayton } 302b0cc53cfSGreg Clayton error_strm.Printf("), use the --platform option to specify a platform"); 303b0cc53cfSGreg Clayton error.SetErrorString(error_strm.GetString().c_str()); 304b3a40ba8SGreg Clayton return error; 305b3a40ba8SGreg Clayton } 306b3a40ba8SGreg Clayton } 307b0cc53cfSGreg Clayton } 308b0cc53cfSGreg Clayton } 309b0cc53cfSGreg Clayton } 310b3a40ba8SGreg Clayton 311869e0c1cSTed Woodward // If we have a valid architecture, make sure the current platform is 312869e0c1cSTed Woodward // compatible with that architecture 3133f19ada8SGreg Clayton if (!prefer_platform_arch && arch.IsValid()) 314b3a40ba8SGreg Clayton { 3153f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 31695bbdf64SGreg Clayton { 31770512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 3188ec55a53SRobert Flack if (!is_dummy_target && platform_sp) 31995bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 32095bbdf64SGreg Clayton } 321b3a40ba8SGreg Clayton } 3223f19ada8SGreg Clayton else if (platform_arch.IsValid()) 3233f19ada8SGreg Clayton { 3243f19ada8SGreg Clayton // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with 3253f19ada8SGreg Clayton // a single architecture which should be used 3263f19ada8SGreg Clayton ArchSpec fixed_platform_arch; 3273f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) 32895bbdf64SGreg Clayton { 3293f19ada8SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); 3308ec55a53SRobert Flack if (!is_dummy_target && platform_sp) 33195bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 33295bbdf64SGreg Clayton } 3333f19ada8SGreg Clayton } 334b3a40ba8SGreg Clayton 33570512317SGreg Clayton if (!platform_arch.IsValid()) 33670512317SGreg Clayton platform_arch = arch; 33770512317SGreg Clayton 338893c932aSJim Ingham error = TargetList::CreateTargetInternal (debugger, 339a0ca6601SGreg Clayton user_exe_path, 34070512317SGreg Clayton platform_arch, 341cac9c5f9SGreg Clayton get_dependent_files, 342cac9c5f9SGreg Clayton platform_sp, 343893c932aSJim Ingham target_sp, 344893c932aSJim Ingham is_dummy_target); 345cac9c5f9SGreg Clayton return error; 346cac9c5f9SGreg Clayton } 347cac9c5f9SGreg Clayton 348893c932aSJim Ingham lldb::TargetSP 349893c932aSJim Ingham TargetList::GetDummyTarget (lldb_private::Debugger &debugger) 350893c932aSJim Ingham { 351893c932aSJim Ingham // FIXME: Maybe the dummy target should be per-Debugger 352893c932aSJim Ingham if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) 353893c932aSJim Ingham { 354893c932aSJim Ingham ArchSpec arch(Target::GetDefaultArchitecture()); 355893c932aSJim Ingham if (!arch.IsValid()) 356893c932aSJim Ingham arch = HostInfo::GetArchitecture(); 357893c932aSJim Ingham Error err = CreateDummyTarget(debugger, 358893c932aSJim Ingham arch.GetTriple().getTriple().c_str(), 359893c932aSJim Ingham m_dummy_target_sp); 360893c932aSJim Ingham } 361893c932aSJim Ingham 362893c932aSJim Ingham return m_dummy_target_sp; 363893c932aSJim Ingham } 364893c932aSJim Ingham 365cac9c5f9SGreg Clayton Error 366893c932aSJim Ingham TargetList::CreateDummyTarget (Debugger &debugger, 367893c932aSJim Ingham const char *specified_arch_name, 368893c932aSJim Ingham lldb::TargetSP &target_sp) 369893c932aSJim Ingham { 370893c932aSJim Ingham PlatformSP host_platform_sp(Platform::GetHostPlatform()); 371893c932aSJim Ingham return CreateTargetInternal (debugger, 372893c932aSJim Ingham (const char *) nullptr, 373893c932aSJim Ingham specified_arch_name, 374893c932aSJim Ingham false, 375893c932aSJim Ingham (const OptionGroupPlatform *) nullptr, 376893c932aSJim Ingham target_sp, 377893c932aSJim Ingham true); 378893c932aSJim Ingham } 379893c932aSJim Ingham 380893c932aSJim Ingham Error 381893c932aSJim Ingham TargetList::CreateTargetInternal (Debugger &debugger, 382a0ca6601SGreg Clayton const char *user_exe_path, 38370512317SGreg Clayton const ArchSpec& specified_arch, 38430fdc8d8SChris Lattner bool get_dependent_files, 385893c932aSJim Ingham lldb::PlatformSP &platform_sp, 386893c932aSJim Ingham lldb::TargetSP &target_sp, 387893c932aSJim Ingham bool is_dummy_target) 38830fdc8d8SChris Lattner { 38930fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 390a0ca6601SGreg Clayton "TargetList::CreateTarget (file = '%s', arch = '%s')", 391a0ca6601SGreg Clayton user_exe_path, 39270512317SGreg Clayton specified_arch.GetArchitectureName()); 3935aee162fSJim Ingham Error error; 3945aee162fSJim Ingham 39570512317SGreg Clayton ArchSpec arch(specified_arch); 39670512317SGreg Clayton 39770512317SGreg Clayton if (arch.IsValid()) 39870512317SGreg Clayton { 399*e65b2cf2SEugene Zelenko if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) 40070512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 40170512317SGreg Clayton } 40270512317SGreg Clayton 40370512317SGreg Clayton if (!platform_sp) 40470512317SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 405ded470d3SGreg Clayton 4068ae50eb4SGreg Clayton if (!arch.IsValid()) 4078ae50eb4SGreg Clayton arch = specified_arch; 4088ae50eb4SGreg Clayton 409d26206b5SJason Molenda FileSpec file (user_exe_path, false); 410d26206b5SJason Molenda if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 411d26206b5SJason Molenda { 4129f822cd1SMichael Sartain // we want to expand the tilde but we don't want to resolve any symbolic links 4139f822cd1SMichael Sartain // so we can't use the FileSpec constructor's resolve flag 4143f559740SZachary Turner llvm::SmallString<64> unglobbed_path(user_exe_path); 4153f559740SZachary Turner FileSpec::ResolveUsername(unglobbed_path); 4169f822cd1SMichael Sartain 4173f559740SZachary Turner if (unglobbed_path.empty()) 4183f559740SZachary Turner file = FileSpec(user_exe_path, false); 4193f559740SZachary Turner else 4203f559740SZachary Turner file = FileSpec(unglobbed_path.c_str(), false); 421d26206b5SJason Molenda } 4229f822cd1SMichael Sartain 42382d79295SGreg Clayton bool user_exe_path_is_bundle = false; 42482d79295SGreg Clayton char resolved_bundle_exe_path[PATH_MAX]; 42582d79295SGreg Clayton resolved_bundle_exe_path[0] = '\0'; 426e996fd30SGreg Clayton if (file) 4275aee162fSJim Ingham { 42882d79295SGreg Clayton if (file.GetFileType() == FileSpec::eFileTypeDirectory) 42982d79295SGreg Clayton user_exe_path_is_bundle = true; 43082d79295SGreg Clayton 431372e9067SChaoren Lin if (file.IsRelative() && user_exe_path) 432a0ca6601SGreg Clayton { 433a0ca6601SGreg Clayton // Ignore paths that start with "./" and "../" 434a0ca6601SGreg Clayton if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 435a0ca6601SGreg Clayton (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 436a0ca6601SGreg Clayton { 437a0ca6601SGreg Clayton char cwd[PATH_MAX]; 438a0ca6601SGreg Clayton if (getcwd (cwd, sizeof(cwd))) 439a0ca6601SGreg Clayton { 440a0ca6601SGreg Clayton std::string cwd_user_exe_path (cwd); 441a0ca6601SGreg Clayton cwd_user_exe_path += '/'; 442a0ca6601SGreg Clayton cwd_user_exe_path += user_exe_path; 4439ff5aae5SGreg Clayton FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 4449ff5aae5SGreg Clayton if (cwd_file.Exists()) 4459ff5aae5SGreg Clayton file = cwd_file; 446a0ca6601SGreg Clayton } 447a0ca6601SGreg Clayton } 448a0ca6601SGreg Clayton } 449a0ca6601SGreg Clayton 45030fdc8d8SChris Lattner ModuleSP exe_module_sp; 451e996fd30SGreg Clayton if (platform_sp) 452c859e2d5SGreg Clayton { 453c859e2d5SGreg Clayton FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 4548012cadbSGreg Clayton ModuleSpec module_spec(file, arch); 4558012cadbSGreg Clayton error = platform_sp->ResolveExecutable(module_spec, 456c859e2d5SGreg Clayton exe_module_sp, 457*e65b2cf2SEugene Zelenko executable_search_paths.GetSize() ? &executable_search_paths : nullptr); 458c859e2d5SGreg Clayton } 459428a9a58SCaroline Tice 460e996fd30SGreg Clayton if (error.Success() && exe_module_sp) 46130fdc8d8SChris Lattner { 462*e65b2cf2SEugene Zelenko if (exe_module_sp->GetObjectFile() == nullptr) 4635aee162fSJim Ingham { 464bc5cad6cSGreg Clayton if (arch.IsValid()) 465bc5cad6cSGreg Clayton { 466b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 467b5ad4ec7SGreg Clayton file.GetPath().c_str(), 46864195a2cSGreg Clayton arch.GetArchitectureName()); 469bc5cad6cSGreg Clayton } 470bc5cad6cSGreg Clayton else 471bc5cad6cSGreg Clayton { 472b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("unsupported file type \"%s\"", 473b5ad4ec7SGreg Clayton file.GetPath().c_str()); 474bc5cad6cSGreg Clayton } 4755aee162fSJim Ingham return error; 4765aee162fSJim Ingham } 477893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 47830fdc8d8SChris Lattner target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 47982d79295SGreg Clayton if (user_exe_path_is_bundle) 48082d79295SGreg Clayton exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 4815aee162fSJim Ingham } 4825aee162fSJim Ingham } 483e996fd30SGreg Clayton else 484e996fd30SGreg Clayton { 485e996fd30SGreg Clayton // No file was specified, just create an empty target with any arch 486e996fd30SGreg Clayton // if a valid arch was specified 487893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 488e996fd30SGreg Clayton } 4891559a46bSCaroline Tice 490e996fd30SGreg Clayton if (target_sp) 491e996fd30SGreg Clayton { 49282d79295SGreg Clayton // Set argv0 with what the user typed, unless the user specified a 49382d79295SGreg Clayton // directory. If the user specified a directory, then it is probably a 49482d79295SGreg Clayton // bundle that was resolved and we need to use the resolved bundle path 495a0ca6601SGreg Clayton if (user_exe_path) 496a0ca6601SGreg Clayton { 497a0ca6601SGreg Clayton // Use exactly what the user typed as the first argument when we exec or posix_spawn 49882d79295SGreg Clayton if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 49982d79295SGreg Clayton { 50082d79295SGreg Clayton target_sp->SetArg0 (resolved_bundle_exe_path); 50182d79295SGreg Clayton } 50282d79295SGreg Clayton else 50382d79295SGreg Clayton { 5049f822cd1SMichael Sartain // Use resolved path 5059f822cd1SMichael Sartain target_sp->SetArg0 (file.GetPath().c_str()); 506a0ca6601SGreg Clayton } 50782d79295SGreg Clayton } 508a0ca6601SGreg Clayton if (file.GetDirectory()) 509a0ca6601SGreg Clayton { 510a0ca6601SGreg Clayton FileSpec file_dir; 511a0ca6601SGreg Clayton file_dir.GetDirectory() = file.GetDirectory(); 512a0ca6601SGreg Clayton target_sp->GetExecutableSearchPaths ().Append (file_dir); 513a0ca6601SGreg Clayton } 514893c932aSJim Ingham 515893c932aSJim Ingham // Don't put the dummy target in the target list, it's held separately. 516893c932aSJim Ingham if (!is_dummy_target) 517893c932aSJim Ingham { 51830fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 5192976d00aSJim Ingham m_selected_target_idx = m_target_list.size(); 52030fdc8d8SChris Lattner m_target_list.push_back(target_sp); 52133df7cd3SJim Ingham // Now prime this from the dummy target: 52233df7cd3SJim Ingham target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); 523893c932aSJim Ingham } 524893c932aSJim Ingham else 525893c932aSJim Ingham { 526893c932aSJim Ingham m_dummy_target_sp = target_sp; 527893c932aSJim Ingham } 52830fdc8d8SChris Lattner } 52930fdc8d8SChris Lattner 53030fdc8d8SChris Lattner return error; 53130fdc8d8SChris Lattner } 53230fdc8d8SChris Lattner 53330fdc8d8SChris Lattner bool 53430fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp) 53530fdc8d8SChris Lattner { 53630fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 53730fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 53830fdc8d8SChris Lattner 53930fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 54030fdc8d8SChris Lattner { 54130fdc8d8SChris Lattner if (pos->get() == target_sp.get()) 54230fdc8d8SChris Lattner { 54330fdc8d8SChris Lattner m_target_list.erase(pos); 54430fdc8d8SChris Lattner return true; 54530fdc8d8SChris Lattner } 54630fdc8d8SChris Lattner } 54730fdc8d8SChris Lattner return false; 54830fdc8d8SChris Lattner } 54930fdc8d8SChris Lattner 55030fdc8d8SChris Lattner TargetSP 551*e65b2cf2SEugene Zelenko TargetList::FindTargetWithExecutableAndArchitecture(const FileSpec &exe_file_spec, 552*e65b2cf2SEugene Zelenko const ArchSpec *exe_arch_ptr) const 55330fdc8d8SChris Lattner { 55430fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 55530fdc8d8SChris Lattner TargetSP target_sp; 556ddd7a2a6SSean Callanan bool full_match = (bool)exe_file_spec.GetDirectory(); 55730fdc8d8SChris Lattner 55830fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 55930fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 56030fdc8d8SChris Lattner { 561aa149cbdSGreg Clayton Module *exe_module = (*pos)->GetExecutableModulePointer(); 56230fdc8d8SChris Lattner 563aa149cbdSGreg Clayton if (exe_module) 56430fdc8d8SChris Lattner { 565aa149cbdSGreg Clayton if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 56630fdc8d8SChris Lattner { 56730fdc8d8SChris Lattner if (exe_arch_ptr) 56830fdc8d8SChris Lattner { 569bf4b7be6SSean Callanan if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 57030fdc8d8SChris Lattner continue; 57130fdc8d8SChris Lattner } 57230fdc8d8SChris Lattner target_sp = *pos; 57330fdc8d8SChris Lattner break; 57430fdc8d8SChris Lattner } 57530fdc8d8SChris Lattner } 57630fdc8d8SChris Lattner } 57730fdc8d8SChris Lattner return target_sp; 57830fdc8d8SChris Lattner } 57930fdc8d8SChris Lattner 58030fdc8d8SChris Lattner TargetSP 58130fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 58230fdc8d8SChris Lattner { 58330fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 58430fdc8d8SChris Lattner TargetSP target_sp; 58530fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 58630fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 58730fdc8d8SChris Lattner { 58830fdc8d8SChris Lattner Process* process = (*pos)->GetProcessSP().get(); 58930fdc8d8SChris Lattner if (process && process->GetID() == pid) 59030fdc8d8SChris Lattner { 59130fdc8d8SChris Lattner target_sp = *pos; 59230fdc8d8SChris Lattner break; 59330fdc8d8SChris Lattner } 59430fdc8d8SChris Lattner } 59530fdc8d8SChris Lattner return target_sp; 59630fdc8d8SChris Lattner } 59730fdc8d8SChris Lattner 59830fdc8d8SChris Lattner TargetSP 59930fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const 60030fdc8d8SChris Lattner { 60130fdc8d8SChris Lattner TargetSP target_sp; 60230fdc8d8SChris Lattner if (process) 60330fdc8d8SChris Lattner { 60430fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 60530fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 60630fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 60730fdc8d8SChris Lattner { 60830fdc8d8SChris Lattner if (process == (*pos)->GetProcessSP().get()) 60930fdc8d8SChris Lattner { 61030fdc8d8SChris Lattner target_sp = *pos; 61130fdc8d8SChris Lattner break; 61230fdc8d8SChris Lattner } 61330fdc8d8SChris Lattner } 61430fdc8d8SChris Lattner } 61530fdc8d8SChris Lattner return target_sp; 61630fdc8d8SChris Lattner } 61730fdc8d8SChris Lattner 61830fdc8d8SChris Lattner TargetSP 61930fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const 62030fdc8d8SChris Lattner { 62130fdc8d8SChris Lattner TargetSP target_sp; 62230fdc8d8SChris Lattner if (target) 62330fdc8d8SChris Lattner { 62430fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 62530fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 62630fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 62730fdc8d8SChris Lattner { 62830fdc8d8SChris Lattner if (target == (*pos).get()) 62930fdc8d8SChris Lattner { 63030fdc8d8SChris Lattner target_sp = *pos; 63130fdc8d8SChris Lattner break; 63230fdc8d8SChris Lattner } 63330fdc8d8SChris Lattner } 63430fdc8d8SChris Lattner } 63530fdc8d8SChris Lattner return target_sp; 63630fdc8d8SChris Lattner } 63730fdc8d8SChris Lattner 63830fdc8d8SChris Lattner uint32_t 63930fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid) 64030fdc8d8SChris Lattner { 64130fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 64230fdc8d8SChris Lattner 64330fdc8d8SChris Lattner if (pid != LLDB_INVALID_PROCESS_ID) 64430fdc8d8SChris Lattner { 64530fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 646*e65b2cf2SEugene Zelenko if (target_sp) 64730fdc8d8SChris Lattner { 64830fdc8d8SChris Lattner Process* process = target_sp->GetProcessSP().get(); 64930fdc8d8SChris Lattner if (process) 65030fdc8d8SChris Lattner { 651cfc0935eSJim Ingham process->SendAsyncInterrupt(); 65230fdc8d8SChris Lattner ++num_async_interrupts_sent; 65330fdc8d8SChris Lattner } 65430fdc8d8SChris Lattner } 65530fdc8d8SChris Lattner } 65630fdc8d8SChris Lattner else 65730fdc8d8SChris Lattner { 65830fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 65930fdc8d8SChris Lattner // list's async broadcaster... 660*e65b2cf2SEugene Zelenko BroadcastEvent(Process::eBroadcastBitInterrupt, nullptr); 66130fdc8d8SChris Lattner } 66230fdc8d8SChris Lattner 66330fdc8d8SChris Lattner return num_async_interrupts_sent; 66430fdc8d8SChris Lattner } 66530fdc8d8SChris Lattner 66630fdc8d8SChris Lattner uint32_t 66730fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 66830fdc8d8SChris Lattner { 66930fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 670*e65b2cf2SEugene Zelenko Process *process = nullptr; 67130fdc8d8SChris Lattner if (pid == LLDB_INVALID_PROCESS_ID) 67230fdc8d8SChris Lattner { 67330fdc8d8SChris Lattner // Signal all processes with signal 67430fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 67530fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 67630fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 67730fdc8d8SChris Lattner { 67830fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 67930fdc8d8SChris Lattner if (process) 68030fdc8d8SChris Lattner { 68130fdc8d8SChris Lattner if (process->IsAlive()) 68230fdc8d8SChris Lattner { 68330fdc8d8SChris Lattner ++num_signals_sent; 68430fdc8d8SChris Lattner process->Signal (signo); 68530fdc8d8SChris Lattner } 68630fdc8d8SChris Lattner } 68730fdc8d8SChris Lattner } 68830fdc8d8SChris Lattner } 68930fdc8d8SChris Lattner else 69030fdc8d8SChris Lattner { 69130fdc8d8SChris Lattner // Signal a specific process with signal 69230fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 693*e65b2cf2SEugene Zelenko if (target_sp) 69430fdc8d8SChris Lattner { 69530fdc8d8SChris Lattner process = target_sp->GetProcessSP().get(); 69630fdc8d8SChris Lattner if (process) 69730fdc8d8SChris Lattner { 69830fdc8d8SChris Lattner if (process->IsAlive()) 69930fdc8d8SChris Lattner { 70030fdc8d8SChris Lattner ++num_signals_sent; 70130fdc8d8SChris Lattner process->Signal (signo); 70230fdc8d8SChris Lattner } 70330fdc8d8SChris Lattner } 70430fdc8d8SChris Lattner } 70530fdc8d8SChris Lattner } 70630fdc8d8SChris Lattner return num_signals_sent; 70730fdc8d8SChris Lattner } 70830fdc8d8SChris Lattner 70930fdc8d8SChris Lattner int 71030fdc8d8SChris Lattner TargetList::GetNumTargets () const 71130fdc8d8SChris Lattner { 71230fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 71330fdc8d8SChris Lattner return m_target_list.size(); 71430fdc8d8SChris Lattner } 71530fdc8d8SChris Lattner 71630fdc8d8SChris Lattner lldb::TargetSP 71730fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const 71830fdc8d8SChris Lattner { 71930fdc8d8SChris Lattner TargetSP target_sp; 72030fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 72130fdc8d8SChris Lattner if (idx < m_target_list.size()) 72230fdc8d8SChris Lattner target_sp = m_target_list[idx]; 72330fdc8d8SChris Lattner return target_sp; 72430fdc8d8SChris Lattner } 72530fdc8d8SChris Lattner 72630fdc8d8SChris Lattner uint32_t 7278499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 7288499e1a4SJim Ingham { 7298499e1a4SJim Ingham Mutex::Locker locker (m_target_list_mutex); 7308499e1a4SJim Ingham size_t num_targets = m_target_list.size(); 7318499e1a4SJim Ingham for (size_t idx = 0; idx < num_targets; idx++) 7328499e1a4SJim Ingham { 7338499e1a4SJim Ingham if (target_sp == m_target_list[idx]) 7348499e1a4SJim Ingham return idx; 7358499e1a4SJim Ingham } 7368499e1a4SJim Ingham return UINT32_MAX; 7378499e1a4SJim Ingham } 7388499e1a4SJim Ingham 7398499e1a4SJim Ingham uint32_t 7402976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target) 74130fdc8d8SChris Lattner { 74230fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 74330fdc8d8SChris Lattner collection::const_iterator pos, 74430fdc8d8SChris Lattner begin = m_target_list.begin(), 74530fdc8d8SChris Lattner end = m_target_list.end(); 74630fdc8d8SChris Lattner for (pos = begin; pos != end; ++pos) 74730fdc8d8SChris Lattner { 74830fdc8d8SChris Lattner if (pos->get() == target) 74930fdc8d8SChris Lattner { 7502976d00aSJim Ingham m_selected_target_idx = std::distance (begin, pos); 7512976d00aSJim Ingham return m_selected_target_idx; 75230fdc8d8SChris Lattner } 75330fdc8d8SChris Lattner } 7542976d00aSJim Ingham m_selected_target_idx = 0; 7552976d00aSJim Ingham return m_selected_target_idx; 75630fdc8d8SChris Lattner } 75730fdc8d8SChris Lattner 75830fdc8d8SChris Lattner lldb::TargetSP 7592976d00aSJim Ingham TargetList::GetSelectedTarget () 76030fdc8d8SChris Lattner { 76130fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 7622976d00aSJim Ingham if (m_selected_target_idx >= m_target_list.size()) 7632976d00aSJim Ingham m_selected_target_idx = 0; 7642976d00aSJim Ingham return GetTargetAtIndex (m_selected_target_idx); 76530fdc8d8SChris Lattner } 766