diff options
Diffstat (limited to 'lldb/source/Target/RemoteAwarePlatform.cpp')
-rw-r--r-- | lldb/source/Target/RemoteAwarePlatform.cpp | 150 |
1 files changed, 148 insertions, 2 deletions
diff --git a/lldb/source/Target/RemoteAwarePlatform.cpp b/lldb/source/Target/RemoteAwarePlatform.cpp index faa217ac83ef..f53158b06b8f 100644 --- a/lldb/source/Target/RemoteAwarePlatform.cpp +++ b/lldb/source/Target/RemoteAwarePlatform.cpp @@ -1,4 +1,4 @@ -//===-- RemoteAwarePlatform.cpp ---------------------------------*- C++ -*-===// +//===-- RemoteAwarePlatform.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,12 +7,17 @@ //===----------------------------------------------------------------------===// #include "lldb/Target/RemoteAwarePlatform.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileCache.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Utility/StreamString.h" using namespace lldb_private; +using namespace lldb; bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, @@ -21,7 +26,148 @@ bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_spec, return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch, module_spec); - return Platform::GetModuleSpec(module_file_spec, arch, module_spec); + return false; +} + +Status RemoteAwarePlatform::ResolveExecutable( + const ModuleSpec &module_spec, ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) { + Status error; + // Nothing special to do here, just use the actual file and architecture + + char exe_path[PATH_MAX]; + ModuleSpec resolved_module_spec(module_spec); + + if (IsHost()) { + // If we have "ls" as the exe_file, resolve the executable location based + // on the current path variables + if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) { + resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); + resolved_module_spec.GetFileSpec().SetFile(exe_path, + FileSpec::Style::native); + FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec()); + } + + if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) + FileSystem::Instance().ResolveExecutableLocation( + resolved_module_spec.GetFileSpec()); + + // Resolve any executable within a bundle on MacOSX + Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); + + if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) + error.Clear(); + else { + const uint32_t permissions = FileSystem::Instance().GetPermissions( + resolved_module_spec.GetFileSpec()); + if (permissions && (permissions & eFilePermissionsEveryoneR) == 0) + error.SetErrorStringWithFormat( + "executable '%s' is not readable", + resolved_module_spec.GetFileSpec().GetPath().c_str()); + else + error.SetErrorStringWithFormat( + "unable to find executable for '%s'", + resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } else { + if (m_remote_platform_sp) { + return GetCachedExecutable(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, + *m_remote_platform_sp); + } + + // We may connect to a process and use the provided executable (Don't use + // local $PATH). + + // Resolve any executable within a bundle on MacOSX + Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); + + if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) + error.Clear(); + else + error.SetErrorStringWithFormat("the platform is not currently " + "connected, and '%s' doesn't exist in " + "the system root.", + exe_path); + } + + if (error.Success()) { + if (resolved_module_spec.GetArchitecture().IsValid()) { + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + module_search_paths_ptr, nullptr, nullptr); + if (error.Fail()) { + // If we failed, it may be because the vendor and os aren't known. If + // that is the case, try setting them to the host architecture and give + // it another try. + llvm::Triple &module_triple = + resolved_module_spec.GetArchitecture().GetTriple(); + bool is_vendor_specified = + (module_triple.getVendor() != llvm::Triple::UnknownVendor); + bool is_os_specified = + (module_triple.getOS() != llvm::Triple::UnknownOS); + if (!is_vendor_specified || !is_os_specified) { + const llvm::Triple &host_triple = + HostInfo::GetArchitecture(HostInfo::eArchKindDefault).GetTriple(); + + if (!is_vendor_specified) + module_triple.setVendorName(host_triple.getVendorName()); + if (!is_os_specified) + module_triple.setOSName(host_triple.getOSName()); + + error = ModuleList::GetSharedModule(resolved_module_spec, + exe_module_sp, module_search_paths_ptr, nullptr, nullptr); + } + } + + // TODO find out why exe_module_sp might be NULL + if (error.Fail() || !exe_module_sp || !exe_module_sp->GetObjectFile()) { + exe_module_sp.reset(); + error.SetErrorStringWithFormat( + "'%s' doesn't contain the architecture %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + } else { + // No valid architecture was specified, 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; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( + idx, resolved_module_spec.GetArchitecture()); + ++idx) { + 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(); + } + + if (idx > 0) + arch_names.PutCString(", "); + arch_names.PutCString( + resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + + if (error.Fail() || !exe_module_sp) { + if (FileSystem::Instance().Readable( + resolved_module_spec.GetFileSpec())) { + error.SetErrorStringWithFormat( + "'%s' doesn't contain any '%s' platform architectures: %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + GetPluginName().GetCString(), arch_names.GetData()); + } else { + error.SetErrorStringWithFormat( + "'%s' is not readable", + resolved_module_spec.GetFileSpec().GetPath().c_str()); + } + } + } + } + + return error; } Status RemoteAwarePlatform::RunShellCommand( |