mgorny created this revision.
mgorny added reviewers: labath, krytarowski.
mgorny added a parent revision: D73802: [lldb] Introduce i386 support in NetBSD 
Process plugin.

Implement detection of ELF binary format, and support for i386 register
context on amd64 when a 32-bit executable is being debugged.  This is
roughly based on the code from Linux.


https://reviews.llvm.org/D73974

Files:
  lldb/source/Host/netbsd/Host.cpp
  lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
  lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h

Index: lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
+++ lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h
@@ -22,9 +22,12 @@
 
   uint32_t GetRegisterCount() const override;
 
+  uint32_t GetUserRegisterCount() const override;
+
 private:
   const lldb_private::RegisterInfo *m_register_info_p;
   const uint32_t m_register_count;
+  const uint32_t m_user_register_count;
 };
 
 #endif
Index: lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
+++ lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "RegisterContextNetBSD_x86_64.h"
+#include "RegisterContextNetBSD_i386.h"
 #include "RegisterContextPOSIX_x86.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/Compiler.h"
@@ -83,9 +84,40 @@
 #include "RegisterInfos_x86_64.h"
 #undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
 
+static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() {
+  static std::vector<lldb_private::RegisterInfo> g_register_infos;
+  return g_register_infos;
+}
+
+static const RegisterInfo *
+GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {
+  std::vector<lldb_private::RegisterInfo> &g_register_infos =
+      GetPrivateRegisterInfoVector();
+
+  // Allocate RegisterInfo only once
+  if (g_register_infos.empty()) {
+    // Copy the register information from base class
+    std::unique_ptr<RegisterContextNetBSD_i386> reg_interface(
+        new RegisterContextNetBSD_i386(arch));
+    const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
+    g_register_infos.insert(g_register_infos.end(), &base_info[0],
+                            &base_info[k_num_registers_i386]);
+
+// Include RegisterInfos_x86_64 to update the g_register_infos structure
+//  with x86_64 offsets.
+#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+#include "RegisterInfos_x86_64.h"
+#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+  }
+
+  return &g_register_infos[0];
+}
+
 static const RegisterInfo *
 PrivateGetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
   switch (target_arch.GetMachine()) {
+  case llvm::Triple::x86:
+    return GetRegisterInfo_i386(target_arch);
   case llvm::Triple::x86_64:
     return g_register_infos_x86_64;
   default:
@@ -97,6 +129,11 @@
 static uint32_t
 PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
   switch (target_arch.GetMachine()) {
+  case llvm::Triple::x86: {
+    assert(!GetPrivateRegisterInfoVector().empty() &&
+           "i386 register info not yet filled.");
+    return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size());
+  }
   case llvm::Triple::x86_64:
     return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
                                  sizeof(g_register_infos_x86_64[0]));
@@ -106,11 +143,25 @@
   }
 }
 
+static uint32_t
+PrivateGetUserRegisterCount(const lldb_private::ArchSpec &target_arch) {
+  switch (target_arch.GetMachine()) {
+  case llvm::Triple::x86:
+    return static_cast<uint32_t>(k_num_user_registers_i386);
+  case llvm::Triple::x86_64:
+    return static_cast<uint32_t>(k_num_user_registers_x86_64);
+  default:
+    assert(false && "Unhandled target architecture.");
+    return 0;
+  }
+}
+
 RegisterContextNetBSD_x86_64::RegisterContextNetBSD_x86_64(
     const ArchSpec &target_arch)
     : lldb_private::RegisterInfoInterface(target_arch),
       m_register_info_p(PrivateGetRegisterInfoPtr(target_arch)),
-      m_register_count(PrivateGetRegisterCount(target_arch)) {}
+      m_register_count(PrivateGetRegisterCount(target_arch)),
+      m_user_register_count(PrivateGetUserRegisterCount(target_arch)) {}
 
 size_t RegisterContextNetBSD_x86_64::GetGPRSize() const { return sizeof(GPR); }
 
@@ -121,3 +172,7 @@
 uint32_t RegisterContextNetBSD_x86_64::GetRegisterCount() const {
   return m_register_count;
 }
+
+uint32_t RegisterContextNetBSD_x86_64::GetUserRegisterCount() const {
+  return m_user_register_count;
+}
Index: lldb/source/Host/netbsd/Host.cpp
===================================================================
--- lldb/source/Host/netbsd/Host.cpp
+++ lldb/source/Host/netbsd/Host.cpp
@@ -15,11 +15,11 @@
 
 #include <limits.h>
 
-#include <elf.h>
 #include <kvm.h>
 #include <sys/exec.h>
 #include <sys/ptrace.h>
 
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Utility/DataBufferHeap.h"
@@ -31,6 +31,7 @@
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/StreamString.h"
 
+#include "llvm/Object/ELF.h"
 #include "llvm/Support/Host.h"
 
 extern "C" {
@@ -100,10 +101,31 @@
 }
 
 static bool GetNetBSDProcessCPUType(ProcessInstanceInfo &process_info) {
+  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+
   if (process_info.ProcessIDIsValid()) {
-    process_info.GetArchitecture() =
-        HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
-    return true;
+    auto buffer_sp = FileSystem::Instance().CreateDataBuffer(
+        process_info.GetExecutableFile(), 0x20, 0);
+    if (buffer_sp) {
+      uint8_t exe_class =
+          llvm::object::getElfArchType(
+              {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
+              .first;
+
+      switch (exe_class) {
+      case llvm::ELF::ELFCLASS32:
+        process_info.GetArchitecture() =
+            HostInfo::GetArchitecture(HostInfo::eArchKind32);
+        return true;
+      case llvm::ELF::ELFCLASS64:
+        process_info.GetArchitecture() =
+            HostInfo::GetArchitecture(HostInfo::eArchKind64);
+        return true;
+      default:
+        LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class,
+                 process_info.GetExecutableFile());
+      }
+    }
   }
   process_info.GetArchitecture().Clear();
   return false;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] D73... Michał Górny via Phabricator via lldb-commits

Reply via email to