Index: include/lldb/Host/common/NativeProcessProtocol.h =================================================================== --- include/lldb/Host/common/NativeProcessProtocol.h +++ include/lldb/Host/common/NativeProcessProtocol.h @@ -466,11 +466,6 @@ NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid); - // ----------------------------------------------------------- - // Static helper methods for derived classes. - // ----------------------------------------------------------- - static Status ResolveProcessArchitecture(lldb::pid_t pid, ArchSpec &arch); - private: void SynchronouslyNotifyProcessStateChanged(lldb::StateType state); }; Index: include/lldb/Utility/ArchSpec.h =================================================================== --- include/lldb/Utility/ArchSpec.h +++ include/lldb/Utility/ArchSpec.h @@ -617,6 +617,7 @@ /// @return true if \a lhs is less than \a rhs //------------------------------------------------------------------ bool operator<(const ArchSpec &lhs, const ArchSpec &rhs); +bool operator==(const ArchSpec &lhs, const ArchSpec &rhs); bool ParseMachCPUDashSubtypeTriple(llvm::StringRef triple_str, ArchSpec &arch); Index: source/Host/CMakeLists.txt =================================================================== --- source/Host/CMakeLists.txt +++ source/Host/CMakeLists.txt @@ -188,5 +188,6 @@ ${EXTRA_LIBS} LINK_COMPONENTS + Object Support ) Index: source/Host/common/NativeProcessProtocol.cpp =================================================================== --- source/Host/common/NativeProcessProtocol.cpp +++ source/Host/common/NativeProcessProtocol.cpp @@ -14,7 +14,6 @@ #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/common/NativeThreadProtocol.h" #include "lldb/Host/common/SoftwareBreakpoint.h" -#include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" @@ -431,26 +430,4 @@ // Default implementation does nothing. } -Status NativeProcessProtocol::ResolveProcessArchitecture(lldb::pid_t pid, - ArchSpec &arch) { - // Grab process info for the running process. - ProcessInstanceInfo process_info; - if (!Host::GetProcessInfo(pid, process_info)) - return Status("failed to get process info"); - - // Resolve the executable module. - ModuleSpecList module_specs; - if (!ObjectFile::GetModuleSpecifications(process_info.GetExecutableFile(), 0, - 0, module_specs)) - return Status("failed to get module specifications"); - lldbassert(module_specs.GetSize() == 1); - - arch = module_specs.GetModuleSpecRefAtIndex(0).GetArchitecture(); - if (arch.IsValid()) - return Status(); - else - return Status( - "failed to retrieve a valid architecture from the exe module"); -} - NativeProcessProtocol::Factory::~Factory() = default; Index: source/Host/linux/Host.cpp =================================================================== --- source/Host/linux/Host.cpp +++ 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 @@ 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 @@ 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 @@ process_info.SetProcessID(pid); process_info.GetExecutableFile().SetFile(PathRef, false); - process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture()); llvm::StringRef Rest = Environ->getBuffer(); while (!Rest.empty()) { Index: source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -26,7 +26,6 @@ #include "lldb/Core/EmulateInstruction.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/RegisterValue.h" -#include "lldb/Utility/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/PseudoTerminal.h" @@ -41,6 +40,7 @@ #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/Target.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StringExtractor.h" #include "llvm/Support/Errno.h" @@ -245,13 +245,15 @@ } LLDB_LOG(log, "inferior started, now in stopped state"); - ArchSpec arch; - if ((status = ResolveProcessArchitecture(pid, arch)).Fail()) - return status.ToError(); + ProcessInstanceInfo Info; + if (!Host::GetProcessInfo(pid, Info)) { + return llvm::make_error("Cannot get process architecture", + llvm::inconvertibleErrorCode()); + } // Set the architecture to the exe architecture. LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid, - arch.GetArchitectureName()); + Info.GetArchitecture().GetArchitectureName()); status = SetDefaultPtraceOpts(pid); if (status.Fail()) { @@ -261,7 +263,7 @@ return std::unique_ptr(new NativeProcessLinux( pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate, - arch, mainloop, {pid})); + Info.GetArchitecture(), mainloop, {pid})); } llvm::Expected> @@ -272,17 +274,18 @@ LLDB_LOG(log, "pid = {0:x}", pid); // Retrieve the architecture for the running process. - ArchSpec arch; - Status status = ResolveProcessArchitecture(pid, arch); - if (!status.Success()) - return status.ToError(); + ProcessInstanceInfo Info; + if (!Host::GetProcessInfo(pid, Info)) { + return llvm::make_error("Cannot get process architecture", + llvm::inconvertibleErrorCode()); + } auto tids_or = NativeProcessLinux::Attach(pid); if (!tids_or) return tids_or.takeError(); return std::unique_ptr(new NativeProcessLinux( - pid, -1, native_delegate, arch, mainloop, *tids_or)); + pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or)); } // ----------------------------------------------------------------------------- Index: source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp =================================================================== --- source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -93,17 +93,19 @@ } LLDB_LOG(log, "inferior started, now in stopped state"); - ArchSpec arch; - if ((status = ResolveProcessArchitecture(pid, arch)).Fail()) - return status.ToError(); + ProcessInstanceInfo Info; + if (!Host::GetProcessInfo(pid, Info)) { + return llvm::make_error("Cannot get process architecture", + llvm::inconvertibleErrorCode()); + } // Set the architecture to the exe architecture. LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid, - arch.GetArchitectureName()); + Info.GetArchitecture().GetArchitectureName()); std::unique_ptr process_up(new NativeProcessNetBSD( pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate, - arch, mainloop)); + Info.GetArchitecture(), mainloop)); status = process_up->ReinitializeThreads(); if (status.Fail()) @@ -124,13 +126,14 @@ LLDB_LOG(log, "pid = {0:x}", pid); // Retrieve the architecture for the running process. - ArchSpec arch; - Status status = ResolveProcessArchitecture(pid, arch); - if (!status.Success()) - return status.ToError(); + ProcessInstanceInfo Info; + if (!Host::GetProcessInfo(pid, Info)) { + return llvm::make_error("Cannot get process architecture", + llvm::inconvertibleErrorCode()); + } - std::unique_ptr process_up( - new NativeProcessNetBSD(pid, -1, native_delegate, arch, mainloop)); + std::unique_ptr process_up(new NativeProcessNetBSD( + pid, -1, native_delegate, Info.GetArchitecture(), mainloop)); status = process_up->Attach(); if (!status.Success()) Index: source/Utility/ArchSpec.cpp =================================================================== --- source/Utility/ArchSpec.cpp +++ source/Utility/ArchSpec.cpp @@ -1416,6 +1416,11 @@ return lhs_core < rhs_core; } + +bool lldb_private::operator==(const ArchSpec &lhs, const ArchSpec &rhs) { + return lhs.GetCore() == rhs.GetCore(); +} + bool ArchSpec::IsFullySpecifiedTriple() const { const auto &user_specified_triple = GetTriple(); Index: unittests/Host/linux/HostTest.cpp =================================================================== --- unittests/Host/linux/HostTest.cpp +++ unittests/Host/linux/HostTest.cpp @@ -45,4 +45,8 @@ ASSERT_TRUE(Info.GroupIDIsValid()); EXPECT_EQ(getegid(), Info.GetGroupID()); + + EXPECT_TRUE(Info.GetArchitecture().IsValid()); + EXPECT_EQ(HostInfo::GetArchitecture(HostInfo::eArchKindDefault), + Info.GetArchitecture()); }