aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Target/Platform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/Platform.cpp')
-rw-r--r--lldb/source/Target/Platform.cpp314
1 files changed, 179 insertions, 135 deletions
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index a77ecddfbab6..bd455310f08e 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -155,9 +155,9 @@ void Platform::Terminate() {
}
}
-const PlatformPropertiesSP &Platform::GetGlobalPlatformProperties() {
- static const auto g_settings_sp(std::make_shared<PlatformProperties>());
- return g_settings_sp;
+PlatformProperties &Platform::GetGlobalPlatformProperties() {
+ static PlatformProperties g_settings;
+ return g_settings;
}
void Platform::SetHostPlatform(const lldb::PlatformSP &platform_sp) {
@@ -294,8 +294,8 @@ PlatformSP Platform::Create(ConstString name, Status &error) {
if (name == g_host_platform_name)
return GetHostPlatform();
- create_callback =
- PluginManager::GetPlatformCreateCallbackForPluginName(name);
+ create_callback = PluginManager::GetPlatformCreateCallbackForPluginName(
+ name.GetStringRef());
if (create_callback)
platform_sp = create_callback(true, nullptr);
else
@@ -395,18 +395,10 @@ Platform::Platform(bool is_host)
LLDB_LOGF(log, "%p Platform::Platform()", static_cast<void *>(this));
}
-/// Destructor.
-///
-/// The destructor is virtual since this class is designed to be
-/// inherited from by the plug-in instance.
-Platform::~Platform() {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- LLDB_LOGF(log, "%p Platform::~Platform()", static_cast<void *>(this));
-}
+Platform::~Platform() = default;
void Platform::GetStatus(Stream &strm) {
- std::string s;
- strm.Printf(" Platform: %s\n", GetPluginName().GetCString());
+ strm.Format(" Platform: {0}\n", GetPluginName());
ArchSpec arch(GetSystemArchitecture());
if (arch.IsValid()) {
@@ -421,8 +413,8 @@ void Platform::GetStatus(Stream &strm) {
if (!os_version.empty()) {
strm.Format("OS Version: {0}", os_version.getAsString());
- if (GetOSBuildString(s))
- strm.Printf(" (%s)", s.c_str());
+ if (llvm::Optional<std::string> s = GetOSBuildString())
+ strm.Format(" ({0})", *s);
strm.EOL();
}
@@ -447,8 +439,8 @@ void Platform::GetStatus(Stream &strm) {
if (!specific_info.empty())
strm.Printf("Platform-specific connection: %s\n", specific_info.c_str());
- if (GetOSKernelDescription(s))
- strm.Printf(" Kernel: %s\n", s.c_str());
+ if (llvm::Optional<std::string> s = GetOSKernelDescription())
+ strm.Format(" Kernel: {0}\n", *s);
}
llvm::VersionTuple Platform::GetOSVersion(Process *process) {
@@ -493,28 +485,16 @@ llvm::VersionTuple Platform::GetOSVersion(Process *process) {
return llvm::VersionTuple();
}
-bool Platform::GetOSBuildString(std::string &s) {
- s.clear();
-
+llvm::Optional<std::string> Platform::GetOSBuildString() {
if (IsHost())
-#if !defined(__linux__)
- return HostInfo::GetOSBuildString(s);
-#else
- return false;
-#endif
- else
- return GetRemoteOSBuildString(s);
+ return HostInfo::GetOSBuildString();
+ return GetRemoteOSBuildString();
}
-bool Platform::GetOSKernelDescription(std::string &s) {
+llvm::Optional<std::string> Platform::GetOSKernelDescription() {
if (IsHost())
-#if !defined(__linux__)
- return HostInfo::GetOSKernelDescription(s);
-#else
- return false;
-#endif
- else
- return GetRemoteOSKernelDescription(s);
+ return HostInfo::GetOSKernelDescription();
+ return GetRemoteOSKernelDescription();
}
void Platform::AddClangModuleCompilationOptions(
@@ -769,9 +749,8 @@ Status Platform::MakeDirectory(const FileSpec &file_spec,
return llvm::sys::fs::create_directory(file_spec.GetPath(), permissions);
else {
Status error;
- error.SetErrorStringWithFormat("remote platform %s doesn't support %s",
- GetPluginName().GetCString(),
- LLVM_PRETTY_FUNCTION);
+ error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}",
+ GetPluginName(), LLVM_PRETTY_FUNCTION);
return error;
}
}
@@ -785,9 +764,8 @@ Status Platform::GetFilePermissions(const FileSpec &file_spec,
return Status(Value.getError());
} else {
Status error;
- error.SetErrorStringWithFormat("remote platform %s doesn't support %s",
- GetPluginName().GetCString(),
- LLVM_PRETTY_FUNCTION);
+ error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}",
+ GetPluginName(), LLVM_PRETTY_FUNCTION);
return error;
}
}
@@ -799,14 +777,13 @@ Status Platform::SetFilePermissions(const FileSpec &file_spec,
return llvm::sys::fs::setPermissions(file_spec.GetPath(), Perms);
} else {
Status error;
- error.SetErrorStringWithFormat("remote platform %s doesn't support %s",
- GetPluginName().GetCString(),
- LLVM_PRETTY_FUNCTION);
+ error.SetErrorStringWithFormatv("remote platform {0} doesn't support {1}",
+ GetPluginName(), LLVM_PRETTY_FUNCTION);
return error;
}
}
-ConstString Platform::GetName() { return GetPluginName(); }
+ConstString Platform::GetName() { return ConstString(GetPluginName()); }
const char *Platform::GetHostname() {
if (IsHost())
@@ -856,6 +833,7 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec,
lldb::ModuleSP &exe_module_sp,
const FileSpecList *module_search_paths_ptr) {
Status error;
+
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
if (module_spec.GetArchitecture().IsValid()) {
error = ModuleList::GetSharedModule(module_spec, exe_module_sp,
@@ -866,9 +844,8 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec,
// architectures that we should be using (in the correct order) and see
// if we can find a match that way
ModuleSpec arch_module_spec(module_spec);
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, arch_module_spec.GetArchitecture());
- ++idx) {
+ for (const ArchSpec &arch : GetSupportedArchitectures()) {
+ arch_module_spec.GetArchitecture() = arch;
error = ModuleList::GetSharedModule(arch_module_spec, exe_module_sp,
module_search_paths_ptr, nullptr,
nullptr);
@@ -878,9 +855,74 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec,
}
}
} else {
- error.SetErrorStringWithFormat("'%s' does not exist",
- module_spec.GetFileSpec().GetPath().c_str());
+ error.SetErrorStringWithFormat(
+ "'%s' does not exist", module_spec.GetFileSpec().GetPath().c_str());
+ }
+ return error;
+}
+
+Status
+Platform::ResolveRemoteExecutable(const ModuleSpec &module_spec,
+ lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ Status error;
+
+ // We may connect to a process and use the provided executable (Don't use
+ // local $PATH).
+ ModuleSpec resolved_module_spec(module_spec);
+
+ // Resolve any executable within a bundle on MacOSX
+ Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
+
+ if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()) ||
+ module_spec.GetUUID().IsValid()) {
+ if (resolved_module_spec.GetArchitecture().IsValid() ||
+ resolved_module_spec.GetUUID().IsValid()) {
+ error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
+ module_search_paths_ptr, nullptr,
+ nullptr);
+
+ if (exe_module_sp && exe_module_sp->GetObjectFile())
+ return error;
+ exe_module_sp.reset();
+ }
+ // No valid architecture was specified or the exact arch wasn't found so
+ // 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;
+ llvm::ListSeparator LS;
+ for (const ArchSpec &arch : GetSupportedArchitectures()) {
+ resolved_module_spec.GetArchitecture() = arch;
+ 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();
+ }
+
+ arch_names << LS << arch.GetArchitectureName();
+ }
+
+ if (error.Fail() || !exe_module_sp) {
+ if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
+ error.SetErrorStringWithFormatv(
+ "'{0}' doesn't contain any '{1}' platform architectures: {2}",
+ resolved_module_spec.GetFileSpec(), GetPluginName(),
+ arch_names.GetData());
+ } else {
+ error.SetErrorStringWithFormatv("'{0}' is not readable",
+ resolved_module_spec.GetFileSpec());
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormatv("'{0}' does not exist",
+ resolved_module_spec.GetFileSpec());
}
+
return error;
}
@@ -966,26 +1008,27 @@ ArchSpec Platform::GetAugmentedArchSpec(llvm::StringRef triple) {
Status Platform::ConnectRemote(Args &args) {
Status error;
if (IsHost())
- error.SetErrorStringWithFormat("The currently selected platform (%s) is "
- "the host platform and is always connected.",
- GetPluginName().GetCString());
+ error.SetErrorStringWithFormatv(
+ "The currently selected platform ({0}) is "
+ "the host platform and is always connected.",
+ GetPluginName());
else
- error.SetErrorStringWithFormat(
- "Platform::ConnectRemote() is not supported by %s",
- GetPluginName().GetCString());
+ error.SetErrorStringWithFormatv(
+ "Platform::ConnectRemote() is not supported by {0}", GetPluginName());
return error;
}
Status Platform::DisconnectRemote() {
Status error;
if (IsHost())
- error.SetErrorStringWithFormat("The currently selected platform (%s) is "
- "the host platform and is always connected.",
- GetPluginName().GetCString());
+ error.SetErrorStringWithFormatv(
+ "The currently selected platform ({0}) is "
+ "the host platform and is always connected.",
+ GetPluginName());
else
- error.SetErrorStringWithFormat(
- "Platform::DisconnectRemote() is not supported by %s",
- GetPluginName().GetCString());
+ error.SetErrorStringWithFormatv(
+ "Platform::DisconnectRemote() is not supported by {0}",
+ GetPluginName());
return error;
}
@@ -1066,36 +1109,19 @@ Status Platform::KillProcess(const lldb::pid_t pid) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
LLDB_LOGF(log, "Platform::%s, pid %" PRIu64, __FUNCTION__, pid);
- // Try to find a process plugin to handle this Kill request. If we can't,
- // fall back to the default OS implementation.
- size_t num_debuggers = Debugger::GetNumDebuggers();
- for (size_t didx = 0; didx < num_debuggers; ++didx) {
- DebuggerSP debugger = Debugger::GetDebuggerAtIndex(didx);
- lldb_private::TargetList &targets = debugger->GetTargetList();
- for (int tidx = 0; tidx < targets.GetNumTargets(); ++tidx) {
- ProcessSP process = targets.GetTargetAtIndex(tidx)->GetProcessSP();
- if (process->GetID() == pid)
- return process->Destroy(true);
- }
- }
-
if (!IsHost()) {
return Status(
- "base lldb_private::Platform class can't kill remote processes unless "
- "they are controlled by a process plugin");
+ "base lldb_private::Platform class can't kill remote processes");
}
- Host::Kill(pid, SIGTERM);
+ Host::Kill(pid, SIGKILL);
return Status();
}
-lldb::ProcessSP
-Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
- Target *target, // Can be nullptr, if nullptr create a
- // new target, else use existing one
- Status &error) {
+lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info,
+ Debugger &debugger, Target &target,
+ Status &error) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
- LLDB_LOGF(log, "Platform::%s entered (target %p)", __FUNCTION__,
- static_cast<void *>(target));
+ LLDB_LOG(log, "target = {0})", &target);
ProcessSP process_sp;
// Make sure we stop at the entry point
@@ -1117,7 +1143,7 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
filter_callback = get_filter_func(++i, iteration_complete)) {
if (filter_callback) {
// Give this ProcessLaunchInfo filter a chance to adjust the launch info.
- error = (*filter_callback)(launch_info, target);
+ error = (*filter_callback)(launch_info, &target);
if (!error.Success()) {
LLDB_LOGF(log,
"Platform::%s() StructuredDataPlugin launch "
@@ -1135,10 +1161,10 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
__FUNCTION__, launch_info.GetProcessID());
if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
ProcessAttachInfo attach_info(launch_info);
- process_sp = Attach(attach_info, debugger, target, error);
+ process_sp = Attach(attach_info, debugger, &target, error);
if (process_sp) {
- LLDB_LOGF(log, "Platform::%s Attach() succeeded, Process plugin: %s",
- __FUNCTION__, process_sp->GetPluginName().AsCString());
+ LLDB_LOG(log, "Attach() succeeded, Process plugin: {0}",
+ process_sp->GetPluginName());
launch_info.SetHijackListener(attach_info.GetHijackListener());
// Since we attached to the process, it will think it needs to detach
@@ -1149,7 +1175,7 @@ Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger,
// If we didn't have any file actions, the pseudo terminal might have
// been used where the secondary side was given as the file to open for
- // stdin/out/err after we have already opened the master so we can
+ // stdin/out/err after we have already opened the primary so we can
// read/write stdin/out/err.
int pty_fd = launch_info.GetPTY().ReleasePrimaryFileDescriptor();
if (pty_fd != PseudoTerminal::invalid_fd) {
@@ -1183,6 +1209,35 @@ Platform::GetPlatformForArchitecture(const ArchSpec &arch,
return platform_sp;
}
+std::vector<ArchSpec>
+Platform::CreateArchList(llvm::ArrayRef<llvm::Triple::ArchType> archs,
+ llvm::Triple::OSType os) {
+ std::vector<ArchSpec> list;
+ for(auto arch : archs) {
+ llvm::Triple triple;
+ triple.setArch(arch);
+ triple.setOS(os);
+ list.push_back(ArchSpec(triple));
+ }
+ return list;
+}
+
+bool Platform::GetSupportedArchitectureAtIndex(uint32_t idx, ArchSpec &arch) {
+ const auto &archs = GetSupportedArchitectures();
+ if (idx >= archs.size())
+ return false;
+ arch = archs[idx];
+ return true;
+}
+
+std::vector<ArchSpec> Platform::GetSupportedArchitectures() {
+ std::vector<ArchSpec> result;
+ ArchSpec arch;
+ for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(idx, arch); ++idx)
+ result.push_back(arch);
+ return result;
+}
+
/// Lets a platform answer if it is compatible with a given
/// architecture and the target triple contained within.
bool Platform::IsCompatibleArchitecture(const ArchSpec &arch,
@@ -1191,26 +1246,13 @@ bool Platform::IsCompatibleArchitecture(const ArchSpec &arch,
// If the architecture is invalid, we must answer true...
if (arch.IsValid()) {
ArchSpec platform_arch;
- // Try for an exact architecture match first.
- if (exact_arch_match) {
- for (uint32_t arch_idx = 0;
- GetSupportedArchitectureAtIndex(arch_idx, platform_arch);
- ++arch_idx) {
- if (arch.IsExactMatch(platform_arch)) {
- if (compatible_arch_ptr)
- *compatible_arch_ptr = platform_arch;
- return true;
- }
- }
- } else {
- for (uint32_t arch_idx = 0;
- GetSupportedArchitectureAtIndex(arch_idx, platform_arch);
- ++arch_idx) {
- if (arch.IsCompatibleMatch(platform_arch)) {
- if (compatible_arch_ptr)
- *compatible_arch_ptr = platform_arch;
- return true;
- }
+ auto match = exact_arch_match ? &ArchSpec::IsExactMatch
+ : &ArchSpec::IsCompatibleMatch;
+ for (const ArchSpec &platform_arch : GetSupportedArchitectures()) {
+ if ((arch.*match)(platform_arch)) {
+ if (compatible_arch_ptr)
+ *compatible_arch_ptr = platform_arch;
+ return true;
}
}
}
@@ -1225,7 +1267,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination,
LLDB_LOGF(log, "[PutFile] Using block by block transfer....\n");
auto source_open_options =
- File::eOpenOptionRead | File::eOpenOptionCloseOnExec;
+ File::eOpenOptionReadOnly | File::eOpenOptionCloseOnExec;
namespace fs = llvm::sys::fs;
if (fs::is_symlink_file(source.GetPath()))
source_open_options |= File::eOpenOptionDontFollowSymlinks;
@@ -1240,7 +1282,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination,
permissions = lldb::eFilePermissionsFileDefault;
lldb::user_id_t dest_file = OpenFile(
- destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite |
+ destination, File::eOpenOptionCanCreate | File::eOpenOptionWriteOnly |
File::eOpenOptionTruncate | File::eOpenOptionCloseOnExec,
permissions, error);
LLDB_LOGF(log, "dest_file = %" PRIu64 "\n", dest_file);
@@ -1517,12 +1559,13 @@ const std::vector<ConstString> &Platform::GetTrapHandlerSymbolNames() {
return m_trap_handlers;
}
-Status Platform::GetCachedExecutable(
- ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr, Platform &remote_platform) {
+Status
+Platform::GetCachedExecutable(ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr) {
const auto platform_spec = module_spec.GetFileSpec();
- const auto error = LoadCachedExecutable(
- module_spec, module_sp, module_search_paths_ptr, remote_platform);
+ const auto error =
+ LoadCachedExecutable(module_spec, module_sp, module_search_paths_ptr);
if (error.Success()) {
module_spec.GetFileSpec() = module_sp->GetFileSpec();
module_spec.GetPlatformFileSpec() = platform_spec;
@@ -1531,15 +1574,17 @@ Status Platform::GetCachedExecutable(
return error;
}
-Status Platform::LoadCachedExecutable(
- const ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr, Platform &remote_platform) {
- return GetRemoteSharedModule(module_spec, nullptr, module_sp,
- [&](const ModuleSpec &spec) {
- return remote_platform.ResolveExecutable(
- spec, module_sp, module_search_paths_ptr);
- },
- nullptr);
+Status
+Platform::LoadCachedExecutable(const ModuleSpec &module_spec,
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr) {
+ return GetRemoteSharedModule(
+ module_spec, nullptr, module_sp,
+ [&](const ModuleSpec &spec) {
+ return ResolveRemoteExecutable(spec, module_sp,
+ module_search_paths_ptr);
+ },
+ nullptr);
}
Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec,
@@ -1568,9 +1613,8 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec,
// architectures that we should be using (in the correct order) and see if
// we can find a match that way
ModuleSpec arch_module_spec(module_spec);
- for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
- idx, arch_module_spec.GetArchitecture());
- ++idx) {
+ for (const ArchSpec &arch : GetSupportedArchitectures()) {
+ arch_module_spec.GetArchitecture() = arch;
error = ModuleList::GetSharedModule(arch_module_spec, module_sp, nullptr,
nullptr, nullptr);
// Did we find an executable using one of the
@@ -1619,8 +1663,8 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec,
bool Platform::GetCachedSharedModule(const ModuleSpec &module_spec,
lldb::ModuleSP &module_sp,
bool *did_create_ptr) {
- if (IsHost() || !GetGlobalPlatformProperties()->GetUseModuleCache() ||
- !GetGlobalPlatformProperties()->GetModuleCacheDirectory())
+ if (IsHost() || !GetGlobalPlatformProperties().GetUseModuleCache() ||
+ !GetGlobalPlatformProperties().GetModuleCacheDirectory())
return false;
Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM);
@@ -1663,7 +1707,7 @@ Status Platform::DownloadModuleSlice(const FileSpec &src_file_spec,
return error;
}
- auto src_fd = OpenFile(src_file_spec, File::eOpenOptionRead,
+ auto src_fd = OpenFile(src_file_spec, File::eOpenOptionReadOnly,
lldb::eFilePermissionsFileDefault, error);
if (error.Fail()) {
@@ -1704,7 +1748,7 @@ Status Platform::DownloadSymbolFile(const lldb::ModuleSP &module_sp,
}
FileSpec Platform::GetModuleCacheRoot() {
- auto dir_spec = GetGlobalPlatformProperties()->GetModuleCacheDirectory();
+ auto dir_spec = GetGlobalPlatformProperties().GetModuleCacheDirectory();
dir_spec.AppendPathComponent(GetName().AsCString());
return dir_spec;
}