mgorny updated this revision to Diff 395850.
mgorny marked an inline comment as done.
mgorny added a comment.

Implemented requested changed.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116005/new/

https://reviews.llvm.org/D116005

Files:
  lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
  lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
  lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
  
lldb/test/API/functionalities/postmortem/FreeBSDKernel/TestFreeBSDKernelLive.py

Index: lldb/test/API/functionalities/postmortem/FreeBSDKernel/TestFreeBSDKernelLive.py
===================================================================
--- /dev/null
+++ lldb/test/API/functionalities/postmortem/FreeBSDKernel/TestFreeBSDKernelLive.py
@@ -0,0 +1,44 @@
+import os
+import struct
+import subprocess
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class FreeBSDKernelVMCoreTestCase(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def test_mem(self):
+        kernel_exec = "/boot/kernel/kernel"
+        mem_device = "/dev/mem"
+
+        if not os.access(kernel_exec, os.R_OK):
+            self.skipTest("Kernel @ %s is not readable" % (kernel_exec,))
+        if not os.access(mem_device, os.R_OK):
+            self.skipTest("Memory @ %s is not readable" % (mem_device,))
+
+        target = self.dbg.CreateTarget(kernel_exec)
+        process = target.LoadCore(mem_device)
+        hz_value = int(subprocess.check_output(["sysctl", "-n", "kern.hz"]))
+
+        self.assertTrue(process, PROCESS_IS_VALID)
+        self.assertEqual(process.GetNumThreads(), 1)
+        self.assertEqual(process.GetProcessID(), 0)
+
+        # test memory reading
+        self.expect("expr -- *(int *) &hz",
+                    substrs=["(int) $0 = %d" % hz_value])
+
+        main_mod = target.GetModuleAtIndex(0)
+        hz_addr = (main_mod.FindSymbols("hz")[0].symbol.addr
+                   .GetLoadAddress(target))
+        error = lldb.SBError()
+        self.assertEqual(process.ReadMemory(hz_addr, 4, error),
+                         struct.pack("<I", hz_value))
+
+        self.dbg.DeleteTarget(target)
Index: lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
===================================================================
--- lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
+++ lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h
@@ -13,10 +13,7 @@
 
 class ProcessFreeBSDKernel : public lldb_private::PostMortemProcess {
 public:
-  ProcessFreeBSDKernel(lldb::TargetSP target_sp, lldb::ListenerSP listener,
-                       const lldb_private::FileSpec &core_file, void *fvc);
-
-  ~ProcessFreeBSDKernel() override;
+  ProcessFreeBSDKernel(lldb::TargetSP target_sp, lldb::ListenerSP listener);
 
   static lldb::ProcessSP
   CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener,
@@ -44,17 +41,11 @@
 
   lldb_private::Status DoLoadCore() override;
 
-  size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
-                      lldb_private::Status &error) override;
-
   lldb_private::DynamicLoader *GetDynamicLoader() override;
 
 protected:
   bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
                           lldb_private::ThreadList &new_thread_list) override;
-
-private:
-  void *m_fvc;
 };
 
 #endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H
Index: lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
===================================================================
--- lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
+++ lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
@@ -10,42 +10,91 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Target/DynamicLoader.h"
 
+#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
 #include "ProcessFreeBSDKernel.h"
 #include "ThreadFreeBSDKernel.h"
-#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
 
+#if LLDB_ENABLE_FBSDVMCORE
 #include <fvc.h>
+#endif
+#if defined(__FreeBSD__)
+#include <kvm.h>
+#endif
 
 using namespace lldb;
 using namespace lldb_private;
 
 LLDB_PLUGIN_DEFINE(ProcessFreeBSDKernel)
 
-ProcessFreeBSDKernel::ProcessFreeBSDKernel(lldb::TargetSP target_sp,
-                                           ListenerSP listener_sp,
-                                           const FileSpec &core_file, void *fvc)
-    : PostMortemProcess(target_sp, listener_sp), m_fvc(fvc) {}
+namespace {
 
-ProcessFreeBSDKernel::~ProcessFreeBSDKernel() {
-  if (m_fvc)
-    fvc_close(static_cast<fvc_t *>(m_fvc));
-}
+#if LLDB_ENABLE_FBSDVMCORE
+class ProcessFreeBSDKernelFVC : public ProcessFreeBSDKernel {
+public:
+  ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+                          fvc_t *fvc);
+
+  ~ProcessFreeBSDKernelFVC();
+
+  size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+                      lldb_private::Status &error) override;
+
+private:
+  fvc_t *m_fvc;
+
+  const char *GetError();
+};
+#endif // LLDB_ENABLE_FBSDVMCORE
+
+#if defined(__FreeBSD__)
+class ProcessFreeBSDKernelKVM : public ProcessFreeBSDKernel {
+public:
+  ProcessFreeBSDKernelKVM(lldb::TargetSP target_sp, lldb::ListenerSP listener,
+                          kvm_t *fvc);
+
+  ~ProcessFreeBSDKernelKVM();
+
+  size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
+                      lldb_private::Status &error) override;
+
+private:
+  kvm_t *m_kvm;
+
+  const char *GetError();
+};
+#endif // defined(__FreeBSD__)
+
+} // namespace
+
+ProcessFreeBSDKernel::ProcessFreeBSDKernel(lldb::TargetSP target_sp,
+                                           ListenerSP listener_sp)
+    : PostMortemProcess(target_sp, listener_sp) {}
 
 lldb::ProcessSP ProcessFreeBSDKernel::CreateInstance(lldb::TargetSP target_sp,
                                                      ListenerSP listener_sp,
                                                      const FileSpec *crash_file,
                                                      bool can_connect) {
-  lldb::ProcessSP process_sp;
   ModuleSP executable = target_sp->GetExecutableModule();
   if (crash_file && !can_connect && executable) {
-    fvc_t *fvc = fvc_open(
-        executable->GetFileSpec().GetPath().c_str(),
-        crash_file->GetPath().c_str(), nullptr, nullptr, nullptr);
+#if LLDB_ENABLE_FBSDVMCORE
+    fvc_t *fvc =
+        fvc_open(executable->GetFileSpec().GetPath().c_str(),
+                 crash_file->GetPath().c_str(), nullptr, nullptr, nullptr);
     if (fvc)
-      process_sp = std::make_shared<ProcessFreeBSDKernel>(
-          target_sp, listener_sp, *crash_file, fvc);
+      return std::make_shared<ProcessFreeBSDKernelFVC>(target_sp, listener_sp,
+                                                       fvc);
+#endif
+
+#if defined(__FreeBSD__)
+    kvm_t *kvm =
+        kvm_open2(executable->GetFileSpec().GetPath().c_str(),
+                  crash_file->GetPath().c_str(), O_RDONLY, nullptr, nullptr);
+    if (kvm)
+      return std::make_shared<ProcessFreeBSDKernelKVM>(target_sp, listener_sp,
+                                                       kvm);
+#endif
   }
-  return process_sp;
+  return nullptr;
 }
 
 void ProcessFreeBSDKernel::Initialize() {
@@ -107,20 +156,63 @@
   return Status();
 }
 
