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(); 129*1b5a74eeSVince Harron 130*1b5a74eeSVince Harron // let's see if there is already an existing plaform before we go creating another... 131*1b5a74eeSVince Harron platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 132*1b5a74eeSVince Harron 133*1b5a74eeSVince Harron if (!platform_sp && platform_options && platform_options->PlatformWasSpecified ()) 134b0cc53cfSGreg Clayton { 135b0cc53cfSGreg Clayton const bool select_platform = true; 136b0cc53cfSGreg Clayton platform_sp = platform_options->CreatePlatformWithOptions (interpreter, 137b0cc53cfSGreg Clayton arch, 138b0cc53cfSGreg Clayton select_platform, 139b0cc53cfSGreg Clayton error, 140b0cc53cfSGreg Clayton platform_arch); 141b0cc53cfSGreg Clayton if (!platform_sp) 142b0cc53cfSGreg Clayton return error; 143b0cc53cfSGreg Clayton } 144b0cc53cfSGreg Clayton 145f4d6de6aSGreg Clayton if (user_exe_path && user_exe_path[0]) 146f4d6de6aSGreg Clayton { 147f4d6de6aSGreg Clayton ModuleSpecList module_specs; 148f4d6de6aSGreg Clayton ModuleSpec module_spec; 149f4d6de6aSGreg Clayton module_spec.GetFileSpec().SetFile(user_exe_path, true); 150c76fa8a3SGreg Clayton 151c76fa8a3SGreg Clayton // Resolve the executable in case we are given a path to a application bundle 152c76fa8a3SGreg Clayton // like a .app bundle on MacOSX 153c76fa8a3SGreg Clayton Host::ResolveExecutableInBundle (module_spec.GetFileSpec()); 154c76fa8a3SGreg Clayton 155f4d6de6aSGreg Clayton lldb::offset_t file_offset = 0; 1562540a8a7SGreg Clayton lldb::offset_t file_size = 0; 1572540a8a7SGreg Clayton const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); 158f4d6de6aSGreg Clayton if (num_specs > 0) 159f4d6de6aSGreg Clayton { 160f4d6de6aSGreg Clayton ModuleSpec matching_module_spec; 161f4d6de6aSGreg Clayton 162f4d6de6aSGreg Clayton if (num_specs == 1) 163f4d6de6aSGreg Clayton { 164f4d6de6aSGreg Clayton if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 165f4d6de6aSGreg Clayton { 166f4d6de6aSGreg Clayton if (platform_arch.IsValid()) 167f4d6de6aSGreg Clayton { 1683f19ada8SGreg Clayton if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) 1693f19ada8SGreg Clayton { 1703f19ada8SGreg Clayton // If the OS or vendor weren't specified, then adopt the module's 1713f19ada8SGreg Clayton // architecture so that the platform matching can be more accurate 1723f19ada8SGreg Clayton if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified()) 1733f19ada8SGreg Clayton { 1743f19ada8SGreg Clayton prefer_platform_arch = true; 1753f19ada8SGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 1763f19ada8SGreg Clayton } 1773f19ada8SGreg Clayton } 1783f19ada8SGreg Clayton else 179f4d6de6aSGreg Clayton { 180b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 181f4d6de6aSGreg Clayton platform_arch.GetTriple().str().c_str(), 182f4d6de6aSGreg Clayton matching_module_spec.GetArchitecture().GetTriple().str().c_str(), 183b5ad4ec7SGreg Clayton module_spec.GetFileSpec().GetPath().c_str()); 184f4d6de6aSGreg Clayton return error; 185f4d6de6aSGreg Clayton } 186f4d6de6aSGreg Clayton } 187f4d6de6aSGreg Clayton else 188f4d6de6aSGreg Clayton { 189f4d6de6aSGreg Clayton // Only one arch and none was specified 1903f19ada8SGreg Clayton prefer_platform_arch = true; 191f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 192f4d6de6aSGreg Clayton } 193f4d6de6aSGreg Clayton } 194f4d6de6aSGreg Clayton } 195f4d6de6aSGreg Clayton else 196f4d6de6aSGreg Clayton { 197f4d6de6aSGreg Clayton if (arch.IsValid()) 198f4d6de6aSGreg Clayton { 199f4d6de6aSGreg Clayton module_spec.GetArchitecture() = arch; 200f4d6de6aSGreg Clayton if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 201f4d6de6aSGreg Clayton { 2023f19ada8SGreg Clayton prefer_platform_arch = true; 203f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 204f4d6de6aSGreg Clayton } 205f4d6de6aSGreg Clayton } 206b0cc53cfSGreg Clayton else 207b0cc53cfSGreg Clayton { 208b0cc53cfSGreg Clayton // No architecture specified, check if there is only one platform for 209b0cc53cfSGreg Clayton // all of the architectures. 210b0cc53cfSGreg Clayton 211b0cc53cfSGreg Clayton typedef std::vector<PlatformSP> PlatformList; 212b0cc53cfSGreg Clayton PlatformList platforms; 213615eb7e6SGreg Clayton PlatformSP host_platform_sp = Platform::GetHostPlatform(); 214b0cc53cfSGreg Clayton for (size_t i=0; i<num_specs; ++i) 215b0cc53cfSGreg Clayton { 216b0cc53cfSGreg Clayton ModuleSpec module_spec; 217b0cc53cfSGreg Clayton if (module_specs.GetModuleSpecAtIndex(i, module_spec)) 218b0cc53cfSGreg Clayton { 219b0cc53cfSGreg Clayton // See if there was a selected platform and check that first 220b0cc53cfSGreg Clayton // since the user may have specified it. 221b0cc53cfSGreg Clayton if (platform_sp) 222b0cc53cfSGreg Clayton { 223b0cc53cfSGreg Clayton if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 224b0cc53cfSGreg Clayton { 225b0cc53cfSGreg Clayton platforms.push_back(platform_sp); 226b0cc53cfSGreg Clayton continue; 227f4d6de6aSGreg Clayton } 228f4d6de6aSGreg Clayton } 229f4d6de6aSGreg Clayton 230b0cc53cfSGreg Clayton // Next check the host platform it if wasn't already checked above 231b0cc53cfSGreg Clayton if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName())) 232b3a40ba8SGreg Clayton { 233b0cc53cfSGreg Clayton if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 234b3a40ba8SGreg Clayton { 235b0cc53cfSGreg Clayton platforms.push_back(host_platform_sp); 236b0cc53cfSGreg Clayton continue; 237b0cc53cfSGreg Clayton } 238b0cc53cfSGreg Clayton } 239b0cc53cfSGreg Clayton 240b0cc53cfSGreg Clayton // Just find a platform that matches the architecture in the executable file 241b0cc53cfSGreg Clayton platforms.push_back(Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr)); 242b0cc53cfSGreg Clayton } 243b0cc53cfSGreg Clayton } 244b0cc53cfSGreg Clayton 245b0cc53cfSGreg Clayton Platform *platform_ptr = NULL; 246b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 247b0cc53cfSGreg Clayton { 248b0cc53cfSGreg Clayton if (platform_ptr) 249b0cc53cfSGreg Clayton { 250b0cc53cfSGreg Clayton if (platform_ptr->GetName() != the_platform_sp->GetName()) 251b0cc53cfSGreg Clayton { 252b0cc53cfSGreg Clayton platform_ptr = NULL; 253b0cc53cfSGreg Clayton break; 254b0cc53cfSGreg Clayton } 255b0cc53cfSGreg Clayton } 256b0cc53cfSGreg Clayton else 257b0cc53cfSGreg Clayton { 258b0cc53cfSGreg Clayton platform_ptr = the_platform_sp.get(); 259b0cc53cfSGreg Clayton } 260b0cc53cfSGreg Clayton } 261b0cc53cfSGreg Clayton 262b0cc53cfSGreg Clayton if (platform_ptr) 263b0cc53cfSGreg Clayton { 264b0cc53cfSGreg Clayton // All platforms for all modules in the exectuable match, so we can select this platform 265b0cc53cfSGreg Clayton platform_sp = platforms.front(); 266b0cc53cfSGreg Clayton } 267b0cc53cfSGreg Clayton else 268b0cc53cfSGreg Clayton { 269b0cc53cfSGreg Clayton // More than one platform claims to support this file, so the --platform option must be specified 270b0cc53cfSGreg Clayton StreamString error_strm; 271b0cc53cfSGreg Clayton std::set<Platform *> platform_set; 272b0cc53cfSGreg Clayton error_strm.Printf ("more than one platform supports this executable ("); 273b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 274b0cc53cfSGreg Clayton { 275b0cc53cfSGreg Clayton if (platform_set.find(the_platform_sp.get()) == platform_set.end()) 276b0cc53cfSGreg Clayton { 277b0cc53cfSGreg Clayton if (!platform_set.empty()) 278b0cc53cfSGreg Clayton error_strm.PutCString(", "); 279b0cc53cfSGreg Clayton error_strm.PutCString(the_platform_sp->GetName().GetCString()); 280b0cc53cfSGreg Clayton platform_set.insert(the_platform_sp.get()); 281b0cc53cfSGreg Clayton } 282b0cc53cfSGreg Clayton } 283b0cc53cfSGreg Clayton error_strm.Printf("), use the --platform option to specify a platform"); 284b0cc53cfSGreg Clayton error.SetErrorString(error_strm.GetString().c_str()); 285b3a40ba8SGreg Clayton return error; 286b3a40ba8SGreg Clayton } 287b3a40ba8SGreg Clayton } 288b0cc53cfSGreg Clayton } 289b0cc53cfSGreg Clayton } 290b0cc53cfSGreg Clayton } 291b3a40ba8SGreg Clayton 292b3a40ba8SGreg Clayton if (!platform_sp) 293b3a40ba8SGreg Clayton { 294b3a40ba8SGreg Clayton // Get the current platform and make sure it is compatible with the 295b3a40ba8SGreg Clayton // current architecture if we have a valid architecture. 296b3a40ba8SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform (); 297b3a40ba8SGreg Clayton 2983f19ada8SGreg Clayton if (!prefer_platform_arch && arch.IsValid()) 299b3a40ba8SGreg Clayton { 3003f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 30195bbdf64SGreg Clayton { 30270512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 30395bbdf64SGreg Clayton if (platform_sp) 30495bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 30595bbdf64SGreg Clayton } 306b3a40ba8SGreg Clayton } 3073f19ada8SGreg Clayton else if (platform_arch.IsValid()) 3083f19ada8SGreg Clayton { 3093f19ada8SGreg Clayton // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with 3103f19ada8SGreg Clayton // a single architecture which should be used 3113f19ada8SGreg Clayton ArchSpec fixed_platform_arch; 3123f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) 31395bbdf64SGreg Clayton { 3143f19ada8SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); 31595bbdf64SGreg Clayton if (platform_sp) 31695bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 31795bbdf64SGreg Clayton } 3183f19ada8SGreg Clayton } 319b3a40ba8SGreg Clayton } 320b3a40ba8SGreg Clayton 32170512317SGreg Clayton if (!platform_arch.IsValid()) 32270512317SGreg Clayton platform_arch = arch; 32370512317SGreg Clayton 324893c932aSJim Ingham error = TargetList::CreateTargetInternal (debugger, 325a0ca6601SGreg Clayton user_exe_path, 32670512317SGreg Clayton platform_arch, 327cac9c5f9SGreg Clayton get_dependent_files, 328cac9c5f9SGreg Clayton platform_sp, 329893c932aSJim Ingham target_sp, 330893c932aSJim Ingham is_dummy_target); 331cac9c5f9SGreg Clayton return error; 332cac9c5f9SGreg Clayton } 333cac9c5f9SGreg Clayton 334893c932aSJim Ingham lldb::TargetSP 335893c932aSJim Ingham TargetList::GetDummyTarget (lldb_private::Debugger &debugger) 336893c932aSJim Ingham { 337893c932aSJim Ingham // FIXME: Maybe the dummy target should be per-Debugger 338893c932aSJim Ingham if (!m_dummy_target_sp || !m_dummy_target_sp->IsValid()) 339893c932aSJim Ingham { 340893c932aSJim Ingham ArchSpec arch(Target::GetDefaultArchitecture()); 341893c932aSJim Ingham if (!arch.IsValid()) 342893c932aSJim Ingham arch = HostInfo::GetArchitecture(); 343893c932aSJim Ingham Error err = CreateDummyTarget(debugger, 344893c932aSJim Ingham arch.GetTriple().getTriple().c_str(), 345893c932aSJim Ingham m_dummy_target_sp); 346893c932aSJim Ingham } 347893c932aSJim Ingham 348893c932aSJim Ingham return m_dummy_target_sp; 349893c932aSJim Ingham } 350893c932aSJim Ingham 351cac9c5f9SGreg Clayton Error 352893c932aSJim Ingham TargetList::CreateDummyTarget (Debugger &debugger, 353893c932aSJim Ingham const char *specified_arch_name, 354893c932aSJim Ingham lldb::TargetSP &target_sp) 355893c932aSJim Ingham { 356893c932aSJim Ingham PlatformSP host_platform_sp(Platform::GetHostPlatform()); 357893c932aSJim Ingham return CreateTargetInternal (debugger, 358893c932aSJim Ingham (const char *) nullptr, 359893c932aSJim Ingham specified_arch_name, 360893c932aSJim Ingham false, 361893c932aSJim Ingham (const OptionGroupPlatform *) nullptr, 362893c932aSJim Ingham target_sp, 363893c932aSJim Ingham true); 364893c932aSJim Ingham } 365893c932aSJim Ingham 366893c932aSJim Ingham Error 367893c932aSJim Ingham TargetList::CreateTargetInternal (Debugger &debugger, 368a0ca6601SGreg Clayton const char *user_exe_path, 36970512317SGreg Clayton const ArchSpec& specified_arch, 37030fdc8d8SChris Lattner bool get_dependent_files, 371893c932aSJim Ingham lldb::PlatformSP &platform_sp, 372893c932aSJim Ingham lldb::TargetSP &target_sp, 373893c932aSJim Ingham bool is_dummy_target) 37430fdc8d8SChris Lattner { 375893c932aSJim Ingham 37630fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 377a0ca6601SGreg Clayton "TargetList::CreateTarget (file = '%s', arch = '%s')", 378a0ca6601SGreg Clayton user_exe_path, 37970512317SGreg Clayton specified_arch.GetArchitectureName()); 3805aee162fSJim Ingham Error error; 3815aee162fSJim Ingham 38270512317SGreg Clayton ArchSpec arch(specified_arch); 38370512317SGreg Clayton 38470512317SGreg Clayton if (arch.IsValid()) 38570512317SGreg Clayton { 386b0cc53cfSGreg Clayton if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 38770512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 38870512317SGreg Clayton } 38970512317SGreg Clayton 39070512317SGreg Clayton if (!platform_sp) 39170512317SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 392ded470d3SGreg Clayton 3938ae50eb4SGreg Clayton if (!arch.IsValid()) 3948ae50eb4SGreg Clayton arch = specified_arch; 3958ae50eb4SGreg Clayton 396d26206b5SJason Molenda FileSpec file (user_exe_path, false); 397d26206b5SJason Molenda if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 398d26206b5SJason Molenda { 3999f822cd1SMichael Sartain // we want to expand the tilde but we don't want to resolve any symbolic links 4009f822cd1SMichael Sartain // so we can't use the FileSpec constructor's resolve flag 4013f559740SZachary Turner llvm::SmallString<64> unglobbed_path(user_exe_path); 4023f559740SZachary Turner FileSpec::ResolveUsername(unglobbed_path); 4039f822cd1SMichael Sartain 4043f559740SZachary Turner if (unglobbed_path.empty()) 4053f559740SZachary Turner file = FileSpec(user_exe_path, false); 4063f559740SZachary Turner else 4073f559740SZachary Turner file = FileSpec(unglobbed_path.c_str(), false); 408d26206b5SJason Molenda } 4099f822cd1SMichael Sartain 41082d79295SGreg Clayton bool user_exe_path_is_bundle = false; 41182d79295SGreg Clayton char resolved_bundle_exe_path[PATH_MAX]; 41282d79295SGreg Clayton resolved_bundle_exe_path[0] = '\0'; 413e996fd30SGreg Clayton if (file) 4145aee162fSJim Ingham { 41582d79295SGreg Clayton if (file.GetFileType() == FileSpec::eFileTypeDirectory) 41682d79295SGreg Clayton user_exe_path_is_bundle = true; 41782d79295SGreg Clayton 41814468812SJason Molenda if (file.IsRelativeToCurrentWorkingDirectory() && user_exe_path) 419a0ca6601SGreg Clayton { 420a0ca6601SGreg Clayton // Ignore paths that start with "./" and "../" 421a0ca6601SGreg Clayton if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 422a0ca6601SGreg Clayton (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 423a0ca6601SGreg Clayton { 424a0ca6601SGreg Clayton char cwd[PATH_MAX]; 425a0ca6601SGreg Clayton if (getcwd (cwd, sizeof(cwd))) 426a0ca6601SGreg Clayton { 427a0ca6601SGreg Clayton std::string cwd_user_exe_path (cwd); 428a0ca6601SGreg Clayton cwd_user_exe_path += '/'; 429a0ca6601SGreg Clayton cwd_user_exe_path += user_exe_path; 4309ff5aae5SGreg Clayton FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 4319ff5aae5SGreg Clayton if (cwd_file.Exists()) 4329ff5aae5SGreg Clayton file = cwd_file; 433a0ca6601SGreg Clayton } 434a0ca6601SGreg Clayton } 435a0ca6601SGreg Clayton } 436a0ca6601SGreg Clayton 43730fdc8d8SChris Lattner ModuleSP exe_module_sp; 438e996fd30SGreg Clayton if (platform_sp) 439c859e2d5SGreg Clayton { 440c859e2d5SGreg Clayton FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 4418012cadbSGreg Clayton ModuleSpec module_spec(file, arch); 4428012cadbSGreg Clayton error = platform_sp->ResolveExecutable (module_spec, 443c859e2d5SGreg Clayton exe_module_sp, 444c859e2d5SGreg Clayton executable_search_paths.GetSize() ? &executable_search_paths : NULL); 445c859e2d5SGreg Clayton } 446428a9a58SCaroline Tice 447e996fd30SGreg Clayton if (error.Success() && exe_module_sp) 44830fdc8d8SChris Lattner { 4495aee162fSJim Ingham if (exe_module_sp->GetObjectFile() == NULL) 4505aee162fSJim Ingham { 451bc5cad6cSGreg Clayton if (arch.IsValid()) 452bc5cad6cSGreg Clayton { 453b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 454b5ad4ec7SGreg Clayton file.GetPath().c_str(), 45564195a2cSGreg Clayton arch.GetArchitectureName()); 456bc5cad6cSGreg Clayton } 457bc5cad6cSGreg Clayton else 458bc5cad6cSGreg Clayton { 459b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("unsupported file type \"%s\"", 460b5ad4ec7SGreg Clayton file.GetPath().c_str()); 461bc5cad6cSGreg Clayton } 4625aee162fSJim Ingham return error; 4635aee162fSJim Ingham } 464893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 46530fdc8d8SChris Lattner target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 46682d79295SGreg Clayton if (user_exe_path_is_bundle) 46782d79295SGreg Clayton exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 4685aee162fSJim Ingham } 4695aee162fSJim Ingham } 470e996fd30SGreg Clayton else 471e996fd30SGreg Clayton { 472e996fd30SGreg Clayton // No file was specified, just create an empty target with any arch 473e996fd30SGreg Clayton // if a valid arch was specified 474893c932aSJim Ingham target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); 475e996fd30SGreg Clayton } 4761559a46bSCaroline Tice 477e996fd30SGreg Clayton if (target_sp) 478e996fd30SGreg Clayton { 47982d79295SGreg Clayton // Set argv0 with what the user typed, unless the user specified a 48082d79295SGreg Clayton // directory. If the user specified a directory, then it is probably a 48182d79295SGreg Clayton // bundle that was resolved and we need to use the resolved bundle path 482a0ca6601SGreg Clayton if (user_exe_path) 483a0ca6601SGreg Clayton { 484a0ca6601SGreg Clayton // Use exactly what the user typed as the first argument when we exec or posix_spawn 48582d79295SGreg Clayton if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 48682d79295SGreg Clayton { 48782d79295SGreg Clayton target_sp->SetArg0 (resolved_bundle_exe_path); 48882d79295SGreg Clayton } 48982d79295SGreg Clayton else 49082d79295SGreg Clayton { 4919f822cd1SMichael Sartain // Use resolved path 4929f822cd1SMichael Sartain target_sp->SetArg0 (file.GetPath().c_str()); 493a0ca6601SGreg Clayton } 49482d79295SGreg Clayton } 495a0ca6601SGreg Clayton if (file.GetDirectory()) 496a0ca6601SGreg Clayton { 497a0ca6601SGreg Clayton FileSpec file_dir; 498a0ca6601SGreg Clayton file_dir.GetDirectory() = file.GetDirectory(); 499a0ca6601SGreg Clayton target_sp->GetExecutableSearchPaths ().Append (file_dir); 500a0ca6601SGreg Clayton } 501893c932aSJim Ingham 502893c932aSJim Ingham // Don't put the dummy target in the target list, it's held separately. 503893c932aSJim Ingham if (!is_dummy_target) 504893c932aSJim Ingham { 50530fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 5062976d00aSJim Ingham m_selected_target_idx = m_target_list.size(); 50730fdc8d8SChris Lattner m_target_list.push_back(target_sp); 50833df7cd3SJim Ingham // Now prime this from the dummy target: 50933df7cd3SJim Ingham target_sp->PrimeFromDummyTarget(debugger.GetDummyTarget()); 510893c932aSJim Ingham } 511893c932aSJim Ingham else 512893c932aSJim Ingham { 513893c932aSJim Ingham m_dummy_target_sp = target_sp; 514893c932aSJim Ingham } 51530fdc8d8SChris Lattner } 51630fdc8d8SChris Lattner 51730fdc8d8SChris Lattner return error; 51830fdc8d8SChris Lattner } 51930fdc8d8SChris Lattner 52030fdc8d8SChris Lattner bool 52130fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp) 52230fdc8d8SChris Lattner { 52330fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 52430fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 52530fdc8d8SChris Lattner 52630fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 52730fdc8d8SChris Lattner { 52830fdc8d8SChris Lattner if (pos->get() == target_sp.get()) 52930fdc8d8SChris Lattner { 53030fdc8d8SChris Lattner m_target_list.erase(pos); 53130fdc8d8SChris Lattner return true; 53230fdc8d8SChris Lattner } 53330fdc8d8SChris Lattner } 53430fdc8d8SChris Lattner return false; 53530fdc8d8SChris Lattner } 53630fdc8d8SChris Lattner 53730fdc8d8SChris Lattner 53830fdc8d8SChris Lattner TargetSP 53930fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture 54030fdc8d8SChris Lattner ( 54130fdc8d8SChris Lattner const FileSpec &exe_file_spec, 54230fdc8d8SChris Lattner const ArchSpec *exe_arch_ptr 54330fdc8d8SChris Lattner ) const 54430fdc8d8SChris Lattner { 54530fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 54630fdc8d8SChris Lattner TargetSP target_sp; 547ddd7a2a6SSean Callanan bool full_match = (bool)exe_file_spec.GetDirectory(); 54830fdc8d8SChris Lattner 54930fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 55030fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 55130fdc8d8SChris Lattner { 552aa149cbdSGreg Clayton Module *exe_module = (*pos)->GetExecutableModulePointer(); 55330fdc8d8SChris Lattner 554aa149cbdSGreg Clayton if (exe_module) 55530fdc8d8SChris Lattner { 556aa149cbdSGreg Clayton if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 55730fdc8d8SChris Lattner { 55830fdc8d8SChris Lattner if (exe_arch_ptr) 55930fdc8d8SChris Lattner { 560bf4b7be6SSean Callanan if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 56130fdc8d8SChris Lattner continue; 56230fdc8d8SChris Lattner } 56330fdc8d8SChris Lattner target_sp = *pos; 56430fdc8d8SChris Lattner break; 56530fdc8d8SChris Lattner } 56630fdc8d8SChris Lattner } 56730fdc8d8SChris Lattner } 56830fdc8d8SChris Lattner return target_sp; 56930fdc8d8SChris Lattner } 57030fdc8d8SChris Lattner 57130fdc8d8SChris Lattner TargetSP 57230fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 57330fdc8d8SChris Lattner { 57430fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 57530fdc8d8SChris Lattner TargetSP target_sp; 57630fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 57730fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 57830fdc8d8SChris Lattner { 57930fdc8d8SChris Lattner Process* process = (*pos)->GetProcessSP().get(); 58030fdc8d8SChris Lattner if (process && process->GetID() == pid) 58130fdc8d8SChris Lattner { 58230fdc8d8SChris Lattner target_sp = *pos; 58330fdc8d8SChris Lattner break; 58430fdc8d8SChris Lattner } 58530fdc8d8SChris Lattner } 58630fdc8d8SChris Lattner return target_sp; 58730fdc8d8SChris Lattner } 58830fdc8d8SChris Lattner 58930fdc8d8SChris Lattner 59030fdc8d8SChris Lattner TargetSP 59130fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const 59230fdc8d8SChris Lattner { 59330fdc8d8SChris Lattner TargetSP target_sp; 59430fdc8d8SChris Lattner if (process) 59530fdc8d8SChris Lattner { 59630fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 59730fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 59830fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 59930fdc8d8SChris Lattner { 60030fdc8d8SChris Lattner if (process == (*pos)->GetProcessSP().get()) 60130fdc8d8SChris Lattner { 60230fdc8d8SChris Lattner target_sp = *pos; 60330fdc8d8SChris Lattner break; 60430fdc8d8SChris Lattner } 60530fdc8d8SChris Lattner } 60630fdc8d8SChris Lattner } 60730fdc8d8SChris Lattner return target_sp; 60830fdc8d8SChris Lattner } 60930fdc8d8SChris Lattner 61030fdc8d8SChris Lattner TargetSP 61130fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const 61230fdc8d8SChris Lattner { 61330fdc8d8SChris Lattner TargetSP target_sp; 61430fdc8d8SChris Lattner if (target) 61530fdc8d8SChris Lattner { 61630fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 61730fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 61830fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 61930fdc8d8SChris Lattner { 62030fdc8d8SChris Lattner if (target == (*pos).get()) 62130fdc8d8SChris Lattner { 62230fdc8d8SChris Lattner target_sp = *pos; 62330fdc8d8SChris Lattner break; 62430fdc8d8SChris Lattner } 62530fdc8d8SChris Lattner } 62630fdc8d8SChris Lattner } 62730fdc8d8SChris Lattner return target_sp; 62830fdc8d8SChris Lattner } 62930fdc8d8SChris Lattner 63030fdc8d8SChris Lattner uint32_t 63130fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid) 63230fdc8d8SChris Lattner { 63330fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 63430fdc8d8SChris Lattner 63530fdc8d8SChris Lattner if (pid != LLDB_INVALID_PROCESS_ID) 63630fdc8d8SChris Lattner { 63730fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 63830fdc8d8SChris Lattner if (target_sp.get()) 63930fdc8d8SChris Lattner { 64030fdc8d8SChris Lattner Process* process = target_sp->GetProcessSP().get(); 64130fdc8d8SChris Lattner if (process) 64230fdc8d8SChris Lattner { 643cfc0935eSJim Ingham process->SendAsyncInterrupt(); 64430fdc8d8SChris Lattner ++num_async_interrupts_sent; 64530fdc8d8SChris Lattner } 64630fdc8d8SChris Lattner } 64730fdc8d8SChris Lattner } 64830fdc8d8SChris Lattner else 64930fdc8d8SChris Lattner { 65030fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 65130fdc8d8SChris Lattner // list's async broadcaster... 65230fdc8d8SChris Lattner BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 65330fdc8d8SChris Lattner } 65430fdc8d8SChris Lattner 65530fdc8d8SChris Lattner return num_async_interrupts_sent; 65630fdc8d8SChris Lattner } 65730fdc8d8SChris Lattner 65830fdc8d8SChris Lattner uint32_t 65930fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 66030fdc8d8SChris Lattner { 66130fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 66230fdc8d8SChris Lattner Process *process = NULL; 66330fdc8d8SChris Lattner if (pid == LLDB_INVALID_PROCESS_ID) 66430fdc8d8SChris Lattner { 66530fdc8d8SChris Lattner // Signal all processes with signal 66630fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 66730fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 66830fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 66930fdc8d8SChris Lattner { 67030fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 67130fdc8d8SChris Lattner if (process) 67230fdc8d8SChris Lattner { 67330fdc8d8SChris Lattner if (process->IsAlive()) 67430fdc8d8SChris Lattner { 67530fdc8d8SChris Lattner ++num_signals_sent; 67630fdc8d8SChris Lattner process->Signal (signo); 67730fdc8d8SChris Lattner } 67830fdc8d8SChris Lattner } 67930fdc8d8SChris Lattner } 68030fdc8d8SChris Lattner } 68130fdc8d8SChris Lattner else 68230fdc8d8SChris Lattner { 68330fdc8d8SChris Lattner // Signal a specific process with signal 68430fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 68530fdc8d8SChris Lattner if (target_sp.get()) 68630fdc8d8SChris Lattner { 68730fdc8d8SChris Lattner process = target_sp->GetProcessSP().get(); 68830fdc8d8SChris Lattner if (process) 68930fdc8d8SChris Lattner { 69030fdc8d8SChris Lattner if (process->IsAlive()) 69130fdc8d8SChris Lattner { 69230fdc8d8SChris Lattner ++num_signals_sent; 69330fdc8d8SChris Lattner process->Signal (signo); 69430fdc8d8SChris Lattner } 69530fdc8d8SChris Lattner } 69630fdc8d8SChris Lattner } 69730fdc8d8SChris Lattner } 69830fdc8d8SChris Lattner return num_signals_sent; 69930fdc8d8SChris Lattner } 70030fdc8d8SChris Lattner 70130fdc8d8SChris Lattner int 70230fdc8d8SChris Lattner TargetList::GetNumTargets () const 70330fdc8d8SChris Lattner { 70430fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 70530fdc8d8SChris Lattner return m_target_list.size(); 70630fdc8d8SChris Lattner } 70730fdc8d8SChris Lattner 70830fdc8d8SChris Lattner lldb::TargetSP 70930fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const 71030fdc8d8SChris Lattner { 71130fdc8d8SChris Lattner TargetSP target_sp; 71230fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 71330fdc8d8SChris Lattner if (idx < m_target_list.size()) 71430fdc8d8SChris Lattner target_sp = m_target_list[idx]; 71530fdc8d8SChris Lattner return target_sp; 71630fdc8d8SChris Lattner } 71730fdc8d8SChris Lattner 71830fdc8d8SChris Lattner uint32_t 7198499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 7208499e1a4SJim Ingham { 7218499e1a4SJim Ingham Mutex::Locker locker (m_target_list_mutex); 7228499e1a4SJim Ingham size_t num_targets = m_target_list.size(); 7238499e1a4SJim Ingham for (size_t idx = 0; idx < num_targets; idx++) 7248499e1a4SJim Ingham { 7258499e1a4SJim Ingham if (target_sp == m_target_list[idx]) 7268499e1a4SJim Ingham return idx; 7278499e1a4SJim Ingham } 7288499e1a4SJim Ingham return UINT32_MAX; 7298499e1a4SJim Ingham } 7308499e1a4SJim Ingham 7318499e1a4SJim Ingham uint32_t 7322976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target) 73330fdc8d8SChris Lattner { 73430fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 73530fdc8d8SChris Lattner collection::const_iterator pos, 73630fdc8d8SChris Lattner begin = m_target_list.begin(), 73730fdc8d8SChris Lattner end = m_target_list.end(); 73830fdc8d8SChris Lattner for (pos = begin; pos != end; ++pos) 73930fdc8d8SChris Lattner { 74030fdc8d8SChris Lattner if (pos->get() == target) 74130fdc8d8SChris Lattner { 7422976d00aSJim Ingham m_selected_target_idx = std::distance (begin, pos); 7432976d00aSJim Ingham return m_selected_target_idx; 74430fdc8d8SChris Lattner } 74530fdc8d8SChris Lattner } 7462976d00aSJim Ingham m_selected_target_idx = 0; 7472976d00aSJim Ingham return m_selected_target_idx; 74830fdc8d8SChris Lattner } 74930fdc8d8SChris Lattner 75030fdc8d8SChris Lattner lldb::TargetSP 7512976d00aSJim Ingham TargetList::GetSelectedTarget () 75230fdc8d8SChris Lattner { 75330fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 7542976d00aSJim Ingham if (m_selected_target_idx >= m_target_list.size()) 7552976d00aSJim Ingham m_selected_target_idx = 0; 7562976d00aSJim Ingham return GetTargetAtIndex (m_selected_target_idx); 75730fdc8d8SChris Lattner } 758