[lldb][Process/FreeBSDKernelCore] Add riscv64 support (#180670)

This is LLDB version of
https://cgit.freebsd.org/ports/tree/devel/gdb/files/kgdb/riscv-fbsd-kern.c.
This enables selecting riscv64 and reading registers from PCB structure
on core dump and live kenrel debugging while trapframe unwinding support
will be implemented in future. Test files using core dump from riscv64
will be implemented once other kernel debugging improvements are done.

---------

Signed-off-by: Minsoo Choo <minsoochoo0122@proton.me>
This commit is contained in:
Minsoo Choo 2026-02-28 15:59:16 -05:00 committed by GitHub
parent 3e05ab6322
commit 4a602c03ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 158 additions and 2 deletions

View File

@ -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 (*)

View File

@ -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

View File

@ -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<RegisterInfoPOSIX_riscv64> 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;
}

View File

@ -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<RegisterInfoPOSIX_riscv64> 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

View File

@ -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<RegisterContextFreeBSDKernelCore_ppc64le>(
*this, new RegisterInfoPOSIX_ppc64le(arch), m_pcb_addr);
break;
case llvm::Triple::riscv64:
m_thread_reg_ctx_sp =
std::make_shared<RegisterContextFreeBSDKernelCore_riscv64>(
*this, std::make_unique<RegisterInfoPOSIX_riscv64>(arch, 0),
m_pcb_addr);
break;
case llvm::Triple::x86:
m_thread_reg_ctx_sp =
std::make_shared<RegisterContextFreeBSDKernelCore_i386>(

View File

@ -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