Index: lldb/source/Plugins/Process/CMakeLists.txt =================================================================== --- lldb/source/Plugins/Process/CMakeLists.txt +++ lldb/source/Plugins/Process/CMakeLists.txt @@ -18,3 +18,4 @@ add_subdirectory(elf-core) add_subdirectory(mach-core) add_subdirectory(minidump) +add_subdirectory(FreeBSDKernel) Index: lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt =================================================================== --- /dev/null +++ lldb/source/Plugins/Process/FreeBSDKernel/CMakeLists.txt @@ -0,0 +1,17 @@ +find_library(FBSDVMCORE fbsdvmcore) + +if (NOT FBSDVMCORE) + message(STATUS "Skipping FreeBSDKernel plugin due to missing libfbsdvmcore") + return() +endif() + +add_lldb_library(lldbPluginProcessFreeBSDKernel PLUGIN + ProcessFreeBSDKernel.cpp + + LINK_LIBS + lldbCore + lldbTarget + ${FBSDVMCORE} + LINK_COMPONENTS + Support + ) Index: lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h =================================================================== --- /dev/null +++ lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.h @@ -0,0 +1,58 @@ +//===-- ProcessFreeBSDKernel.h ----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H +#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_PROCESSFREEBSDKERNEL_H + +#include "lldb/Target/PostMortemProcess.h" + +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; + + static lldb::ProcessSP + CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener, + const lldb_private::FileSpec *crash_file_path, + bool can_connect); + + static void Initialize(); + + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "freebsd-kernel"; } + + static llvm::StringRef GetPluginDescriptionStatic() { + return "FreeBSD kernel vmcore debugging plug-in."; + } + + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + lldb_private::Status DoDestroy() override; + + bool CanDebug(lldb::TargetSP target_sp, + bool plugin_specified_by_name) override; + + void RefreshStateAfterStop() override; + + lldb_private::Status DoLoadCore() override; + + size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, + lldb_private::Status &error) 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 =================================================================== --- /dev/null +++ lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp @@ -0,0 +1,86 @@ +//===-- ProcessFreeBSDKernel.cpp ------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ProcessFreeBSDKernel.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" + +#include + +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) {} + +ProcessFreeBSDKernel::~ProcessFreeBSDKernel() { + if (m_fvc) + fvc_close(static_cast(m_fvc)); +} + +lldb::ProcessSP ProcessFreeBSDKernel::CreateInstance(lldb::TargetSP target_sp, + ListenerSP listener_sp, + const FileSpec *crash_file, + bool can_connect) { + lldb::ProcessSP process_sp; + if (crash_file && !can_connect) { + fvc_t *fvc = fvc_open( + target_sp->GetExecutableModule()->GetFileSpec().GetPath().c_str(), + crash_file->GetPath().c_str(), nullptr, nullptr, nullptr); + if (fvc) + process_sp = std::make_shared( + target_sp, listener_sp, *crash_file, fvc); + } + return process_sp; +} + +void ProcessFreeBSDKernel::Initialize() { + static llvm::once_flag g_once_flag; + + llvm::call_once(g_once_flag, []() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); + }); +} + +void ProcessFreeBSDKernel::Terminate() { + PluginManager::UnregisterPlugin(ProcessFreeBSDKernel::CreateInstance); +} + +Status ProcessFreeBSDKernel::DoDestroy() { return Status(); } + +bool ProcessFreeBSDKernel::CanDebug(lldb::TargetSP target_sp, + bool plugin_specified_by_name) { + return true; +} + +void ProcessFreeBSDKernel::RefreshStateAfterStop() {} + +bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, + ThreadList &new_thread_list) { + return false; +} + +Status ProcessFreeBSDKernel::DoLoadCore() { + // The core is already loaded by CreateInstance(). + return Status(); +} + +size_t ProcessFreeBSDKernel::DoReadMemory(lldb::addr_t addr, void *buf, + size_t size, Status &error) { + ssize_t rd = fvc_read(static_cast(m_fvc), addr, buf, size); + if (rd < 0 || static_cast(rd) != size) + error.SetErrorStringWithFormat("Reading memory failed: %s", + fvc_geterr(static_cast(m_fvc))); + return rd; +}