diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:09:23 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:09:23 +0000 |
| commit | f73363f1dd94996356cefbf24388f561891acf0b (patch) | |
| tree | e3c31248bdb36eaec5fd833490d4278162dba2a0 /source/Host/linux | |
| parent | 160ee69dd7ae18978f4068116777639ea98dc951 (diff) | |
Notes
Diffstat (limited to 'source/Host/linux')
| -rw-r--r-- | source/Host/linux/Host.cpp | 67 | ||||
| -rw-r--r-- | source/Host/linux/HostInfoLinux.cpp | 56 |
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); |
