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" 24b3a40ba8SGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 25cac9c5f9SGreg Clayton #include "lldb/Interpreter/OptionGroupPlatform.h" 26f4d6de6aSGreg Clayton #include "lldb/Symbol/ObjectFile.h" 27e996fd30SGreg Clayton #include "lldb/Target/Platform.h" 2830fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2930fdc8d8SChris Lattner #include "lldb/Target/TargetList.h" 3030fdc8d8SChris Lattner 313f559740SZachary Turner #include "llvm/ADT/SmallString.h" 323f559740SZachary Turner 3330fdc8d8SChris Lattner using namespace lldb; 3430fdc8d8SChris Lattner using namespace lldb_private; 3530fdc8d8SChris Lattner 364bddaeb5SJim Ingham ConstString & 374bddaeb5SJim Ingham TargetList::GetStaticBroadcasterClass () 384bddaeb5SJim Ingham { 394bddaeb5SJim Ingham static ConstString class_name ("lldb.targetList"); 404bddaeb5SJim Ingham return class_name; 414bddaeb5SJim Ingham } 4230fdc8d8SChris Lattner 4330fdc8d8SChris Lattner //---------------------------------------------------------------------- 4430fdc8d8SChris Lattner // TargetList constructor 4530fdc8d8SChris Lattner //---------------------------------------------------------------------- 464bddaeb5SJim Ingham TargetList::TargetList(Debugger &debugger) : 474f465cffSJim Ingham Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()), 4830fdc8d8SChris Lattner m_target_list(), 4930fdc8d8SChris Lattner m_target_list_mutex (Mutex::eMutexTypeRecursive), 502976d00aSJim Ingham m_selected_target_idx (0) 5130fdc8d8SChris Lattner { 524bddaeb5SJim Ingham CheckInWithManager(); 5330fdc8d8SChris Lattner } 5430fdc8d8SChris Lattner 5530fdc8d8SChris Lattner //---------------------------------------------------------------------- 5630fdc8d8SChris Lattner // Destructor 5730fdc8d8SChris Lattner //---------------------------------------------------------------------- 5830fdc8d8SChris Lattner TargetList::~TargetList() 5930fdc8d8SChris Lattner { 6030fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 6130fdc8d8SChris Lattner m_target_list.clear(); 6230fdc8d8SChris Lattner } 6330fdc8d8SChris Lattner 6430fdc8d8SChris Lattner Error 65cac9c5f9SGreg Clayton TargetList::CreateTarget (Debugger &debugger, 66a0ca6601SGreg Clayton const char *user_exe_path, 67cac9c5f9SGreg Clayton const char *triple_cstr, 68cac9c5f9SGreg Clayton bool get_dependent_files, 69cac9c5f9SGreg Clayton const OptionGroupPlatform *platform_options, 70cac9c5f9SGreg Clayton TargetSP &target_sp) 71cac9c5f9SGreg Clayton { 72cac9c5f9SGreg Clayton Error error; 73cac9c5f9SGreg Clayton PlatformSP platform_sp; 74cac9c5f9SGreg Clayton 75cdc21d4cSJohnny Chen // This is purposely left empty unless it is specified by triple_cstr. 76cdc21d4cSJohnny Chen // If not initialized via triple_cstr, then the currently selected platform 77cdc21d4cSJohnny Chen // will set the architecture correctly. 7870512317SGreg Clayton const ArchSpec arch(triple_cstr); 7970512317SGreg Clayton if (triple_cstr && triple_cstr[0]) 80cac9c5f9SGreg Clayton { 81cac9c5f9SGreg Clayton if (!arch.IsValid()) 82cac9c5f9SGreg Clayton { 8386edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid triple '%s'", triple_cstr); 84cac9c5f9SGreg Clayton return error; 85cac9c5f9SGreg Clayton } 86cac9c5f9SGreg Clayton } 87b3a40ba8SGreg Clayton 8870512317SGreg Clayton ArchSpec platform_arch(arch); 89f4d6de6aSGreg Clayton 903f19ada8SGreg Clayton bool prefer_platform_arch = false; 91f4d6de6aSGreg Clayton 92b0cc53cfSGreg Clayton CommandInterpreter &interpreter = debugger.GetCommandInterpreter(); 93b0cc53cfSGreg Clayton if (platform_options && platform_options->PlatformWasSpecified ()) 94b0cc53cfSGreg Clayton { 95b0cc53cfSGreg Clayton const bool select_platform = true; 96b0cc53cfSGreg Clayton platform_sp = platform_options->CreatePlatformWithOptions (interpreter, 97b0cc53cfSGreg Clayton arch, 98b0cc53cfSGreg Clayton select_platform, 99b0cc53cfSGreg Clayton error, 100b0cc53cfSGreg Clayton platform_arch); 101b0cc53cfSGreg Clayton if (!platform_sp) 102b0cc53cfSGreg Clayton return error; 103b0cc53cfSGreg Clayton } 104b0cc53cfSGreg Clayton 105f4d6de6aSGreg Clayton if (user_exe_path && user_exe_path[0]) 106f4d6de6aSGreg Clayton { 107f4d6de6aSGreg Clayton ModuleSpecList module_specs; 108f4d6de6aSGreg Clayton ModuleSpec module_spec; 109f4d6de6aSGreg Clayton module_spec.GetFileSpec().SetFile(user_exe_path, true); 110c76fa8a3SGreg Clayton 111c76fa8a3SGreg Clayton // Resolve the executable in case we are given a path to a application bundle 112c76fa8a3SGreg Clayton // like a .app bundle on MacOSX 113c76fa8a3SGreg Clayton Host::ResolveExecutableInBundle (module_spec.GetFileSpec()); 114c76fa8a3SGreg Clayton 115f4d6de6aSGreg Clayton lldb::offset_t file_offset = 0; 1162540a8a7SGreg Clayton lldb::offset_t file_size = 0; 1172540a8a7SGreg Clayton const size_t num_specs = ObjectFile::GetModuleSpecifications (module_spec.GetFileSpec(), file_offset, file_size, module_specs); 118f4d6de6aSGreg Clayton if (num_specs > 0) 119f4d6de6aSGreg Clayton { 120f4d6de6aSGreg Clayton ModuleSpec matching_module_spec; 121f4d6de6aSGreg Clayton 122f4d6de6aSGreg Clayton if (num_specs == 1) 123f4d6de6aSGreg Clayton { 124f4d6de6aSGreg Clayton if (module_specs.GetModuleSpecAtIndex(0, matching_module_spec)) 125f4d6de6aSGreg Clayton { 126f4d6de6aSGreg Clayton if (platform_arch.IsValid()) 127f4d6de6aSGreg Clayton { 1283f19ada8SGreg Clayton if (platform_arch.IsCompatibleMatch(matching_module_spec.GetArchitecture())) 1293f19ada8SGreg Clayton { 1303f19ada8SGreg Clayton // If the OS or vendor weren't specified, then adopt the module's 1313f19ada8SGreg Clayton // architecture so that the platform matching can be more accurate 1323f19ada8SGreg Clayton if (!platform_arch.TripleOSWasSpecified() || !platform_arch.TripleVendorWasSpecified()) 1333f19ada8SGreg Clayton { 1343f19ada8SGreg Clayton prefer_platform_arch = true; 1353f19ada8SGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 1363f19ada8SGreg Clayton } 1373f19ada8SGreg Clayton } 1383f19ada8SGreg Clayton else 139f4d6de6aSGreg Clayton { 140b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("the specified architecture '%s' is not compatible with '%s' in '%s'", 141f4d6de6aSGreg Clayton platform_arch.GetTriple().str().c_str(), 142f4d6de6aSGreg Clayton matching_module_spec.GetArchitecture().GetTriple().str().c_str(), 143b5ad4ec7SGreg Clayton module_spec.GetFileSpec().GetPath().c_str()); 144f4d6de6aSGreg Clayton return error; 145f4d6de6aSGreg Clayton } 146f4d6de6aSGreg Clayton } 147f4d6de6aSGreg Clayton else 148f4d6de6aSGreg Clayton { 149f4d6de6aSGreg Clayton // Only one arch and none was specified 1503f19ada8SGreg Clayton prefer_platform_arch = true; 151f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 152f4d6de6aSGreg Clayton } 153f4d6de6aSGreg Clayton } 154f4d6de6aSGreg Clayton } 155f4d6de6aSGreg Clayton else 156f4d6de6aSGreg Clayton { 157f4d6de6aSGreg Clayton if (arch.IsValid()) 158f4d6de6aSGreg Clayton { 159f4d6de6aSGreg Clayton module_spec.GetArchitecture() = arch; 160f4d6de6aSGreg Clayton if (module_specs.FindMatchingModuleSpec(module_spec, matching_module_spec)) 161f4d6de6aSGreg Clayton { 1623f19ada8SGreg Clayton prefer_platform_arch = true; 163f4d6de6aSGreg Clayton platform_arch = matching_module_spec.GetArchitecture(); 164f4d6de6aSGreg Clayton } 165f4d6de6aSGreg Clayton } 166b0cc53cfSGreg Clayton else 167b0cc53cfSGreg Clayton { 168b0cc53cfSGreg Clayton // No architecture specified, check if there is only one platform for 169b0cc53cfSGreg Clayton // all of the architectures. 170b0cc53cfSGreg Clayton 171b0cc53cfSGreg Clayton typedef std::vector<PlatformSP> PlatformList; 172b0cc53cfSGreg Clayton PlatformList platforms; 173*615eb7e6SGreg Clayton PlatformSP host_platform_sp = Platform::GetHostPlatform(); 174b0cc53cfSGreg Clayton for (size_t i=0; i<num_specs; ++i) 175b0cc53cfSGreg Clayton { 176b0cc53cfSGreg Clayton ModuleSpec module_spec; 177b0cc53cfSGreg Clayton if (module_specs.GetModuleSpecAtIndex(i, module_spec)) 178b0cc53cfSGreg Clayton { 179b0cc53cfSGreg Clayton // See if there was a selected platform and check that first 180b0cc53cfSGreg Clayton // since the user may have specified it. 181b0cc53cfSGreg Clayton if (platform_sp) 182b0cc53cfSGreg Clayton { 183b0cc53cfSGreg Clayton if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 184b0cc53cfSGreg Clayton { 185b0cc53cfSGreg Clayton platforms.push_back(platform_sp); 186b0cc53cfSGreg Clayton continue; 187f4d6de6aSGreg Clayton } 188f4d6de6aSGreg Clayton } 189f4d6de6aSGreg Clayton 190b0cc53cfSGreg Clayton // Next check the host platform it if wasn't already checked above 191b0cc53cfSGreg Clayton if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName())) 192b3a40ba8SGreg Clayton { 193b0cc53cfSGreg Clayton if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL)) 194b3a40ba8SGreg Clayton { 195b0cc53cfSGreg Clayton platforms.push_back(host_platform_sp); 196b0cc53cfSGreg Clayton continue; 197b0cc53cfSGreg Clayton } 198b0cc53cfSGreg Clayton } 199b0cc53cfSGreg Clayton 200b0cc53cfSGreg Clayton // Just find a platform that matches the architecture in the executable file 201b0cc53cfSGreg Clayton platforms.push_back(Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr)); 202b0cc53cfSGreg Clayton } 203b0cc53cfSGreg Clayton } 204b0cc53cfSGreg Clayton 205b0cc53cfSGreg Clayton Platform *platform_ptr = NULL; 206b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 207b0cc53cfSGreg Clayton { 208b0cc53cfSGreg Clayton if (platform_ptr) 209b0cc53cfSGreg Clayton { 210b0cc53cfSGreg Clayton if (platform_ptr->GetName() != the_platform_sp->GetName()) 211b0cc53cfSGreg Clayton { 212b0cc53cfSGreg Clayton platform_ptr = NULL; 213b0cc53cfSGreg Clayton break; 214b0cc53cfSGreg Clayton } 215b0cc53cfSGreg Clayton } 216b0cc53cfSGreg Clayton else 217b0cc53cfSGreg Clayton { 218b0cc53cfSGreg Clayton platform_ptr = the_platform_sp.get(); 219b0cc53cfSGreg Clayton } 220b0cc53cfSGreg Clayton } 221b0cc53cfSGreg Clayton 222b0cc53cfSGreg Clayton if (platform_ptr) 223b0cc53cfSGreg Clayton { 224b0cc53cfSGreg Clayton // All platforms for all modules in the exectuable match, so we can select this platform 225b0cc53cfSGreg Clayton platform_sp = platforms.front(); 226b0cc53cfSGreg Clayton } 227b0cc53cfSGreg Clayton else 228b0cc53cfSGreg Clayton { 229b0cc53cfSGreg Clayton // More than one platform claims to support this file, so the --platform option must be specified 230b0cc53cfSGreg Clayton StreamString error_strm; 231b0cc53cfSGreg Clayton std::set<Platform *> platform_set; 232b0cc53cfSGreg Clayton error_strm.Printf ("more than one platform supports this executable ("); 233b0cc53cfSGreg Clayton for (const auto &the_platform_sp : platforms) 234b0cc53cfSGreg Clayton { 235b0cc53cfSGreg Clayton if (platform_set.find(the_platform_sp.get()) == platform_set.end()) 236b0cc53cfSGreg Clayton { 237b0cc53cfSGreg Clayton if (!platform_set.empty()) 238b0cc53cfSGreg Clayton error_strm.PutCString(", "); 239b0cc53cfSGreg Clayton error_strm.PutCString(the_platform_sp->GetName().GetCString()); 240b0cc53cfSGreg Clayton platform_set.insert(the_platform_sp.get()); 241b0cc53cfSGreg Clayton } 242b0cc53cfSGreg Clayton } 243b0cc53cfSGreg Clayton error_strm.Printf("), use the --platform option to specify a platform"); 244b0cc53cfSGreg Clayton error.SetErrorString(error_strm.GetString().c_str()); 245b3a40ba8SGreg Clayton return error; 246b3a40ba8SGreg Clayton } 247b3a40ba8SGreg Clayton } 248b0cc53cfSGreg Clayton } 249b0cc53cfSGreg Clayton } 250b0cc53cfSGreg Clayton } 251b3a40ba8SGreg Clayton 252b3a40ba8SGreg Clayton if (!platform_sp) 253b3a40ba8SGreg Clayton { 254b3a40ba8SGreg Clayton // Get the current platform and make sure it is compatible with the 255b3a40ba8SGreg Clayton // current architecture if we have a valid architecture. 256b3a40ba8SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform (); 257b3a40ba8SGreg Clayton 2583f19ada8SGreg Clayton if (!prefer_platform_arch && arch.IsValid()) 259b3a40ba8SGreg Clayton { 2603f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) 26195bbdf64SGreg Clayton { 26270512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); 26395bbdf64SGreg Clayton if (platform_sp) 26495bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 26595bbdf64SGreg Clayton } 266b3a40ba8SGreg Clayton } 2673f19ada8SGreg Clayton else if (platform_arch.IsValid()) 2683f19ada8SGreg Clayton { 2693f19ada8SGreg Clayton // if "arch" isn't valid, yet "platform_arch" is, it means we have an executable file with 2703f19ada8SGreg Clayton // a single architecture which should be used 2713f19ada8SGreg Clayton ArchSpec fixed_platform_arch; 2723f19ada8SGreg Clayton if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, &fixed_platform_arch)) 27395bbdf64SGreg Clayton { 2743f19ada8SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(platform_arch, &fixed_platform_arch); 27595bbdf64SGreg Clayton if (platform_sp) 27695bbdf64SGreg Clayton debugger.GetPlatformList().SetSelectedPlatform(platform_sp); 27795bbdf64SGreg Clayton } 2783f19ada8SGreg Clayton } 279b3a40ba8SGreg Clayton } 280b3a40ba8SGreg Clayton 28170512317SGreg Clayton if (!platform_arch.IsValid()) 28270512317SGreg Clayton platform_arch = arch; 28370512317SGreg Clayton 284cac9c5f9SGreg Clayton error = TargetList::CreateTarget (debugger, 285a0ca6601SGreg Clayton user_exe_path, 28670512317SGreg Clayton platform_arch, 287cac9c5f9SGreg Clayton get_dependent_files, 288cac9c5f9SGreg Clayton platform_sp, 289cac9c5f9SGreg Clayton target_sp); 290cac9c5f9SGreg Clayton return error; 291cac9c5f9SGreg Clayton } 292cac9c5f9SGreg Clayton 293cac9c5f9SGreg Clayton Error 294a0ca6601SGreg Clayton TargetList::CreateTarget (Debugger &debugger, 295a0ca6601SGreg Clayton const char *user_exe_path, 29670512317SGreg Clayton const ArchSpec& specified_arch, 29730fdc8d8SChris Lattner bool get_dependent_files, 298b3a40ba8SGreg Clayton PlatformSP &platform_sp, 299a0ca6601SGreg Clayton TargetSP &target_sp) 30030fdc8d8SChris Lattner { 30130fdc8d8SChris Lattner Timer scoped_timer (__PRETTY_FUNCTION__, 302a0ca6601SGreg Clayton "TargetList::CreateTarget (file = '%s', arch = '%s')", 303a0ca6601SGreg Clayton user_exe_path, 30470512317SGreg Clayton specified_arch.GetArchitectureName()); 3055aee162fSJim Ingham Error error; 3065aee162fSJim Ingham 30770512317SGreg Clayton ArchSpec arch(specified_arch); 30870512317SGreg Clayton 30970512317SGreg Clayton if (arch.IsValid()) 31070512317SGreg Clayton { 311b0cc53cfSGreg Clayton if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL)) 31270512317SGreg Clayton platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); 31370512317SGreg Clayton } 31470512317SGreg Clayton 31570512317SGreg Clayton if (!platform_sp) 31670512317SGreg Clayton platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); 317ded470d3SGreg Clayton 3188ae50eb4SGreg Clayton if (!arch.IsValid()) 3198ae50eb4SGreg Clayton arch = specified_arch; 3208ae50eb4SGreg Clayton 321d26206b5SJason Molenda FileSpec file (user_exe_path, false); 322d26206b5SJason Molenda if (!file.Exists() && user_exe_path && user_exe_path[0] == '~') 323d26206b5SJason Molenda { 3249f822cd1SMichael Sartain // we want to expand the tilde but we don't want to resolve any symbolic links 3259f822cd1SMichael Sartain // so we can't use the FileSpec constructor's resolve flag 3263f559740SZachary Turner llvm::SmallString<64> unglobbed_path(user_exe_path); 3273f559740SZachary Turner FileSpec::ResolveUsername(unglobbed_path); 3289f822cd1SMichael Sartain 3293f559740SZachary Turner if (unglobbed_path.empty()) 3303f559740SZachary Turner file = FileSpec(user_exe_path, false); 3313f559740SZachary Turner else 3323f559740SZachary Turner file = FileSpec(unglobbed_path.c_str(), false); 333d26206b5SJason Molenda } 3349f822cd1SMichael Sartain 33582d79295SGreg Clayton bool user_exe_path_is_bundle = false; 33682d79295SGreg Clayton char resolved_bundle_exe_path[PATH_MAX]; 33782d79295SGreg Clayton resolved_bundle_exe_path[0] = '\0'; 338e996fd30SGreg Clayton if (file) 3395aee162fSJim Ingham { 34082d79295SGreg Clayton if (file.GetFileType() == FileSpec::eFileTypeDirectory) 34182d79295SGreg Clayton user_exe_path_is_bundle = true; 34282d79295SGreg Clayton 343a0ca6601SGreg Clayton if (file.IsRelativeToCurrentWorkingDirectory()) 344a0ca6601SGreg Clayton { 345a0ca6601SGreg Clayton // Ignore paths that start with "./" and "../" 346a0ca6601SGreg Clayton if (!((user_exe_path[0] == '.' && user_exe_path[1] == '/') || 347a0ca6601SGreg Clayton (user_exe_path[0] == '.' && user_exe_path[1] == '.' && user_exe_path[2] == '/'))) 348a0ca6601SGreg Clayton { 349a0ca6601SGreg Clayton char cwd[PATH_MAX]; 350a0ca6601SGreg Clayton if (getcwd (cwd, sizeof(cwd))) 351a0ca6601SGreg Clayton { 352a0ca6601SGreg Clayton std::string cwd_user_exe_path (cwd); 353a0ca6601SGreg Clayton cwd_user_exe_path += '/'; 354a0ca6601SGreg Clayton cwd_user_exe_path += user_exe_path; 3559ff5aae5SGreg Clayton FileSpec cwd_file (cwd_user_exe_path.c_str(), false); 3569ff5aae5SGreg Clayton if (cwd_file.Exists()) 3579ff5aae5SGreg Clayton file = cwd_file; 358a0ca6601SGreg Clayton } 359a0ca6601SGreg Clayton } 360a0ca6601SGreg Clayton } 361a0ca6601SGreg Clayton 36230fdc8d8SChris Lattner ModuleSP exe_module_sp; 363e996fd30SGreg Clayton if (platform_sp) 364c859e2d5SGreg Clayton { 365c859e2d5SGreg Clayton FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths()); 36670512317SGreg Clayton error = platform_sp->ResolveExecutable (file, 36770512317SGreg Clayton arch, 368c859e2d5SGreg Clayton exe_module_sp, 369c859e2d5SGreg Clayton executable_search_paths.GetSize() ? &executable_search_paths : NULL); 370c859e2d5SGreg Clayton } 371428a9a58SCaroline Tice 372e996fd30SGreg Clayton if (error.Success() && exe_module_sp) 37330fdc8d8SChris Lattner { 3745aee162fSJim Ingham if (exe_module_sp->GetObjectFile() == NULL) 3755aee162fSJim Ingham { 376bc5cad6cSGreg Clayton if (arch.IsValid()) 377bc5cad6cSGreg Clayton { 378b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("\"%s\" doesn't contain architecture %s", 379b5ad4ec7SGreg Clayton file.GetPath().c_str(), 38064195a2cSGreg Clayton arch.GetArchitectureName()); 381bc5cad6cSGreg Clayton } 382bc5cad6cSGreg Clayton else 383bc5cad6cSGreg Clayton { 384b5ad4ec7SGreg Clayton error.SetErrorStringWithFormat("unsupported file type \"%s\"", 385b5ad4ec7SGreg Clayton file.GetPath().c_str()); 386bc5cad6cSGreg Clayton } 3875aee162fSJim Ingham return error; 3885aee162fSJim Ingham } 38932e0a750SGreg Clayton target_sp.reset(new Target(debugger, arch, platform_sp)); 39030fdc8d8SChris Lattner target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); 39182d79295SGreg Clayton if (user_exe_path_is_bundle) 39282d79295SGreg Clayton exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); 3935aee162fSJim Ingham } 3945aee162fSJim Ingham } 395e996fd30SGreg Clayton else 396e996fd30SGreg Clayton { 397e996fd30SGreg Clayton // No file was specified, just create an empty target with any arch 398e996fd30SGreg Clayton // if a valid arch was specified 39932e0a750SGreg Clayton target_sp.reset(new Target(debugger, arch, platform_sp)); 400e996fd30SGreg Clayton } 4011559a46bSCaroline Tice 402e996fd30SGreg Clayton if (target_sp) 403e996fd30SGreg Clayton { 40482d79295SGreg Clayton // Set argv0 with what the user typed, unless the user specified a 40582d79295SGreg Clayton // directory. If the user specified a directory, then it is probably a 40682d79295SGreg Clayton // bundle that was resolved and we need to use the resolved bundle path 407a0ca6601SGreg Clayton if (user_exe_path) 408a0ca6601SGreg Clayton { 409a0ca6601SGreg Clayton // Use exactly what the user typed as the first argument when we exec or posix_spawn 41082d79295SGreg Clayton if (user_exe_path_is_bundle && resolved_bundle_exe_path[0]) 41182d79295SGreg Clayton { 41282d79295SGreg Clayton target_sp->SetArg0 (resolved_bundle_exe_path); 41382d79295SGreg Clayton } 41482d79295SGreg Clayton else 41582d79295SGreg Clayton { 4169f822cd1SMichael Sartain // Use resolved path 4179f822cd1SMichael Sartain target_sp->SetArg0 (file.GetPath().c_str()); 418a0ca6601SGreg Clayton } 41982d79295SGreg Clayton } 420a0ca6601SGreg Clayton if (file.GetDirectory()) 421a0ca6601SGreg Clayton { 422a0ca6601SGreg Clayton FileSpec file_dir; 423a0ca6601SGreg Clayton file_dir.GetDirectory() = file.GetDirectory(); 424a0ca6601SGreg Clayton target_sp->GetExecutableSearchPaths ().Append (file_dir); 425a0ca6601SGreg Clayton } 42630fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 4272976d00aSJim Ingham m_selected_target_idx = m_target_list.size(); 42830fdc8d8SChris Lattner m_target_list.push_back(target_sp); 429a0ca6601SGreg Clayton 430a0ca6601SGreg Clayton 43130fdc8d8SChris Lattner } 43230fdc8d8SChris Lattner 43330fdc8d8SChris Lattner return error; 43430fdc8d8SChris Lattner } 43530fdc8d8SChris Lattner 43630fdc8d8SChris Lattner bool 43730fdc8d8SChris Lattner TargetList::DeleteTarget (TargetSP &target_sp) 43830fdc8d8SChris Lattner { 43930fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 44030fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 44130fdc8d8SChris Lattner 44230fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 44330fdc8d8SChris Lattner { 44430fdc8d8SChris Lattner if (pos->get() == target_sp.get()) 44530fdc8d8SChris Lattner { 44630fdc8d8SChris Lattner m_target_list.erase(pos); 44730fdc8d8SChris Lattner return true; 44830fdc8d8SChris Lattner } 44930fdc8d8SChris Lattner } 45030fdc8d8SChris Lattner return false; 45130fdc8d8SChris Lattner } 45230fdc8d8SChris Lattner 45330fdc8d8SChris Lattner 45430fdc8d8SChris Lattner TargetSP 45530fdc8d8SChris Lattner TargetList::FindTargetWithExecutableAndArchitecture 45630fdc8d8SChris Lattner ( 45730fdc8d8SChris Lattner const FileSpec &exe_file_spec, 45830fdc8d8SChris Lattner const ArchSpec *exe_arch_ptr 45930fdc8d8SChris Lattner ) const 46030fdc8d8SChris Lattner { 46130fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 46230fdc8d8SChris Lattner TargetSP target_sp; 463ddd7a2a6SSean Callanan bool full_match = (bool)exe_file_spec.GetDirectory(); 46430fdc8d8SChris Lattner 46530fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 46630fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 46730fdc8d8SChris Lattner { 468aa149cbdSGreg Clayton Module *exe_module = (*pos)->GetExecutableModulePointer(); 46930fdc8d8SChris Lattner 470aa149cbdSGreg Clayton if (exe_module) 47130fdc8d8SChris Lattner { 472aa149cbdSGreg Clayton if (FileSpec::Equal (exe_file_spec, exe_module->GetFileSpec(), full_match)) 47330fdc8d8SChris Lattner { 47430fdc8d8SChris Lattner if (exe_arch_ptr) 47530fdc8d8SChris Lattner { 476bf4b7be6SSean Callanan if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture())) 47730fdc8d8SChris Lattner continue; 47830fdc8d8SChris Lattner } 47930fdc8d8SChris Lattner target_sp = *pos; 48030fdc8d8SChris Lattner break; 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner } 48330fdc8d8SChris Lattner } 48430fdc8d8SChris Lattner return target_sp; 48530fdc8d8SChris Lattner } 48630fdc8d8SChris Lattner 48730fdc8d8SChris Lattner TargetSP 48830fdc8d8SChris Lattner TargetList::FindTargetWithProcessID (lldb::pid_t pid) const 48930fdc8d8SChris Lattner { 49030fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 49130fdc8d8SChris Lattner TargetSP target_sp; 49230fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 49330fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 49430fdc8d8SChris Lattner { 49530fdc8d8SChris Lattner Process* process = (*pos)->GetProcessSP().get(); 49630fdc8d8SChris Lattner if (process && process->GetID() == pid) 49730fdc8d8SChris Lattner { 49830fdc8d8SChris Lattner target_sp = *pos; 49930fdc8d8SChris Lattner break; 50030fdc8d8SChris Lattner } 50130fdc8d8SChris Lattner } 50230fdc8d8SChris Lattner return target_sp; 50330fdc8d8SChris Lattner } 50430fdc8d8SChris Lattner 50530fdc8d8SChris Lattner 50630fdc8d8SChris Lattner TargetSP 50730fdc8d8SChris Lattner TargetList::FindTargetWithProcess (Process *process) const 50830fdc8d8SChris Lattner { 50930fdc8d8SChris Lattner TargetSP target_sp; 51030fdc8d8SChris Lattner if (process) 51130fdc8d8SChris Lattner { 51230fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 51330fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 51430fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 51530fdc8d8SChris Lattner { 51630fdc8d8SChris Lattner if (process == (*pos)->GetProcessSP().get()) 51730fdc8d8SChris Lattner { 51830fdc8d8SChris Lattner target_sp = *pos; 51930fdc8d8SChris Lattner break; 52030fdc8d8SChris Lattner } 52130fdc8d8SChris Lattner } 52230fdc8d8SChris Lattner } 52330fdc8d8SChris Lattner return target_sp; 52430fdc8d8SChris Lattner } 52530fdc8d8SChris Lattner 52630fdc8d8SChris Lattner TargetSP 52730fdc8d8SChris Lattner TargetList::GetTargetSP (Target *target) const 52830fdc8d8SChris Lattner { 52930fdc8d8SChris Lattner TargetSP target_sp; 53030fdc8d8SChris Lattner if (target) 53130fdc8d8SChris Lattner { 53230fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 53330fdc8d8SChris Lattner collection::const_iterator pos, end = m_target_list.end(); 53430fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 53530fdc8d8SChris Lattner { 53630fdc8d8SChris Lattner if (target == (*pos).get()) 53730fdc8d8SChris Lattner { 53830fdc8d8SChris Lattner target_sp = *pos; 53930fdc8d8SChris Lattner break; 54030fdc8d8SChris Lattner } 54130fdc8d8SChris Lattner } 54230fdc8d8SChris Lattner } 54330fdc8d8SChris Lattner return target_sp; 54430fdc8d8SChris Lattner } 54530fdc8d8SChris Lattner 54630fdc8d8SChris Lattner uint32_t 54730fdc8d8SChris Lattner TargetList::SendAsyncInterrupt (lldb::pid_t pid) 54830fdc8d8SChris Lattner { 54930fdc8d8SChris Lattner uint32_t num_async_interrupts_sent = 0; 55030fdc8d8SChris Lattner 55130fdc8d8SChris Lattner if (pid != LLDB_INVALID_PROCESS_ID) 55230fdc8d8SChris Lattner { 55330fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 55430fdc8d8SChris Lattner if (target_sp.get()) 55530fdc8d8SChris Lattner { 55630fdc8d8SChris Lattner Process* process = target_sp->GetProcessSP().get(); 55730fdc8d8SChris Lattner if (process) 55830fdc8d8SChris Lattner { 559cfc0935eSJim Ingham process->SendAsyncInterrupt(); 56030fdc8d8SChris Lattner ++num_async_interrupts_sent; 56130fdc8d8SChris Lattner } 56230fdc8d8SChris Lattner } 56330fdc8d8SChris Lattner } 56430fdc8d8SChris Lattner else 56530fdc8d8SChris Lattner { 56630fdc8d8SChris Lattner // We don't have a valid pid to broadcast to, so broadcast to the target 56730fdc8d8SChris Lattner // list's async broadcaster... 56830fdc8d8SChris Lattner BroadcastEvent (Process::eBroadcastBitInterrupt, NULL); 56930fdc8d8SChris Lattner } 57030fdc8d8SChris Lattner 57130fdc8d8SChris Lattner return num_async_interrupts_sent; 57230fdc8d8SChris Lattner } 57330fdc8d8SChris Lattner 57430fdc8d8SChris Lattner uint32_t 57530fdc8d8SChris Lattner TargetList::SignalIfRunning (lldb::pid_t pid, int signo) 57630fdc8d8SChris Lattner { 57730fdc8d8SChris Lattner uint32_t num_signals_sent = 0; 57830fdc8d8SChris Lattner Process *process = NULL; 57930fdc8d8SChris Lattner if (pid == LLDB_INVALID_PROCESS_ID) 58030fdc8d8SChris Lattner { 58130fdc8d8SChris Lattner // Signal all processes with signal 58230fdc8d8SChris Lattner Mutex::Locker locker(m_target_list_mutex); 58330fdc8d8SChris Lattner collection::iterator pos, end = m_target_list.end(); 58430fdc8d8SChris Lattner for (pos = m_target_list.begin(); pos != end; ++pos) 58530fdc8d8SChris Lattner { 58630fdc8d8SChris Lattner process = (*pos)->GetProcessSP().get(); 58730fdc8d8SChris Lattner if (process) 58830fdc8d8SChris Lattner { 58930fdc8d8SChris Lattner if (process->IsAlive()) 59030fdc8d8SChris Lattner { 59130fdc8d8SChris Lattner ++num_signals_sent; 59230fdc8d8SChris Lattner process->Signal (signo); 59330fdc8d8SChris Lattner } 59430fdc8d8SChris Lattner } 59530fdc8d8SChris Lattner } 59630fdc8d8SChris Lattner } 59730fdc8d8SChris Lattner else 59830fdc8d8SChris Lattner { 59930fdc8d8SChris Lattner // Signal a specific process with signal 60030fdc8d8SChris Lattner TargetSP target_sp(FindTargetWithProcessID (pid)); 60130fdc8d8SChris Lattner if (target_sp.get()) 60230fdc8d8SChris Lattner { 60330fdc8d8SChris Lattner process = target_sp->GetProcessSP().get(); 60430fdc8d8SChris Lattner if (process) 60530fdc8d8SChris Lattner { 60630fdc8d8SChris Lattner if (process->IsAlive()) 60730fdc8d8SChris Lattner { 60830fdc8d8SChris Lattner ++num_signals_sent; 60930fdc8d8SChris Lattner process->Signal (signo); 61030fdc8d8SChris Lattner } 61130fdc8d8SChris Lattner } 61230fdc8d8SChris Lattner } 61330fdc8d8SChris Lattner } 61430fdc8d8SChris Lattner return num_signals_sent; 61530fdc8d8SChris Lattner } 61630fdc8d8SChris Lattner 61730fdc8d8SChris Lattner int 61830fdc8d8SChris Lattner TargetList::GetNumTargets () const 61930fdc8d8SChris Lattner { 62030fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 62130fdc8d8SChris Lattner return m_target_list.size(); 62230fdc8d8SChris Lattner } 62330fdc8d8SChris Lattner 62430fdc8d8SChris Lattner lldb::TargetSP 62530fdc8d8SChris Lattner TargetList::GetTargetAtIndex (uint32_t idx) const 62630fdc8d8SChris Lattner { 62730fdc8d8SChris Lattner TargetSP target_sp; 62830fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 62930fdc8d8SChris Lattner if (idx < m_target_list.size()) 63030fdc8d8SChris Lattner target_sp = m_target_list[idx]; 63130fdc8d8SChris Lattner return target_sp; 63230fdc8d8SChris Lattner } 63330fdc8d8SChris Lattner 63430fdc8d8SChris Lattner uint32_t 6358499e1a4SJim Ingham TargetList::GetIndexOfTarget (lldb::TargetSP target_sp) const 6368499e1a4SJim Ingham { 6378499e1a4SJim Ingham Mutex::Locker locker (m_target_list_mutex); 6388499e1a4SJim Ingham size_t num_targets = m_target_list.size(); 6398499e1a4SJim Ingham for (size_t idx = 0; idx < num_targets; idx++) 6408499e1a4SJim Ingham { 6418499e1a4SJim Ingham if (target_sp == m_target_list[idx]) 6428499e1a4SJim Ingham return idx; 6438499e1a4SJim Ingham } 6448499e1a4SJim Ingham return UINT32_MAX; 6458499e1a4SJim Ingham } 6468499e1a4SJim Ingham 6478499e1a4SJim Ingham uint32_t 6482976d00aSJim Ingham TargetList::SetSelectedTarget (Target* target) 64930fdc8d8SChris Lattner { 65030fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 65130fdc8d8SChris Lattner collection::const_iterator pos, 65230fdc8d8SChris Lattner begin = m_target_list.begin(), 65330fdc8d8SChris Lattner end = m_target_list.end(); 65430fdc8d8SChris Lattner for (pos = begin; pos != end; ++pos) 65530fdc8d8SChris Lattner { 65630fdc8d8SChris Lattner if (pos->get() == target) 65730fdc8d8SChris Lattner { 6582976d00aSJim Ingham m_selected_target_idx = std::distance (begin, pos); 6592976d00aSJim Ingham return m_selected_target_idx; 66030fdc8d8SChris Lattner } 66130fdc8d8SChris Lattner } 6622976d00aSJim Ingham m_selected_target_idx = 0; 6632976d00aSJim Ingham return m_selected_target_idx; 66430fdc8d8SChris Lattner } 66530fdc8d8SChris Lattner 66630fdc8d8SChris Lattner lldb::TargetSP 6672976d00aSJim Ingham TargetList::GetSelectedTarget () 66830fdc8d8SChris Lattner { 66930fdc8d8SChris Lattner Mutex::Locker locker (m_target_list_mutex); 6702976d00aSJim Ingham if (m_selected_target_idx >= m_target_list.size()) 6712976d00aSJim Ingham m_selected_target_idx = 0; 6722976d00aSJim Ingham return GetTargetAtIndex (m_selected_target_idx); 67330fdc8d8SChris Lattner } 674