aboutsummaryrefslogtreecommitdiff
path: root/source/Host/linux
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
commitf73363f1dd94996356cefbf24388f561891acf0b (patch)
treee3c31248bdb36eaec5fd833490d4278162dba2a0 /source/Host/linux
parent160ee69dd7ae18978f4068116777639ea98dc951 (diff)
Notes
Diffstat (limited to 'source/Host/linux')
-rw-r--r--source/Host/linux/Host.cpp67
-rw-r--r--source/Host/linux/HostInfoLinux.cpp56
2 files changed, 48 insertions, 75 deletions
diff --git a/source/Host/linux/Host.cpp b/source/Host/linux/Host.cpp
index f43090eadf81..1a0eb767eb34 100644
--- a/source/Host/linux/Host.cpp
+++ b/source/Host/linux/Host.cpp
@@ -20,7 +20,9 @@
// C++ Includes
// Other libraries and framework includes
+#include "llvm/Object/ELF.h"
#include "llvm/Support/ScopedPrinter.h"
+
// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Utility/Log.h"
@@ -29,12 +31,9 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/linux/Support.h"
-#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Symbol/ObjectFile.h"
-
using namespace lldb;
using namespace lldb_private;
@@ -123,28 +122,27 @@ static bool IsDirNumeric(const char *dname) {
return true;
}
-static bool GetELFProcessCPUType(llvm::StringRef exe_path,
- ProcessInstanceInfo &process_info) {
- // Clear the architecture.
- process_info.GetArchitecture().Clear();
+static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- ModuleSpecList specs;
- FileSpec filespec(exe_path, false);
- const size_t num_specs =
- ObjectFile::GetModuleSpecifications(filespec, 0, 0, specs);
- // GetModuleSpecifications() could fail if the executable has been deleted or
- // is locked.
- // But it shouldn't return more than 1 architecture.
- assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
- if (num_specs == 1) {
- ModuleSpec module_spec;
- if (specs.GetModuleSpecAtIndex(0, module_spec) &&
- module_spec.GetArchitecture().IsValid()) {
- process_info.GetArchitecture() = module_spec.GetArchitecture();
- return true;
- }
+ auto buffer_sp = DataBufferLLVM::CreateSliceFromPath(exe_path, 0x20, 0);
+ if (!buffer_sp)
+ return ArchSpec();
+
+ uint8_t exe_class =
+ llvm::object::getElfArchType(
+ {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
+ .first;
+
+ switch (exe_class) {
+ case llvm::ELF::ELFCLASS32:
+ return HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ case llvm::ELF::ELFCLASS64:
+ return HostInfo::GetArchitecture(HostInfo::eArchKind64);
+ default:
+ LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, exe_path);
+ return ArchSpec();
}
- return false;
}
static bool GetProcessAndStatInfo(::pid_t pid,
@@ -173,7 +171,7 @@ static bool GetProcessAndStatInfo(::pid_t pid,
llvm::StringRef PathRef = ExePath;
PathRef.consume_back(" (deleted)");
- GetELFProcessCPUType(PathRef, process_info);
+ process_info.SetArchitecture(GetELFProcessCPUType(PathRef));
// Get the process environment.
auto BufferOrError = getProcFile(pid, "environ");
@@ -192,14 +190,14 @@ static bool GetProcessAndStatInfo(::pid_t pid,
return false;
process_info.SetProcessID(pid);
- process_info.GetExecutableFile().SetFile(PathRef, false);
- process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture());
+ process_info.GetExecutableFile().SetFile(PathRef, false,
+ FileSpec::Style::native);
llvm::StringRef Rest = Environ->getBuffer();
while (!Rest.empty()) {
llvm::StringRef Var;
std::tie(Var, Rest) = Rest.split('\0');
- process_info.GetEnvironmentEntries().AppendArgument(Var);
+ process_info.GetEnvironment().insert(Var);
}
llvm::StringRef Arg0;
@@ -249,8 +247,8 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
if (State == ProcessState::Zombie)
continue;
- // Check for user match if we're not matching all users and not running as
- // root.
+ // Check for user match if we're not matching all users and not running
+ // as root.
if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
continue;
@@ -297,14 +295,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
}
-size_t Host::GetEnvironment(StringList &env) {
- char **host_env = environ;
- char *env_entry;
- size_t i;
- for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
- env.AppendString(env_entry);
- return i;
-}
+Environment Host::GetEnvironment() { return Environment(environ); }
Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return Status("unimplemented");
diff --git a/source/Host/linux/HostInfoLinux.cpp b/source/Host/linux/HostInfoLinux.cpp
index 8d59cda249e8..1d95010e2f73 100644
--- a/source/Host/linux/HostInfoLinux.cpp
+++ b/source/Host/linux/HostInfoLinux.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/Host/Config.h"
#include "lldb/Host/linux/HostInfoLinux.h"
#include "lldb/Utility/Log.h"
@@ -25,12 +26,8 @@ using namespace lldb_private;
namespace {
struct HostInfoLinuxFields {
- HostInfoLinuxFields() : m_os_major(0), m_os_minor(0), m_os_update(0) {}
-
std::string m_distribution_id;
- uint32_t m_os_major;
- uint32_t m_os_minor;
- uint32_t m_os_update;
+ llvm::VersionTuple m_os_version;
};
HostInfoLinuxFields *g_fields = nullptr;
@@ -42,35 +39,21 @@ void HostInfoLinux::Initialize() {
g_fields = new HostInfoLinuxFields();
}
-bool HostInfoLinux::GetOSVersion(uint32_t &major, uint32_t &minor,
- uint32_t &update) {
- static bool success = false;
+llvm::VersionTuple HostInfoLinux::GetOSVersion() {
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
-
struct utsname un;
- if (uname(&un) == 0) {
- int status = sscanf(un.release, "%u.%u.%u", &g_fields->m_os_major,
- &g_fields->m_os_minor, &g_fields->m_os_update);
- if (status == 3)
- success = true;
- else {
- // Some kernels omit the update version, so try looking for just "X.Y"
- // and
- // set update to 0.
- g_fields->m_os_update = 0;
- status = sscanf(un.release, "%u.%u", &g_fields->m_os_major,
- &g_fields->m_os_minor);
- if (status == 2)
- success = true;
- }
- }
+ if (uname(&un) != 0)
+ return;
+
+ llvm::StringRef release = un.release;
+ // The kernel release string can include a lot of stuff (e.g.
+ // 4.9.0-6-amd64). We're only interested in the numbered prefix.
+ release = release.substr(0, release.find_first_not_of("0123456789."));
+ g_fields->m_os_version.tryParse(release);
});
- major = g_fields->m_os_major;
- minor = g_fields->m_os_minor;
- update = g_fields->m_os_update;
- return success;
+ return g_fields->m_os_version;
}
bool HostInfoLinux::GetOSBuildString(std::string &s) {
@@ -99,8 +82,8 @@ bool HostInfoLinux::GetOSKernelDescription(std::string &s) {
}
llvm::StringRef HostInfoLinux::GetDistributionId() {
- // Try to run 'lbs_release -i', and use that response
- // for the distribution id.
+ // Try to run 'lbs_release -i', and use that response for the distribution
+ // id.
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
@@ -108,8 +91,7 @@ llvm::StringRef HostInfoLinux::GetDistributionId() {
if (log)
log->Printf("attempting to determine Linux distribution...");
- // check if the lsb_release command exists at one of the
- // following paths
+ // check if the lsb_release command exists at one of the following paths
const char *const exe_paths[] = {"/bin/lsb_release",
"/usr/bin/lsb_release"};
@@ -188,7 +170,7 @@ FileSpec HostInfoLinux::GetProgramFileSpec() {
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
if (len > 0) {
exe_path[len] = 0;
- g_program_filespec.SetFile(exe_path, false);
+ g_program_filespec.SetFile(exe_path, false, FileSpec::Style::native);
}
}
@@ -204,15 +186,15 @@ bool HostInfoLinux::ComputeSupportExeDirectory(FileSpec &file_spec) {
}
bool HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
- FileSpec temp_file("/usr/lib/lldb/plugins", true);
+ FileSpec temp_file("/usr/lib" LLDB_LIBDIR_SUFFIX "/lldb/plugins", true);
file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
return true;
}
bool HostInfoLinux::ComputeUserPluginsDirectory(FileSpec &file_spec) {
// XDG Base Directory Specification
- // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
- // If XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html If
+ // XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
const char *xdg_data_home = getenv("XDG_DATA_HOME");
if (xdg_data_home && xdg_data_home[0]) {
std::string user_plugin_dir(xdg_data_home);