From 5c6e69fe513467e1026bfd6ba5cbaf4a855921c5 Mon Sep 17 00:00:00 2001 From: Georgiy Samoylov 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 | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index da14da44f5939..1bcf97a9ff3d5 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,56 @@ static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) { return unwind_plan_sp; } +static lldb::UnwindPlanSP GetRISCVTrapHandlerUnwindPlan(ConstString name) { + 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 = 0; reg_num <= 31; ++reg_num) + row.SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * 8, false); + + UnwindPlanSP unwind_plan_sp = std::make_shared(eRegisterKindLLDB); + unwind_plan_sp->AppendRow(std::move(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 f52f1e7919ede0920434e90d3ca9fe7a2fd6649b Mon Sep 17 00:00:00 2001 From: Georgiy Samoylov 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; }