================ @@ -0,0 +1,559 @@ +//===-- NativeRegisterContextFreeBSD_riscv64.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 +// +//===----------------------------------------------------------------------===// + +#if defined(__riscv) && __riscv_xlen == 64 + +#include "NativeRegisterContextFreeBSD_riscv64.h" + +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Status.h" + +#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h" +#include "Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h" + +// clang-format off +#include <sys/param.h> +#include <sys/ptrace.h> +#include <sys/types.h> +// clang-format on + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::process_freebsd; + +// Translation between RegisterInfoPosix_riscv64 and reg.h +// https://github.com/freebsd/freebsd-src/blob/main/sys/riscv/include/reg.h: +// +// 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 */ +// }; +// +// struct dbreg { +// int dummy; +// }; + +// ============================================================================ +// Static Conversion Functions between FreeBSD and POSIX +// ============================================================================ + +void NativeRegisterContextFreeBSD_riscv64::FreeBSDToPOSIXGPR( + const struct reg &freebsd_gpr, RegisterInfoPOSIX_riscv64::GPR &posix_gpr) { + posix_gpr.gpr[gpr_pc_riscv64] = freebsd_gpr.sepc; // x0/pc + posix_gpr.gpr[gpr_ra_riscv64] = freebsd_gpr.ra; // x1/ra + posix_gpr.gpr[gpr_sp_riscv64] = freebsd_gpr.sp; // x2/sp + posix_gpr.gpr[gpr_gp_riscv64] = freebsd_gpr.gp; // x3/gp + posix_gpr.gpr[gpr_tp_riscv64] = freebsd_gpr.tp; // x4/tp + + // x5-x7: t0-t2 + posix_gpr.gpr[gpr_t0_riscv64] = freebsd_gpr.t[0]; + posix_gpr.gpr[gpr_t1_riscv64] = freebsd_gpr.t[1]; + posix_gpr.gpr[gpr_t2_riscv64] = freebsd_gpr.t[2]; + + // x8-x9: s0-s1 (s0 is also fp) + posix_gpr.gpr[gpr_s0_riscv64] = freebsd_gpr.s[0]; + posix_gpr.gpr[gpr_s1_riscv64] = freebsd_gpr.s[1]; + + // x10-x17: a0-a7 + for (int i = 0; i < 8; i++) + posix_gpr.gpr[gpr_a0_riscv64 + i] = freebsd_gpr.a[i]; + + // x18-x27: s2-s11 + for (int i = 0; i < 10; i++) + posix_gpr.gpr[gpr_s2_riscv64 + i] = freebsd_gpr.s[2 + i]; + + // x28-x31: t3-t6 + posix_gpr.gpr[gpr_t3_riscv64] = freebsd_gpr.t[3]; + posix_gpr.gpr[gpr_t4_riscv64] = freebsd_gpr.t[4]; + posix_gpr.gpr[gpr_t5_riscv64] = freebsd_gpr.t[5]; + posix_gpr.gpr[gpr_t6_riscv64] = freebsd_gpr.t[6]; +} + +void NativeRegisterContextFreeBSD_riscv64::POSIXToFreeBSDGPR( + const RegisterInfoPOSIX_riscv64::GPR &posix_gpr, struct reg &freebsd_gpr) { + freebsd_gpr.sepc = posix_gpr.gpr[gpr_pc_riscv64]; // x0/pc + freebsd_gpr.ra = posix_gpr.gpr[gpr_ra_riscv64]; // x1/ra + freebsd_gpr.sp = posix_gpr.gpr[gpr_sp_riscv64]; // x2/sp + freebsd_gpr.gp = posix_gpr.gpr[gpr_gp_riscv64]; // x3/gp + freebsd_gpr.tp = posix_gpr.gpr[gpr_tp_riscv64]; // x4/tp + + // x5-x7: t0-t2 + freebsd_gpr.t[0] = posix_gpr.gpr[gpr_t0_riscv64]; + freebsd_gpr.t[1] = posix_gpr.gpr[gpr_t1_riscv64]; + freebsd_gpr.t[2] = posix_gpr.gpr[gpr_t2_riscv64]; + + // x8-x9: s0-s1 + freebsd_gpr.s[0] = posix_gpr.gpr[gpr_s0_riscv64]; + freebsd_gpr.s[1] = posix_gpr.gpr[gpr_s1_riscv64]; + + // x10-x17: a0-a7 + for (int i = 0; i < 8; i++) + freebsd_gpr.a[i] = posix_gpr.gpr[gpr_a0_riscv64 + i]; + + // x18-x27: s2-s11 + for (int i = 0; i < 10; i++) + freebsd_gpr.s[2 + i] = posix_gpr.gpr[gpr_s2_riscv64 + i]; + + // x28-x31: t3-t6 + freebsd_gpr.t[3] = posix_gpr.gpr[gpr_t3_riscv64]; + freebsd_gpr.t[4] = posix_gpr.gpr[gpr_t4_riscv64]; + freebsd_gpr.t[5] = posix_gpr.gpr[gpr_t5_riscv64]; + freebsd_gpr.t[6] = posix_gpr.gpr[gpr_t6_riscv64]; +} + +void NativeRegisterContextFreeBSD_riscv64::FreeBSDToPOSIXFPR( + const struct fpreg &freebsd_fpr, + RegisterInfoPOSIX_riscv64::FPR &posix_fpr) { + // FreeBSD stores FP registers as 128-bit (fp_x[32][2]) + // POSIX expects 64-bit (fpr[32]) + // We only use the lower 64 bits (D extension, double precision) + for (int i = 0; i < 32; i++) + posix_fpr.fpr[i] = freebsd_fpr.fp_x[i][0]; + + // FCSR: FreeBSD has 64-bit, POSIX expects 32-bit + posix_fpr.fcsr = static_cast<uint32_t>(freebsd_fpr.fp_fcsr); +} + +void NativeRegisterContextFreeBSD_riscv64::POSIXToFreeBSDFPR( + const RegisterInfoPOSIX_riscv64::FPR &posix_fpr, + struct fpreg &freebsd_fpr) { + // POSIX has 64-bit FP registers, FreeBSD expects 128-bit + for (int i = 0; i < 32; i++) { + freebsd_fpr.fp_x[i][0] = posix_fpr.fpr[i]; // Lower 64 bits + freebsd_fpr.fp_x[i][1] = 0; // Upper 64 bits (unused for D) + } + + // FCSR: POSIX has 32-bit, FreeBSD expects 64-bit + freebsd_fpr.fp_fcsr = static_cast<uint64_t>(posix_fpr.fcsr); +} + +// ============================================================================ +// Constructor and Setup +// ============================================================================ ---------------- DavidSpickett wrote:
Remove these headers. If you're doing them because they were in an existing file, I understand, but they are not much use and advised against these days. If you have important things to say about a particular function, you can add comments to that particular function. https://github.com/llvm/llvm-project/pull/180549 _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