-size_t ProcessFreeBSDKernel::DoReadMemory(lldb::addr_t addr, void *buf,
-                                          size_t size, Status &error) {
-  ssize_t rd = fvc_read(static_cast<fvc_t *>(m_fvc), addr, buf, size);
+DynamicLoader *ProcessFreeBSDKernel::GetDynamicLoader() {
+  if (m_dyld_up.get() == nullptr)
+    m_dyld_up.reset(DynamicLoader::FindPlugin(
+        this, DynamicLoaderStatic::GetPluginNameStatic()));
+  return m_dyld_up.get();
+}
+
+#if LLDB_ENABLE_FBSDVMCORE
+
+ProcessFreeBSDKernelFVC::ProcessFreeBSDKernelFVC(lldb::TargetSP target_sp,
+                                                 ListenerSP listener_sp,
+                                                 fvc_t *fvc)
+    : ProcessFreeBSDKernel(target_sp, listener_sp), m_fvc(fvc) {}
+
+ProcessFreeBSDKernelFVC::~ProcessFreeBSDKernelFVC() {
+  if (m_fvc)
+    fvc_close(m_fvc);
+}
+
+size_t ProcessFreeBSDKernelFVC::DoReadMemory(lldb::addr_t addr, void *buf,
+                                             size_t size, Status &error) {
+  ssize_t rd = 0;
+  rd = fvc_read(m_fvc, addr, buf, size);
   if (rd < 0 || static_cast<size_t>(rd) != size) {
-    error.SetErrorStringWithFormat("Reading memory failed: %s",
-                                   fvc_geterr(static_cast<fvc_t *>(m_fvc)));
+    error.SetErrorStringWithFormat("Reading memory failed: %s", GetError());
     return rd > 0 ? rd : 0;
   }
   return rd;
 }
 
-DynamicLoader *ProcessFreeBSDKernel::GetDynamicLoader() {
-  if (m_dyld_up.get() == nullptr)
-    m_dyld_up.reset(DynamicLoader::FindPlugin(
-        this, DynamicLoaderStatic::GetPluginNameStatic()));
-  return m_dyld_up.get();
+const char *ProcessFreeBSDKernelFVC::GetError() { return fvc_geterr(m_fvc); }
+
+#endif // LLDB_ENABLE_FBSDVMCORE
+
+#if defined(__FreeBSD__)
+
+ProcessFreeBSDKernelKVM::ProcessFreeBSDKernelKVM(lldb::TargetSP target_sp,
+                                                 ListenerSP listener_sp,
+                                                 kvm_t *fvc)
+    : ProcessFreeBSDKernel(target_sp, listener_sp), m_kvm(fvc) {}
+
+ProcessFreeBSDKernelKVM::~ProcessFreeBSDKernelKVM() {
+  if (m_kvm)
+    kvm_close(m_kvm);
 }
+
+size_t ProcessFreeBSDKernelKVM::DoReadMemory(lldb::addr_t addr, void *buf,
+                                             size_t size, Status &error) {
+  ssize_t rd = 0;
+  rd = kvm_read2(m_kvm, addr, buf, size);
+  if (rd < 0 || static_cast<size_t>(rd) != size) {
+    error.SetErrorStringWithFormat("Reading memory failed: %s", GetError());
+    return rd > 0 ? rd : 0;
+  }
+  return rd;
+}
+
+const char *ProcessFreeBSDKernelKVM::GetError() { return kvm_geterr(m_kvm); }
+
+#endif // defined(__FreeBSD__)
Index: lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
+++ lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt
@@ -1,4 +1,12 @@
-if (NOT FBSDVMCore_FOUND)
+set(FBSDKERNEL_LIBS)
+if(FBSDVMCore_FOUND)
+  list(APPEND FBSDKERNEL_LIBS fbsdvmcore)
+endif()
+if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+  list(APPEND FBSDKERNEL_LIBS kvm)
+endif()
+
+if (NOT FBSDKERNEL_LIBS)
   message(STATUS "Skipping FreeBSDKernel plugin due to missing libfbsdvmcore")
   return()
 endif()
@@ -13,7 +21,7 @@
   LINK_LIBS
     lldbCore
     lldbTarget
-    fbsdvmcore
+    ${FBSDKERNEL_LIBS}
   LINK_COMPONENTS
     Support
   )
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to