https://github.com/sga-sc updated https://github.com/llvm/llvm-project/pull/166531
>From 39aa9af9ea31abc26d9bf719fb1a9579a90d647e Mon Sep 17 00:00:00 2001 From: Georgiy Samoylov <[email protected]> Date: Thu, 23 Oct 2025 13:12:32 +0300 Subject: [PATCH 1/3] [lldb][RISCV] Implement trap handler unwind plan --- lldb/include/lldb/Target/Platform.h | 8 +- .../Plugins/Platform/Linux/PlatformLinux.cpp | 89 ++++++++++++++++++- .../Plugins/Platform/Linux/PlatformLinux.h | 2 +- lldb/source/Target/RegisterContextUnwind.cpp | 4 +- 4 files changed, 92 insertions(+), 11 deletions(-) diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index 35ffdabf907e7..7bedde92b81a2 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -778,8 +778,8 @@ class Platform : public PluginInterface { /// Try to get a specific unwind plan for a named trap handler. /// The default is not to have specific unwind plans for trap handlers. /// - /// \param[in] triple - /// Triple of the current target. + /// \param[in] arch + /// Architecture of the current target. /// /// \param[in] name /// Name of the trap handler function. @@ -788,8 +788,8 @@ class Platform : public PluginInterface { /// A specific unwind plan for that trap handler, or an empty /// shared pointer. The latter means there is no specific plan, /// unwind as normal. - virtual lldb::UnwindPlanSP - GetTrapHandlerUnwindPlan(const llvm::Triple &triple, ConstString name) { + virtual lldb::UnwindPlanSP GetTrapHandlerUnwindPlan(const ArchSpec &arch, + ConstString name) { return {}; } diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp index da14da44f5939..d6acf7971537a 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" @@ -22,6 +23,7 @@ #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" @@ -220,6 +222,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 +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 + row.SetRegisterLocationToAtCFAPlusOffset(fpr_fcsr_riscv, fpr_fcsr_riscv * 4, + false); + } + + UnwindPlanSP unwind_plan_sp = std::make_shared<UnwindPlan>(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 ArchSpec &arch, + ConstString name) { + llvm::Triple triple = arch.GetTriple(); if (triple.isAArch64()) return GetAArch64TrapHandlerUnwindPlan(name); - + if (triple.isRISCV()) { + uint32_t fp_flags = arch.GetFlags() & ArchSpec::eRISCV_float_abi_mask; + return GetRISCVTrapHandlerUnwindPlan(name, fp_flags); + } return {}; } diff --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h index 0fd33b03dcd23..cf6a60874b04e 100644 --- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h +++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h @@ -52,7 +52,7 @@ class PlatformLinux : public PlatformPOSIX { void CalculateTrapHandlerSymbolNames() override; - lldb::UnwindPlanSP GetTrapHandlerUnwindPlan(const llvm::Triple &triple, + lldb::UnwindPlanSP GetTrapHandlerUnwindPlan(const ArchSpec &arch, ConstString name) override; MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr, diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp index 252bee2b5d72a..0755d21bc8cc4 100644 --- a/lldb/source/Target/RegisterContextUnwind.cpp +++ b/lldb/source/Target/RegisterContextUnwind.cpp @@ -907,9 +907,9 @@ RegisterContextUnwind::GetFullUnwindPlanForFrame() { // substitute plan. Otherwise, use eh_frame. if (m_sym_ctx_valid) { lldb::PlatformSP platform = process->GetTarget().GetPlatform(); + const ArchSpec arch = process->GetTarget().GetArchitecture(); if (auto unwind_plan_sp = platform->GetTrapHandlerUnwindPlan( - process->GetTarget().GetArchitecture().GetTriple(), - GetSymbolOrFunctionName(m_sym_ctx))) + arch, GetSymbolOrFunctionName(m_sym_ctx))) return unwind_plan_sp; } >From 249016970b1eadfb976c06d314afa6a328bc06d0 Mon Sep 17 00:00:00 2001 From: Georgiy Samoylov <[email protected]> Date: Thu, 23 Oct 2025 13:34:54 +0300 Subject: [PATCH 2/3] [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; } >From a882f514a840fc1eb3f437b5804f49306d0f590c Mon Sep 17 00:00:00 2001 From: Georgiy Samoylov <[email protected]> Date: Mon, 17 Nov 2025 16:47:34 +0300 Subject: [PATCH 3/3] [lldb] Change GetTrapHandlerUnwindPlan interface --- lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp | 5 ++--- lldb/source/Plugins/Platform/AIX/PlatformAIX.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp b/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp index 21724d83133e9..2122d5d08cb1b 100644 --- a/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp +++ b/lldb/source/Plugins/Platform/AIX/PlatformAIX.cpp @@ -132,9 +132,8 @@ void PlatformAIX::GetStatus(Stream &strm) { void PlatformAIX::CalculateTrapHandlerSymbolNames() {} -lldb::UnwindPlanSP -PlatformAIX::GetTrapHandlerUnwindPlan(const llvm::Triple &triple, - ConstString name) { +lldb::UnwindPlanSP PlatformAIX::GetTrapHandlerUnwindPlan(const ArchSpec &arch, + ConstString name) { return {}; } diff --git a/lldb/source/Plugins/Platform/AIX/PlatformAIX.h b/lldb/source/Plugins/Platform/AIX/PlatformAIX.h index 92b4f6c0ed426..b7f6a62f65c9f 100644 --- a/lldb/source/Plugins/Platform/AIX/PlatformAIX.h +++ b/lldb/source/Plugins/Platform/AIX/PlatformAIX.h @@ -47,7 +47,7 @@ class PlatformAIX : public PlatformPOSIX { void CalculateTrapHandlerSymbolNames() override; - lldb::UnwindPlanSP GetTrapHandlerUnwindPlan(const llvm::Triple &triple, + lldb::UnwindPlanSP GetTrapHandlerUnwindPlan(const ArchSpec &arch, ConstString name) override; MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr, _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
