[lldb] [llvm] [lldb][Process/FreeBSD] Add riscv64 support (PR #180549)

Minsoo Choo via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 10 06:41:10 PST 2026


================
@@ -0,0 +1,81 @@
+//===-- NativeRegisterContextFreeBSD_riscv64.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
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__riscv) && __riscv_xlen == 64
+
+#ifndef lldb_NativeRegisterContextFreeBSD_riscv64_h
+#define lldb_NativeRegisterContextFreeBSD_riscv64_h
+
+// clang-format off
+#include <sys/types.h>
+#include <sys/param.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h"
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeRegisterContextFreeBSD_riscv64
+    : public NativeRegisterContextFreeBSD {
+public:
+  NativeRegisterContextFreeBSD_riscv64(const ArchSpec &target_arch,
+                                       NativeThreadFreeBSD &native_thread);
+
+  uint32_t GetRegisterSetCount() const override;
+  uint32_t GetUserRegisterCount() const override;
+  const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+  Status ReadRegister(const RegisterInfo *reg_info,
+                      RegisterValue &reg_value) override;
+  Status WriteRegister(const RegisterInfo *reg_info,
+                       const RegisterValue &reg_value) override;
+  Status ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override;
+  Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+  void InvalidateAllRegisters() override;
+
+private:
+  // FreeBSD's native register structures
+  struct reg m_gpr;
+  struct fpreg m_fpr;
+
+  bool m_gpr_is_valid;
+  bool m_fpr_is_valid;
+
+  // Ptrace wrappers
+  Status ReadGPR();
+  Status WriteGPR();
+  Status ReadFPR();
+  Status WriteFPR();
+
+  // Conversion functions between FreeBSD and POSIX layouts
----------------
mchoo7 wrote:

For i386, x86_64, and powerpc we have RegisterContextFreeBSD. For arm, there is a clever workaround using byte offsets.

For riscv, it's a bit complicated. 

FreeBSD:

```c
struct reg {
	__uint64_t	ra;		/* return address */
	__uint64_t	sp;		/* stack pointer */
	__uint64_t	gp;		/* global pointer */
	__uint64_t	tp;		/* thread pointer */
	__uint64_t	t[7];		/* temporaries */
	__uint64_t	s[12];		/* saved registers */
	__uint64_t	a[8];		/* function arguments */
	__uint64_t	sepc;		/* exception program counter */
	__uint64_t	sstatus;	/* status register */
};

struct fpreg {
	__uint64_t	fp_x[32][2];	/* Floating point registers */
	__uint64_t	fp_fcsr;	/* Floating point control reg */
};
```

LLDB: 
```c
 struct GPR {
    // note: gpr[0] is pc, not x0
    uint64_t gpr[32];
  };

  struct FPR {
    uint64_t fpr[32];
    uint32_t fcsr;
  };
```

For GPR reg.h doesn't have pc. For FPR the floating point registers have different sizes. That's why I asked if I'm supposed to create and use RegisterContextFreeBSD_riscv64 over RegisterContextPOSIX_riscv64

https://github.com/llvm/llvm-project/pull/180549


More information about the llvm-commits mailing list