[lldb] Merge PlatformXXX::ResolveExecutable

The near-identical implementations of this function for posix-y
platforms were merged in r293910. PlatformWindows was left out of this
merge because at the time we did not have a suitable base class to sink
the code into. That is no longer true, so this commit finishes the job
by moving the code into RemoteAwarePlatform::ResolveExecutable.
This commit is contained in:
Pavel Labath
2020-05-13 13:21:59 +02:00
parent 18a5428e60
commit e072b20bde
6 changed files with 150 additions and 257 deletions

View File

@@ -22,6 +22,10 @@ public:
bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch,
ModuleSpec &module_spec) override;
Status
ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr) override;
lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags,
uint32_t mode, Status &error) override;

View File

@@ -11,7 +11,6 @@
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/DiagnosticManager.h"
#include "lldb/Expression/FunctionCaller.h"
@@ -64,148 +63,6 @@ lldb_private::OptionGroupOptions *PlatformPOSIX::GetConnectionOptions(
return m_options.at(&interpreter).get();
}
Status
PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec,
lldb::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) {
error =
GetCachedExecutable(resolved_module_spec, exe_module_sp,
module_search_paths_ptr, *m_remote_platform_sp);
} else {
// 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;
}
static uint32_t chown_file(Platform *platform, const char *path,
uint32_t uid = UINT32_MAX,
uint32_t gid = UINT32_MAX) {

View File

@@ -37,10 +37,6 @@ public:
const lldb::UnixSignalsSP &GetRemoteUnixSignals() override;
lldb_private::Status ResolveExecutable(
const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
const lldb_private::FileSpecList *module_search_paths_ptr) override;
lldb::ProcessSP Attach(lldb_private::ProcessAttachInfo &attach_info,
lldb_private::Debugger &debugger,
lldb_private::Target *target, // Can be nullptr, if

View File

@@ -18,7 +18,6 @@
#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
@@ -158,110 +157,6 @@ PlatformWindows::PlatformWindows(bool is_host) : RemoteAwarePlatform(is_host) {}
/// inherited from by the plug-in instance.
PlatformWindows::~PlatformWindows() = default;
Status PlatformWindows::ResolveExecutable(
const ModuleSpec &ms, lldb::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(ms);
if (IsHost()) {
// if we cant resolve the executable loation 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());
if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()))
error.Clear();
else {
ms.GetFileSpec().GetPath(exe_path, sizeof(exe_path));
error.SetErrorStringWithFormat("unable to find executable for '%s'",
exe_path);
}
} else {
if (m_remote_platform_sp) {
error =
GetCachedExecutable(resolved_module_spec, exe_module_sp,
module_search_paths_ptr, *m_remote_platform_sp);
} else {
// We may connect to a process and use the provided executable (Don't use
// local $PATH).
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,
nullptr, nullptr, nullptr);
if (!exe_module_sp || exe_module_sp->GetObjectFile() == nullptr) {
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 PlatformWindows::ConnectRemote(Args &args) {
Status error;
if (IsHost()) {

View File

@@ -36,11 +36,6 @@ public:
uint32_t GetPluginVersion() override { return 1; }
// lldb_private::Platform functions
Status
ResolveExecutable(const lldb_private::ModuleSpec &module_spec,
lldb::ModuleSP &module_sp,
const FileSpecList *module_search_paths_ptr) override;
const char *GetDescription() override {
return GetPluginDescriptionStatic(IsHost());
}

View File

@@ -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,
@@ -24,6 +29,147 @@ bool RemoteAwarePlatform::GetModuleSpec(const FileSpec &module_file_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) {
error =
GetCachedExecutable(resolved_module_spec, exe_module_sp,
module_search_paths_ptr, *m_remote_platform_sp);
} else {
// 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(
const char *command, const FileSpec &working_dir, int *status_ptr,
int *signo_ptr, std::string *command_output,