diff --git a/lldb/docs/index.rst b/lldb/docs/index.rst index bbf6a84d34d9..2d05e4f95852 100644 --- a/lldb/docs/index.rst +++ b/lldb/docs/index.rst @@ -74,7 +74,7 @@ are welcome: * iOS, tvOS, and watchOS device debugging on ARM and AArch64 * Linux user-space debugging for i386, x86_64, ARM, AArch64, PPC64le, s390x * FreeBSD user-space debugging for i386, x86_64, ARM, AArch64, PPC -* FreeBSD kernel debugging for i386, x86_64, ARM, AArch64, PPC64le +* FreeBSD kernel debugging for i386, x86_64, ARM, AArch64, PPC64le, RISCV64 * NetBSD user-space debugging for i386 and x86_64 * Windows user-space debugging for i386, x86_64, ARM and AArch64 (*) diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/CMakeLists.txt b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/CMakeLists.txt index c23af7c34585..193714317136 100644 --- a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/CMakeLists.txt +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/CMakeLists.txt @@ -12,6 +12,7 @@ add_lldb_library(lldbPluginProcessFreeBSDKernelCore PLUGIN RegisterContextFreeBSDKernelCore_arm64.cpp RegisterContextFreeBSDKernelCore_i386.cpp RegisterContextFreeBSDKernelCore_ppc64le.cpp + RegisterContextFreeBSDKernelCore_riscv64.cpp RegisterContextFreeBSDKernelCore_x86_64.cpp ThreadFreeBSDKernelCore.cpp diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/RegisterContextFreeBSDKernelCore_riscv64.cpp b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/RegisterContextFreeBSDKernelCore_riscv64.cpp new file mode 100644 index 000000000000..b705c6d6d43b --- /dev/null +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/RegisterContextFreeBSDKernelCore_riscv64.cpp @@ -0,0 +1,105 @@ +//===----------------------------------------------------------------------===// +// +// 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 "RegisterContextFreeBSDKernelCore_riscv64.h" + +#include "lldb/Target/Process.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" +#include "llvm/Support/Endian.h" + +using namespace lldb; +using namespace lldb_private; + +RegisterContextFreeBSDKernelCore_riscv64:: + RegisterContextFreeBSDKernelCore_riscv64( + Thread &thread, + std::unique_ptr register_info_up, + lldb::addr_t pcb_addr) + : RegisterContextPOSIX_riscv64(thread, std::move(register_info_up)), + m_pcb_addr(pcb_addr) {} + +bool RegisterContextFreeBSDKernelCore_riscv64::ReadGPR() { return true; } + +bool RegisterContextFreeBSDKernelCore_riscv64::ReadFPR() { return true; } + +bool RegisterContextFreeBSDKernelCore_riscv64::WriteGPR() { + assert(0); + return false; +} + +bool RegisterContextFreeBSDKernelCore_riscv64::WriteFPR() { + assert(0); + return false; +} + +bool RegisterContextFreeBSDKernelCore_riscv64::ReadRegister( + const RegisterInfo *reg_info, RegisterValue &value) { + if (m_pcb_addr == LLDB_INVALID_ADDRESS) + return false; + + // https://cgit.freebsd.org/src/tree/sys/riscv/include/pcb.h + struct { + llvm::support::ulittle64_t ra; + llvm::support::ulittle64_t sp; + llvm::support::ulittle64_t gp; + llvm::support::ulittle64_t tp; + llvm::support::ulittle64_t s[12]; + } pcb; + + Status error; + size_t rd = + m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error); + if (rd != sizeof(pcb)) + return false; + + uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + switch (reg) { + case gpr_pc_riscv: + case gpr_ra_riscv: + // Supply the RA as PC as well to simulate the PC as if the thread had just + // returned. + value = pcb.ra; + break; + case gpr_sp_riscv: + value = pcb.sp; + break; + case gpr_gp_riscv: + value = pcb.gp; + break; + case gpr_tp_riscv: + value = pcb.tp; + break; + case gpr_fp_riscv: + value = pcb.s[0]; + break; + case gpr_s1_riscv: + value = pcb.s[1]; + break; + case gpr_s2_riscv: + case gpr_s3_riscv: + case gpr_s4_riscv: + case gpr_s5_riscv: + case gpr_s6_riscv: + case gpr_s7_riscv: + case gpr_s8_riscv: + case gpr_s9_riscv: + case gpr_s10_riscv: + case gpr_s11_riscv: + value = pcb.s[reg - gpr_s2_riscv + 2]; + break; + default: + return false; + } + return true; +} + +bool RegisterContextFreeBSDKernelCore_riscv64::WriteRegister( + const RegisterInfo *reg_info, const RegisterValue &value) { + return false; +} diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/RegisterContextFreeBSDKernelCore_riscv64.h b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/RegisterContextFreeBSDKernelCore_riscv64.h new file mode 100644 index 000000000000..033671da8ff7 --- /dev/null +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/RegisterContextFreeBSDKernelCore_riscv64.h @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// 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_REGISTERCONTEXTFREEBSDKERNELCORE_RISCV64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNELCORE_RISCV64_H + +#include "Plugins/Process/Utility/RegisterContextPOSIX_riscv64.h" +#include "Plugins/Process/elf-core/RegisterUtilities.h" + +class RegisterContextFreeBSDKernelCore_riscv64 + : public RegisterContextPOSIX_riscv64 { +public: + RegisterContextFreeBSDKernelCore_riscv64( + lldb_private::Thread &thread, + std::unique_ptr register_info_up, + lldb::addr_t pcb_addr); + + bool ReadRegister(const lldb_private::RegisterInfo *reg_info, + lldb_private::RegisterValue &value) override; + + bool WriteRegister(const lldb_private::RegisterInfo *reg_info, + const lldb_private::RegisterValue &value) override; + +protected: + bool ReadGPR() override; + + bool ReadFPR() override; + + bool WriteGPR() override; + + bool WriteFPR() override; + +private: + lldb::addr_t m_pcb_addr; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_FREEBSDKERNEL_REGISTERCONTEXTFREEBSDKERNELCORE_RISCV64_H diff --git a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ThreadFreeBSDKernelCore.cpp b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ThreadFreeBSDKernelCore.cpp index 386a2ab29ec2..b98ed1208f5e 100644 --- a/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ThreadFreeBSDKernelCore.cpp +++ b/lldb/source/Plugins/Process/FreeBSD-Kernel-Core/ThreadFreeBSDKernelCore.cpp @@ -17,11 +17,13 @@ #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h" +#include "Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h" #include "ProcessFreeBSDKernelCore.h" #include "RegisterContextFreeBSDKernelCore_arm.h" #include "RegisterContextFreeBSDKernelCore_arm64.h" #include "RegisterContextFreeBSDKernelCore_i386.h" #include "RegisterContextFreeBSDKernelCore_ppc64le.h" +#include "RegisterContextFreeBSDKernelCore_riscv64.h" #include "RegisterContextFreeBSDKernelCore_x86_64.h" using namespace lldb; @@ -77,6 +79,12 @@ ThreadFreeBSDKernelCore::CreateRegisterContextForFrame(StackFrame *frame) { std::make_shared( *this, new RegisterInfoPOSIX_ppc64le(arch), m_pcb_addr); break; + case llvm::Triple::riscv64: + m_thread_reg_ctx_sp = + std::make_shared( + *this, std::make_unique(arch, 0), + m_pcb_addr); + break; case llvm::Triple::x86: m_thread_reg_ctx_sp = std::make_shared( diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index 0c0fa1b94064..2e0c5c5cb937 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -221,7 +221,7 @@ Changes to LLDB * Support for libfbsdvmcore has been removed. As a result, FreeBSD kernel dump debugging is now only available on FreeBSD hosts. Live kernel debugging through the GDB remote protocol is still available from any platform. -* Support for ARM and PPC64le has been added. +* Support for ARM, PPC64le, and RISCV64 has been added. * The crashed thread is now automatically selected on start. * Threads are listed in incrmental order by pid then by tid. * Unread kernel messages saved in msgbufp are now printed when lldb starts. This information is printed only