diff options
Diffstat (limited to 'lldb/source/Target/TargetList.cpp')
| -rw-r--r-- | lldb/source/Target/TargetList.cpp | 114 |
1 files changed, 37 insertions, 77 deletions
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp index 595799cfc92a..214e98ee91ed 100644 --- a/lldb/source/Target/TargetList.cpp +++ b/lldb/source/Target/TargetList.cpp @@ -79,8 +79,9 @@ Status TargetList::CreateTargetInternal( const OptionGroupPlatform *platform_options, TargetSP &target_sp) { Status error; + PlatformList &platform_list = debugger.GetPlatformList(); // Let's start by looking at the selected platform. - PlatformSP platform_sp = debugger.GetPlatformList().GetSelectedPlatform(); + PlatformSP platform_sp = platform_list.GetSelectedPlatform(); // This variable corresponds to the architecture specified by the triple // string. If that string was empty the currently selected platform will @@ -120,6 +121,14 @@ Status TargetList::CreateTargetInternal( if (!user_exe_path.empty()) { ModuleSpec module_spec(FileSpec(user_exe_path, FileSpec::Style::native)); FileSystem::Instance().Resolve(module_spec.GetFileSpec()); + + // Try to resolve the exe based on PATH and/or platform-specific suffixes, + // but only if using the host platform. + if (platform_sp->IsHost() && + !FileSystem::Instance().Exists(module_spec.GetFileSpec())) + FileSystem::Instance().ResolveExecutableLocation( + module_spec.GetFileSpec()); + // Resolve the executable in case we are given a path to a application // bundle like a .app bundle on MacOSX. Host::ResolveExecutableInBundle(module_spec.GetFileSpec()); @@ -171,80 +180,30 @@ Status TargetList::CreateTargetInternal( } else { // Fat binary. No architecture specified, check if there is // only one platform for all of the architectures. - PlatformSP host_platform_sp = Platform::GetHostPlatform(); - std::vector<PlatformSP> platforms; - for (size_t i = 0; i < num_specs; ++i) { - ModuleSpec module_spec; - if (module_specs.GetModuleSpecAtIndex(i, module_spec)) { - // First consider the platform specified by the user, if any, and - // the selected platform otherwise. - if (platform_sp) { - if (platform_sp->IsCompatibleArchitecture( - module_spec.GetArchitecture(), false, nullptr)) { - platforms.push_back(platform_sp); - continue; - } - } - - // Now consider the host platform if it is different from the - // specified/selected platform. - if (host_platform_sp && - (!platform_sp || - host_platform_sp->GetName() != platform_sp->GetName())) { - if (host_platform_sp->IsCompatibleArchitecture( - module_spec.GetArchitecture(), false, nullptr)) { - platforms.push_back(host_platform_sp); - continue; - } - } - - // Finally find a platform that matches the architecture in the - // executable file. - PlatformSP fallback_platform_sp( - Platform::GetPlatformForArchitecture( - module_spec.GetArchitecture(), nullptr)); - if (fallback_platform_sp) { - platforms.push_back(fallback_platform_sp); - } - } - } - - Platform *platform_ptr = nullptr; - bool more_than_one_platforms = false; - for (const auto &the_platform_sp : platforms) { - if (platform_ptr) { - if (platform_ptr->GetName() != the_platform_sp->GetName()) { - more_than_one_platforms = true; - platform_ptr = nullptr; - break; - } - } else { - platform_ptr = the_platform_sp.get(); - } - } - - if (platform_ptr) { - // All platforms for all modules in the executable match, so we can - // select this platform. - platform_sp = platforms.front(); - } else if (!more_than_one_platforms) { - // No platforms claim to support this file. + std::vector<PlatformSP> candidates; + std::vector<ArchSpec> archs; + for (const ModuleSpec &spec : module_specs.ModuleSpecs()) + archs.push_back(spec.GetArchitecture()); + if (PlatformSP platform_for_archs_sp = + platform_list.GetOrCreate(archs, {}, candidates)) { + platform_sp = platform_for_archs_sp; + } else if (candidates.empty()) { error.SetErrorString("no matching platforms found for this file"); return error; } else { // More than one platform claims to support this file. StreamString error_strm; - std::set<Platform *> platform_set; + std::set<llvm::StringRef> platform_set; error_strm.Printf( "more than one platform supports this executable ("); - for (const auto &the_platform_sp : platforms) { - if (platform_set.find(the_platform_sp.get()) == - platform_set.end()) { - if (!platform_set.empty()) - error_strm.PutCString(", "); - error_strm.PutCString(the_platform_sp->GetName().GetCString()); - platform_set.insert(the_platform_sp.get()); - } + for (const auto &candidate : candidates) { + llvm::StringRef platform_name = candidate->GetName(); + if (platform_set.count(platform_name)) + continue; + if (!platform_set.empty()) + error_strm.PutCString(", "); + error_strm.PutCString(platform_name); + platform_set.insert(platform_name); } error_strm.Printf("), specify an architecture to disambiguate"); error.SetErrorString(error_strm.GetString()); @@ -257,20 +216,20 @@ Status TargetList::CreateTargetInternal( // If we have a valid architecture, make sure the current platform is // compatible with that architecture. if (!prefer_platform_arch && arch.IsValid()) { - if (!platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) { - platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch); + if (!platform_sp->IsCompatibleArchitecture(arch, {}, false, nullptr)) { + platform_sp = platform_list.GetOrCreate(arch, {}, &platform_arch); if (platform_sp) - debugger.GetPlatformList().SetSelectedPlatform(platform_sp); + platform_list.SetSelectedPlatform(platform_sp); } } else if (platform_arch.IsValid()) { // If "arch" isn't valid, yet "platform_arch" is, it means we have an // executable file with a single architecture which should be used. ArchSpec fixed_platform_arch; - if (!platform_sp->IsCompatibleArchitecture(platform_arch, false, nullptr)) { - platform_sp = Platform::GetPlatformForArchitecture(platform_arch, - &fixed_platform_arch); + if (!platform_sp->IsCompatibleArchitecture(platform_arch, {}, false, nullptr)) { + platform_sp = + platform_list.GetOrCreate(platform_arch, {}, &fixed_platform_arch); if (platform_sp) - debugger.GetPlatformList().SetSelectedPlatform(platform_sp); + platform_list.SetSelectedPlatform(platform_sp); } } @@ -298,8 +257,9 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, if (arch.IsValid()) { if (!platform_sp || - !platform_sp->IsCompatibleArchitecture(arch, false, nullptr)) - platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch); + !platform_sp->IsCompatibleArchitecture(arch, {}, false, nullptr)) + platform_sp = + debugger.GetPlatformList().GetOrCreate(specified_arch, {}, &arch); } if (!platform_sp) |
