[Lldb-commits] [lldb] [lldb][RISCV] Implement trap handler unwind plan (PR #166531)
Georgiy Samoylov via lldb-commits
lldb-commits at lists.llvm.org
Tue Nov 18 04:09:32 PST 2025
================
@@ -302,12 +305,90 @@ static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) {
return unwind_plan_sp;
}
-lldb::UnwindPlanSP
-PlatformLinux::GetTrapHandlerUnwindPlan(const llvm::Triple &triple,
- ConstString name) {
+static lldb::UnwindPlanSP GetRISCVTrapHandlerUnwindPlan(ConstString name,
+ uint32_t fp_flags) {
+ if (name != "__vdso_rt_sigreturn")
+ return UnwindPlanSP{};
+
+ UnwindPlan::Row row;
+
+ // In the signal trampoline frame, sp points to an rt_sigframe[1], which is:
+ // - 128-byte siginfo struct
+ // - ucontext struct:
+ // - 8-byte long (uc_flags)
+ // - 8-byte pointer (*uc_link)
+ // - 24-byte struct (uc_stack)
+ // - 8-byte struct (uc_sigmask)
+ // - 120-byte of padding to allow sigset_t to be expanded in the future
+ // - 8 bytes of padding because sigcontext has 16-byte alignment
+ // - struct sigcontext uc_mcontext
+ // [1]
+ // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c
+
+ constexpr size_t siginfo_size = 128;
+ constexpr size_t uc_flags_size = 8;
+ constexpr size_t uc_link_ptr_size = 8;
+ constexpr size_t uc_stack_size = 24;
+ constexpr size_t uc_sigmask_size = 8;
+ constexpr size_t padding_size = 128;
+
+ constexpr size_t offset = siginfo_size + uc_flags_size + uc_link_ptr_size +
+ uc_stack_size + uc_sigmask_size + padding_size;
+
+ row.GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_riscv, offset);
+ for (uint32_t reg_num = gpr_first_riscv; reg_num < gpr_first_riscv + 32;
+ ++reg_num)
+ row.SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * 8, false);
+
+ size_t fpr_size = 0;
+ switch (fp_flags) {
+ case ArchSpec::eRISCV_float_abi_soft:
+ fpr_size = 0;
+ break;
+ case ArchSpec::eRISCV_float_abi_single:
+ fpr_size = 4;
+ break;
+ case ArchSpec::eRISCV_float_abi_double:
+ fpr_size = 8;
+ break;
+ case ArchSpec::eRISCV_float_abi_quad:
+ fpr_size = 16;
+ break;
+ default:
+ llvm_unreachable("Invalid RISC-V FP flags");
+ }
+
+ if (fpr_size != 0) {
+ for (uint32_t reg_num = fpr_first_riscv; reg_num < fpr_first_riscv + 32;
+ ++reg_num) {
+ row.SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * fpr_size,
+ false);
+ }
+
+ // CSR for FP registers always has 32-bit length
----------------
sga-sc wrote:
Addressed
https://github.com/llvm/llvm-project/pull/166531
More information about the lldb-commits
mailing list