mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 05:32:28 +08:00
[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:
@@ -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;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user