summaryrefslogtreecommitdiff
path: root/lldb/source/Target/RemoteAwarePlatform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/RemoteAwarePlatform.cpp')
-rw-r--r--lldb/source/Target/RemoteAwarePlatform.cpp150
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(