labath updated this revision to Diff 131401.
labath added a comment.
This revision is now accepted and ready to land.

Ok, so the issue was a subsequent MergeFrom(HostArchitecture) call which was
overwriting the invalid ArchSpec I was returning here. I think this was present
there to fill in the bits we could not get from the ObjectFile (like some
environment details). Since now I am returning the ArchSpec I get from HostInfo,
the merge will become a no-op in the success case and produce garbage in case
the detection fails -- so I just remove the merge call.


https://reviews.llvm.org/D42488

Files:
  include/lldb/Host/common/NativeProcessProtocol.h
  include/lldb/Utility/ArchSpec.h
  source/Host/CMakeLists.txt
  source/Host/common/NativeProcessProtocol.cpp
  source/Host/linux/Host.cpp
  source/Plugins/Process/Linux/NativeProcessLinux.cpp
  source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
  source/Utility/ArchSpec.cpp
  unittests/Host/linux/HostTest.cpp

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());
 }
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: 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<StringError>("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<NativeProcessNetBSD> 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<StringError>("Cannot get process architecture",
+                                         llvm::inconvertibleErrorCode());
+  }
 
-  std::unique_ptr<NativeProcessNetBSD> process_up(
-      new NativeProcessNetBSD(pid, -1, native_delegate, arch, mainloop));
+  std::unique_ptr<NativeProcessNetBSD> process_up(new NativeProcessNetBSD(
+      pid, -1, native_delegate, Info.GetArchitecture(), mainloop));
 
   status = process_up->Attach();
   if (!status.Success())
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<StringError>("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<NativeProcessLinux>(new NativeProcessLinux(
       pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
-      arch, mainloop, {pid}));
+      Info.GetArchitecture(), mainloop, {pid}));
 }
 
 llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
@@ -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<StringError>("Cannot get process architecture",
+                                         llvm::inconvertibleErrorCode());
+  }
 
   auto tids_or = NativeProcessLinux::Attach(pid);
   if (!tids_or)
     return tids_or.takeError();
 
   return std::unique_ptr<NativeProcessLinux>(new NativeProcessLinux(
-      pid, -1, native_delegate, arch, mainloop, *tids_or));
+      pid, -1, native_delegate, Info.GetArchitecture(), mainloop, *tids_or));
 }
 
 // -----------------------------------------------------------------------------
Index: source/Host/linux/Host.cpp
===================================================================
--- source/Host/linux/Host.cpp
+++ source/Host/linux/Host.cpp
@@ -20,21 +20,20 @@
 
 // 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"
 #include "lldb/Utility/Status.h"
 
 #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/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/CMakeLists.txt
===================================================================
--- source/Host/CMakeLists.txt
+++ source/Host/CMakeLists.txt
@@ -188,5 +188,6 @@
     ${EXTRA_LIBS}
   
   LINK_COMPONENTS
+    Object
     Support
   )
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: 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);
 };
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to