diff options
Diffstat (limited to 'lldb/source/Target/Platform.cpp')
| -rw-r--r-- | lldb/source/Target/Platform.cpp | 314 |
1 files changed, 179 insertions, 135 deletions
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index a77ecddfbab6..bd455310f08e 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -155,9 +155,9 @@ void Platform::Terminate() { } } -const PlatformPropertiesSP &Platform::GetGlobalPlatformProperties() { - static const auto g_settings_sp(std::make_shared<PlatformProperties>()); - return g_settings_sp; +PlatformProperties &Platform::GetGlobalPlatformProperties() { + static PlatformProperties g_settings; + return g_settings; } void Platform::SetHostPlatform(const lldb::PlatformSP &platform_sp) { @@ -294,8 +294,8 @@ PlatformSP Platform::Create(ConstString name, Status &error) { if (name == g_host_platform_name) return GetHostPlatform(); - create_callback = - PluginManager::GetPlatformCreateCallbackForPluginName(name); + create_callback = PluginManager::GetPlatformCreateCallbackForPluginName( + name.GetStringRef()); if (create_callback) platform_sp = create_callback(true, nullptr); else @@ -395,18 +395,10 @@ Platform::Platform(bool is_host) LLDB_LOGF(log, "%p Platform::Platform()", static_cast<void *>(this)); } -/// Destructor. -/// -/// The destructor is virtual since this class is designed to be -/// inherited from by the plug-in instance. -Platform::~Platform() { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); - LLDB_LOGF(log, "%p Platform::~Platform()", static_cast<void *>(this)); -} +Platform::~Platform() = default; void Platform::GetStatus(Stream &strm) { - std::string s; - strm.Printf(" Platform: %s\n", GetPluginName().GetCString()); + strm.Format(" Platform: {0}\n", GetPluginName()); ArchSpec arch(GetSystemArchitecture()); if (arch.IsValid()) { @@ -421,8 +413,8 @@ void Platform::GetStatus(Stream &strm) { if (!os_version.empty()) { strm.Format("OS Version: {0}", os_version.getAsString()); - if (GetOSBuildString(s)) - strm.Printf(" (%s)", s.c_str()); + if (llvm::Optional<std::string> s = GetOSBuildString()) + strm.Format(" ({0})", *s); strm.EOL(); } @@ -447,8 +439,8 @@ void Platform::GetStatus(Stream &strm) { if (!specific_info.empty()) strm.Printf("Platform-specific connection: %s\n", specific_info.c_str()); - if (GetOSKernelDescription(s)) - strm.Printf(" Kernel: %s\n", s.c_str()); + if (llvm::Optional<std::string> s = GetOSKernelDescription()) + strm.Format(" Kernel: {0}\n", *s); } llvm::VersionTuple Platform::GetOSVersion(Process *process) { @@ -493,28 +485,16 @@ llvm::VersionTuple Platform::GetOSVersion(Process *process) { return llvm::VersionTuple(); } -bool Platform::GetOSBuildString(std::string &s) { - s.clear(); - +llvm::Optional<std::string> Platform::GetOSBuildString() { if (IsHost()) -#if !defined(__linux__) - return HostInfo::GetOSBuildString(s); -#else - return false; -#endif - else - return GetRemoteOSBuildString(s); + return HostInfo::GetOSBuildString(); + return GetRemoteOSBuildString(); } -bool Platform::GetOSKernelDescription(std::string &s) { +llvm::Optional<std::string> Platform::GetOSKernelDescription() { if (IsHost()) -#if !defined(__linux__) - return HostInfo::GetOSKernelDescription(s); -#else - return false; -#endif - else - return GetRemoteOSKernelDescription(s); + return HostInfo::GetOSKernelDescription(); + return GetRemoteOSKernelDescription(); } void Platform::AddClangModuleCompilationOptions( @@ -769,9 +749,8 @@ Status Platform::MakeDirectory(const FileSpec &file_spec, return llvm::sys::fs::create_directory(file_spec.GetPath(), permissions); else { Status error; - error.SetErrorStringWithFormat("remote platform %s doesn't support %s", - GetPluginName().GetCString(), - LLVM_PRETTY_FUNCTION); + error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", + GetPluginName(), LLVM_PRETTY_FUNCTION); return error; } } @@ -785,9 +764,8 @@ Status Platform::GetFilePermissions(const FileSpec &file_spec, return Status(Value.getError()); } else { Status error; - error.SetErrorStringWithFormat("remote platform %s doesn't support %s", - GetPluginName().GetCString(), - LLVM_PRETTY_FUNCTION); + error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", + GetPluginName(), LLVM_PRETTY_FUNCTION); return error; } } @@ -799,14 +777,13 @@ Status Platform::SetFilePermissions(const FileSpec &file_spec, return llvm::sys::fs::setPermissions(file_spec.GetPath(), Perms); } else { Status error; - error.SetErrorStringWithFormat("remote platform %s doesn't support %s", - GetPluginName().GetCString(), - LLVM_PRETTY_FUNCTION); + error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}", + GetPluginName(), LLVM_PRETTY_FUNCTION); return error; } } -ConstString Platform::GetName() { return GetPluginName(); } +ConstString Platform::GetName() { return ConstString(GetPluginName()); } const char *Platform::GetHostname() { if (IsHost()) @@ -856,6 +833,7 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Status error; + if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { if (module_spec.GetArchitecture().IsValid()) { error = ModuleList::GetSharedModule(module_spec, exe_module_sp, @@ -866,9 +844,8 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, // architectures that we should be using (in the correct order) and see // if we can find a match that way ModuleSpec arch_module_spec(module_spec); - for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( - idx, arch_module_spec.GetArchitecture()); - ++idx) { + for (const ArchSpec &arch : GetSupportedArchitectures()) { + arch_module_spec.GetArchitecture() = arch; error = ModuleList::GetSharedModule(arch_module_spec, exe_module_sp, module_search_paths_ptr, nullptr, nullptr); @@ -878,9 +855,74 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, } } } else { - error.SetErrorStringWithFormat("'%s' does not exist", - module_spec.GetFileSpec().GetPath().c_str()); + error.SetErrorStringWithFormat( + "'%s' does not exist", module_spec.GetFileSpec().GetPath().c_str()); + } + return error; +} + +Status +Platform::ResolveRemoteExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) { + Status error; + + // We may connect to a process and use the provided executable (Don't use + // local $PATH). + ModuleSpec resolved_module_spec(module_spec); + + // Resolve any executable within a bundle on MacOSX + Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); + + if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()) || + module_spec.GetUUID().IsValid()) { + if (resolved_module_spec.GetArchitecture().IsValid() || + resolved_module_spec.GetUUID().IsValid()) { + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, nullptr, + nullptr); + + if (exe_module_sp && exe_module_sp->GetObjectFile()) + return error; + exe_module_sp.reset(); + } + // No valid architecture was specified or the exact arch wasn't found so + // ask the platform for the architectures that we should be using (in the + // correct order) and see if we can find a match that way + StreamString arch_names; + llvm::ListSeparator LS; + for (const ArchSpec &arch : GetSupportedArchitectures()) { + resolved_module_spec.GetArchitecture() = arch; + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, nullptr, + nullptr); + // Did we find an executable using one of the + if (error.Success()) { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); + } + + arch_names << LS << arch.GetArchitectureName(); + } + + if (error.Fail() || !exe_module_sp) { + if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) { + error.SetErrorStringWithFormatv( + "'{0}' doesn't contain any '{1}' platform architectures: {2}", + resolved_module_spec.GetFileSpec(), GetPluginName(), + arch_names.GetData()); + } else { + error.SetErrorStringWithFormatv("'{0}' is not readable", + resolved_module_spec.GetFileSpec()); + } + } + } else { + error.SetErrorStringWithFormatv("'{0}' does not exist", + resolved_module_spec.GetFileSpec()); } + return error; } @@ -966,26 +1008,27 @@ ArchSpec Platform::GetAugmentedArchSpec(llvm::StringRef triple) { Status Platform::ConnectRemote(Args &args) { Status error; if (IsHost()) - error.SetErrorStringWithFormat("The currently selected platform (%s) is " - "the host platform and is always connected.", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "The currently selected platform ({0}) is " + "the host platform and is always connected.", + GetPluginName()); else - error.SetErrorStringWithFormat( - "Platform::ConnectRemote() is not supported by %s", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "Platform::ConnectRemote() is not supported by {0}", GetPluginName()); return error; } Status Platform::DisconnectRemote() { Status error; if (IsHost()) - error.SetErrorStringWithFormat("The currently selected platform (%s) is " - "the host platform and is always connected.", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "The currently selected platform ({0}) is " + "the host platform and is always connected.", + GetPluginName()); else - error.SetErrorStringWithFormat( - "Platform::DisconnectRemote() is not supported by %s", - GetPluginName().GetCString()); + error.SetErrorStringWithFormatv( + "Platform::DisconnectRemote() is not supported by {0}", + GetPluginName()); return error; } @@ -1066,36 +1109,19 @@ Status Platform::KillProcess(const lldb::pid_t pid) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); LLDB_LOGF(log, "Platform::%s, pid %" PRIu64, __FUNCTION__, pid); - // Try to find a process plugin to handle this Kill request. If we can't, - // fall back to the default OS implementation. - size_t num_debuggers = Debugger::GetNumDebuggers(); - for (size_t didx = 0; didx < num_debuggers; ++didx) { - DebuggerSP debugger = Debugger::GetDebuggerAtIndex(didx); - lldb_private::TargetList &targets = debugger->GetTargetList(); - for (int tidx = 0; tidx < targets.GetNumTargets(); ++tidx) { - ProcessSP process = targets.GetTargetAtIndex(tidx)->GetProcessSP(); - if (process->GetID() == pid) - return process->Destroy(true); - } - } - if (!IsHost()) { return Status( - "base lldb_private::Platform class can't kill remote processes unless " - "they are controlled by a process plugin"); + "base lldb_private::Platform class can't kill remote processes"); } - Host::Kill(pid, SIGTERM); + Host::Kill(pid, SIGKILL); return Status(); } -lldb::ProcessSP -Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, - Target *target, // Can be nullptr, if nullptr create a - // new target, else use existing one - Status &error) { +lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info, + Debugger &debugger, Target &target, + Status &error) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); - LLDB_LOGF(log, "Platform::%s entered (target %p)", __FUNCTION__, - static_cast<void *>(target)); + LLDB_LOG(log, "target = {0})", &target); ProcessSP process_sp; // Make sure we stop at the entry point @@ -1117,7 +1143,7 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, filter_callback = get_filter_func(++i, iteration_complete)) { if (filter_callback) { // Give this ProcessLaunchInfo filter a chance to adjust the launch info. - error = (*filter_callback)(launch_info, target); + error = (*filter_callback)(launch_info, &target); if (!error.Success()) { LLDB_LOGF(log, "Platform::%s() StructuredDataPlugin launch " @@ -1135,10 +1161,10 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, __FUNCTION__, launch_info.GetProcessID()); if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) { ProcessAttachInfo attach_info(launch_info); - process_sp = Attach(attach_info, debugger, target, error); + process_sp = Attach(attach_info, debugger, &target, error); if (process_sp) { - LLDB_LOGF(log, "Platform::%s Attach() succeeded, Process plugin: %s", - __FUNCTION__, process_sp->GetPluginName().AsCString()); + LLDB_LOG(log, "Attach() succeeded, Process plugin: {0}", + process_sp->GetPluginName()); launch_info.SetHijackListener(attach_info.GetHijackListener()); // Since we attached to the process, it will think it needs to detach @@ -1149,7 +1175,7 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, // If we didn't have any file actions, the pseudo terminal might have // been used where the secondary side was given as the file to open for - // stdin/out/err after we have already opened the master so we can + // stdin/out/err after we have already opened the primary so we can // read/write stdin/out/err. int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor(); if (pty_fd != PseudoTerminal::invalid_fd) { @@ -1183,6 +1209,35 @@ Platform::GetPlatformForArchitecture(const ArchSpec &arch, return platform_sp; } +std::vector<ArchSpec> +Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs, + llvm::Triple::OSType os) { + std::vector<ArchSpec> list; + for(auto arch : archs) { + llvm::Triple triple; + triple.setArch(arch); + triple.setOS(os); + list.push_back(ArchSpec(triple)); + } + return list; +} + +bool Platform::GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) { + const auto &archs = GetSupportedArchitectures(); + if (idx >= archs.size()) + return false; + arch = archs[idx]; + return true; +} + +std::vector<ArchSpec> Platform::GetSupportedArchitectures() { + std::vector<ArchSpec> result; + ArchSpec arch; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(idx, arch); ++idx) + result.push_back(arch); + return result; +} + /// Lets a platform answer if it is compatible with a given /// architecture and the target triple contained within. bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, @@ -1191,26 +1246,13 @@ bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, // If the architecture is invalid, we must answer true... if (arch.IsValid()) { ArchSpec platform_arch; - // Try for an exact architecture match first. - if (exact_arch_match) { - for (uint32_t arch_idx = 0; - GetSupportedArchitectureAtIndex(arch_idx, platform_arch); - ++arch_idx) { - if (arch.IsExactMatch(platform_arch)) { - if (compatible_arch_ptr) - *compatible_arch_ptr = platform_arch; - return true; - } - } - } else { - for (uint32_t arch_idx = 0; - GetSupportedArchitectureAtIndex(arch_idx, platform_arch); - ++arch_idx) { - if (arch.IsCompatibleMatch(platform_arch)) { - if (compatible_arch_ptr) - *compatible_arch_ptr = platform_arch; - return true; - } + auto match = exact_arch_match ? &ArchSpec::IsExactMatch + : &ArchSpec::IsCompatibleMatch; + for (const ArchSpec &platform_arch : GetSupportedArchitectures()) { + if ((arch.*match)(platform_arch)) { + if (compatible_arch_ptr) + *compatible_arch_ptr = platform_arch; + return true; } } } @@ -1225,7 +1267,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, LLDB_LOGF(log, "[PutFile] Using block by block transfer....\n"); auto source_open_options = - File::eOpenOptionRead | File::eOpenOptionCloseOnExec; + File::eOpenOptionReadOnly | File::eOpenOptionCloseOnExec; namespace fs = llvm::sys::fs; if (fs::is_symlink_file(source.GetPath())) source_open_options |= File::eOpenOptionDontFollowSymlinks; @@ -1240,7 +1282,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, permissions = lldb::eFilePermissionsFileDefault; lldb::user_id_t dest_file = OpenFile( - destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | + destination, File::eOpenOptionCanCreate | File::eOpenOptionWriteOnly | File::eOpenOptionTruncate | File::eOpenOptionCloseOnExec, permissions, error); LLDB_LOGF(log, "dest_file = %" PRIu64 "\n", dest_file); @@ -1517,12 +1559,13 @@ const std::vector<ConstString> &Platform::GetTrapHandlerSymbolNames() { return m_trap_handlers; } -Status Platform::GetCachedExecutable( - ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, Platform &remote_platform) { +Status +Platform::GetCachedExecutable(ModuleSpec &module_spec, + lldb::ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr) { const auto platform_spec = module_spec.GetFileSpec(); - const auto error = LoadCachedExecutable( - module_spec, module_sp, module_search_paths_ptr, remote_platform); + const auto error = + LoadCachedExecutable(module_spec, module_sp, module_search_paths_ptr); if (error.Success()) { module_spec.GetFileSpec() = module_sp->GetFileSpec(); module_spec.GetPlatformFileSpec() = platform_spec; @@ -1531,15 +1574,17 @@ Status Platform::GetCachedExecutable( return error; } -Status Platform::LoadCachedExecutable( - const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, Platform &remote_platform) { - return GetRemoteSharedModule(module_spec, nullptr, module_sp, - [&](const ModuleSpec &spec) { - return remote_platform.ResolveExecutable( - spec, module_sp, module_search_paths_ptr); - }, - nullptr); +Status +Platform::LoadCachedExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr) { + return GetRemoteSharedModule( + module_spec, nullptr, module_sp, + [&](const ModuleSpec &spec) { + return ResolveRemoteExecutable(spec, module_sp, + module_search_paths_ptr); + }, + nullptr); } Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, @@ -1568,9 +1613,8 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, // architectures that we should be using (in the correct order) and see if // we can find a match that way ModuleSpec arch_module_spec(module_spec); - for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( - idx, arch_module_spec.GetArchitecture()); - ++idx) { + for (const ArchSpec &arch : GetSupportedArchitectures()) { + arch_module_spec.GetArchitecture() = arch; error = ModuleList::GetSharedModule(arch_module_spec, module_sp, nullptr, nullptr, nullptr); // Did we find an executable using one of the @@ -1619,8 +1663,8 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, bool Platform::GetCachedSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, bool *did_create_ptr) { - if (IsHost() || !GetGlobalPlatformProperties()->GetUseModuleCache() || - !GetGlobalPlatformProperties()->GetModuleCacheDirectory()) + if (IsHost() || !GetGlobalPlatformProperties().GetUseModuleCache() || + !GetGlobalPlatformProperties().GetModuleCacheDirectory()) return false; Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); @@ -1663,7 +1707,7 @@ Status Platform::DownloadModuleSlice(const FileSpec &src_file_spec, return error; } - auto src_fd = OpenFile(src_file_spec, File::eOpenOptionRead, + auto src_fd = OpenFile(src_file_spec, File::eOpenOptionReadOnly, lldb::eFilePermissionsFileDefault, error); if (error.Fail()) { @@ -1704,7 +1748,7 @@ Status Platform::DownloadSymbolFile(const lldb::ModuleSP &module_sp, } FileSpec Platform::GetModuleCacheRoot() { - auto dir_spec = GetGlobalPlatformProperties()->GetModuleCacheDirectory(); + auto dir_spec = GetGlobalPlatformProperties().GetModuleCacheDirectory(); dir_spec.AppendPathComponent(GetName().AsCString()); return dir_spec; } |
