diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 | 
| commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
| tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lldb/source/Target/RemoteAwarePlatform.cpp | |
| parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
Notes
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( | 
