aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
diff options
context:
space:
mode:
authorMichał Górny <mgorny@moritz.systems>2021-12-18 10:09:12 +0100
committerMichał Górny <mgorny@moritz.systems>2021-12-22 16:14:03 +0100
commitfb785877a95d5d51e802df618b22187b624a2b23 (patch)
tree540685fef60f4d4663e58c81df5549be24530abe /lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
parent5eb271880c8fc59835797806ac44f736eaf3ddbd (diff)
downloadllvm-fb785877a95d5d51e802df618b22187b624a2b23.tar.gz
llvm-fb785877a95d5d51e802df618b22187b624a2b23.tar.bz2
llvm-fb785877a95d5d51e802df618b22187b624a2b23.zip
[lldb] [Process/FreeBSDKernel] Introduce libkvm support
Introduce initial support for using libkvm on FreeBSD. The library can be used as an alternate implementation for processing kernel coredumps but it can also be used to access live kernel memory through specifying "/dev/mem" as the core file, i.e.: lldb --core /dev/mem /boot/kernel/kernel Differential Revision: https://reviews.llvm.org/D116005
Diffstat (limited to 'lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp')
-rw-r--r--lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp144
1 files changed, 118 insertions, 26 deletions
diff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
index 327e25acd589..339d33d25110 100644
--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp
+++ b/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 @@ Status ProcessFreeBSDKernel::DoLoadCore() {
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__)