[Lldb-commits] [lldb] [lldb][RISCV] Implement trap handler unwind plan (PR #166531)
Georgiy Samoylov via lldb-commits
lldb-commits at lists.llvm.org
Wed Nov 5 03:02:34 PST 2025
https://github.com/sga-sc created https://github.com/llvm/llvm-project/pull/166531
This patch introduces special unwind plan for trap handling for RISC-V
>From f2343120cd1b98cd43eff6daae798fd583ff7065 Mon Sep 17 00:00:00 2001
From: Georgiy Samoylov <g.samoylov at syntacore.com>
Date: Thu, 23 Oct 2025 13:12:32 +0300
Subject: [PATCH 1/2] [lldb][RISCV] Implement trap handler unwind plan
---
.../Plugins/Platform/Linux/PlatformLinux.cpp | 49 ++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
index da14da44f5939..d7c15f19f5d69 100644
--- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -15,6 +15,7 @@
#endif
#include "Plugins/Process/Utility/LinuxSignals.h"
+#include "Plugins/Process/Utility/lldb-riscv-register-enums.h"
#include "Utility/ARM64_DWARF_Registers.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
@@ -220,6 +221,7 @@ void PlatformLinux::CalculateTrapHandlerSymbolNames() {
m_trap_handlers.push_back(ConstString("_sigtramp"));
m_trap_handlers.push_back(ConstString("__kernel_rt_sigreturn"));
m_trap_handlers.push_back(ConstString("__restore_rt"));
+ m_trap_handlers.push_back(ConstString("__vdso_rt_sigreturn"));
}
static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) {
@@ -302,12 +304,57 @@ static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) {
return unwind_plan_sp;
}
+static lldb::UnwindPlanSP GetRISCVTrapHandlerUnwindPlan(ConstString name) {
+ if (name != "__vdso_rt_sigreturn")
+ return UnwindPlanSP{};
+
+ UnwindPlan::RowSP row = std::make_shared<UnwindPlan::Row>();
+ row->SetOffset(0);
+
+ // 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 = 0; reg_num <= 31; ++reg_num)
+ row->SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * 8, false);
+
+ UnwindPlanSP unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindLLDB);
+ unwind_plan_sp->AppendRow(row);
+ unwind_plan_sp->SetSourceName("RISC-V Linux sigcontext");
+ unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes);
+ unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes);
+
+ return unwind_plan_sp;
+}
+
lldb::UnwindPlanSP
PlatformLinux::GetTrapHandlerUnwindPlan(const llvm::Triple &triple,
ConstString name) {
if (triple.isAArch64())
return GetAArch64TrapHandlerUnwindPlan(name);
-
+ if (triple.isRISCV())
+ return GetRISCVTrapHandlerUnwindPlan(name);
return {};
}
>From 3b72ba2cb51871e940f9be8c0671d1e693f23974 Mon Sep 17 00:00:00 2001
From: Georgiy Samoylov <g.samoylov at syntacore.com>
Date: Thu, 23 Oct 2025 13:34:54 +0300
Subject: [PATCH 2/2] [lldb][RISCV] Mark default unwind plans they couldn't be
used for trap handling
After we introduced a special unwind plan for trap handling, we should
mark that other unwind plans for RISC-V can't be used in the same case.
---
lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
index a5547a4699ca9..d209980d65589 100644
--- a/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
+++ b/lldb/source/Plugins/ABI/RISCV/ABISysV_riscv.cpp
@@ -735,6 +735,8 @@ UnwindPlanSP ABISysV_riscv::CreateFunctionEntryUnwindPlan() {
plan_sp->AppendRow(std::move(row));
plan_sp->SetSourceName("riscv function-entry unwind plan");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
+ plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
+
return plan_sp;
}
@@ -761,6 +763,8 @@ UnwindPlanSP ABISysV_riscv::CreateDefaultUnwindPlan() {
plan_sp->SetSourceName("riscv default unwind plan");
plan_sp->SetSourcedFromCompiler(eLazyBoolNo);
plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
+ plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo);
+
return plan_sp;
}
More information about the lldb-commits
mailing list