diff options
author | Pavel Labath <labath@google.com> | 2018-01-29 10:46:00 +0000 |
---|---|---|
committer | Pavel Labath <labath@google.com> | 2018-01-29 10:46:00 +0000 |
commit | 36e82208c7752b5a8f5064f22c6c7232b801a607 (patch) | |
tree | ce1b71ed92ed0c844bef6b34a971f5f14472f0c2 /lldb/source/Host/linux | |
parent | 1902ffd9a4914d4cd03e200ca9050bf3b1564c19 (diff) | |
download | bcm5719-llvm-36e82208c7752b5a8f5064f22c6c7232b801a607.tar.gz bcm5719-llvm-36e82208c7752b5a8f5064f22c6c7232b801a607.zip |
Remove ObjectFile usage from HostLinux::GetProcessInfo
Summary:
The ObjectFile class was used to determine the architecture of a running
process by inspecting it's main executable. There were two issues with
this:
- it's in the wrong layer
- the call can be very expensive (it can end up computing the crc of the
whole file).
Since the process is running on the host, ideally we would be able to
just query the data straight from the OS like darwin does, but there
doesn't seem to be a reasonable way to do that. So, this fixes the
layering issue by using the llvm object library to inspect the file.
Since we know the process is already running on the host, we just need
to peek at a few bytes of the elf header to determine whether it's 32-
or 64-bit (which should make this faster as well).
Pretty much the same logic was implemented in
NativeProcessProtocol::ResolveProcessArchitecture, so I delete this
logic and replace calls with GetProcessInfo.
Reviewers: eugene, krytarowski
Subscribers: mgorny, hintonda, lldb-commits
Differential Revision: https://reviews.llvm.org/D42488
llvm-svn: 323637
Diffstat (limited to 'lldb/source/Host/linux')
-rw-r--r-- | lldb/source/Host/linux/Host.cpp | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp index 1edef7aceed..a9e0d91a228 100644 --- a/lldb/source/Host/linux/Host.cpp +++ b/lldb/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(); - - 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; - } +static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); + + 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"); @@ -193,7 +191,6 @@ static bool GetProcessAndStatInfo(::pid_t pid, process_info.SetProcessID(pid); process_info.GetExecutableFile().SetFile(PathRef, false); - process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture()); llvm::StringRef Rest = Environ->getBuffer(); while (!Rest.empty()) { |