-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[lldb][RISCV] Implement trap handler unwind plan #166531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-lldb @llvm/pr-subscribers-backend-risc-v Author: Georgiy Samoylov (sga-sc) ChangesThis patch introduces special unwind plan for trap handling for RISC-V Full diff: https://github.com/llvm/llvm-project/pull/166531.diff 2 Files Affected:
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;
}
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 {};
}
|
|
Unless this fixes an existing test case, you could adapt the one from 9db2541 to work for RISC-V. I put it in the AArch64 folder but it can be moved somewhere generic. The specific bits are the |
|
I forgot to mention that this patch fixes TestHandleAbort on RISC-V. I'll change PR description for this |
…p 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.
3b72ba2 to
f52f1e7
Compare
|
Cool. Now I see that I enabled that test for AArch64 Linux at the time, but added the new one to check the register values. Not sure why I didn't hack something into the existing one. Anyway, this is a net improvement as is and if you want to add more checks later there's something for you to crib from. |
This patch introduces special unwind plan for trap handling for RISC-V and fixes
TestHandleAbort