|
15 | 15 | #endif |
16 | 16 |
|
17 | 17 | #include "Plugins/Process/Utility/LinuxSignals.h" |
| 18 | +#include "Plugins/Process/Utility/lldb-riscv-register-enums.h" |
18 | 19 | #include "Utility/ARM64_DWARF_Registers.h" |
19 | 20 | #include "lldb/Core/Debugger.h" |
20 | 21 | #include "lldb/Core/PluginManager.h" |
@@ -220,6 +221,7 @@ void PlatformLinux::CalculateTrapHandlerSymbolNames() { |
220 | 221 | m_trap_handlers.push_back(ConstString("_sigtramp")); |
221 | 222 | m_trap_handlers.push_back(ConstString("__kernel_rt_sigreturn")); |
222 | 223 | m_trap_handlers.push_back(ConstString("__restore_rt")); |
| 224 | + m_trap_handlers.push_back(ConstString("__vdso_rt_sigreturn")); |
223 | 225 | } |
224 | 226 |
|
225 | 227 | static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) { |
@@ -302,12 +304,56 @@ static lldb::UnwindPlanSP GetAArch64TrapHandlerUnwindPlan(ConstString name) { |
302 | 304 | return unwind_plan_sp; |
303 | 305 | } |
304 | 306 |
|
| 307 | +static lldb::UnwindPlanSP GetRISCVTrapHandlerUnwindPlan(ConstString name) { |
| 308 | + if (name != "__vdso_rt_sigreturn") |
| 309 | + return UnwindPlanSP{}; |
| 310 | + |
| 311 | + UnwindPlan::Row row; |
| 312 | + |
| 313 | + // In the signal trampoline frame, sp points to an rt_sigframe[1], which is: |
| 314 | + // - 128-byte siginfo struct |
| 315 | + // - ucontext struct: |
| 316 | + // - 8-byte long (uc_flags) |
| 317 | + // - 8-byte pointer (*uc_link) |
| 318 | + // - 24-byte struct (uc_stack) |
| 319 | + // - 8-byte struct (uc_sigmask) |
| 320 | + // - 120-byte of padding to allow sigset_t to be expanded in the future |
| 321 | + // - 8 bytes of padding because sigcontext has 16-byte alignment |
| 322 | + // - struct sigcontext uc_mcontext |
| 323 | + // [1] |
| 324 | + // https://github.com/torvalds/linux/blob/master/arch/riscv/kernel/signal.c |
| 325 | + |
| 326 | + constexpr size_t siginfo_size = 128; |
| 327 | + constexpr size_t uc_flags_size = 8; |
| 328 | + constexpr size_t uc_link_ptr_size = 8; |
| 329 | + constexpr size_t uc_stack_size = 24; |
| 330 | + constexpr size_t uc_sigmask_size = 8; |
| 331 | + constexpr size_t padding_size = 128; |
| 332 | + |
| 333 | + constexpr size_t offset = siginfo_size + uc_flags_size + uc_link_ptr_size + |
| 334 | + uc_stack_size + uc_sigmask_size + padding_size; |
| 335 | + |
| 336 | + row.GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_riscv, offset); |
| 337 | + for (uint32_t reg_num = 0; reg_num <= 31; ++reg_num) |
| 338 | + row.SetRegisterLocationToAtCFAPlusOffset(reg_num, reg_num * 8, false); |
| 339 | + |
| 340 | + UnwindPlanSP unwind_plan_sp = std::make_shared<UnwindPlan>(eRegisterKindLLDB); |
| 341 | + unwind_plan_sp->AppendRow(std::move(row)); |
| 342 | + unwind_plan_sp->SetSourceName("RISC-V Linux sigcontext"); |
| 343 | + unwind_plan_sp->SetSourcedFromCompiler(eLazyBoolYes); |
| 344 | + unwind_plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); |
| 345 | + unwind_plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolYes); |
| 346 | + |
| 347 | + return unwind_plan_sp; |
| 348 | +} |
| 349 | + |
305 | 350 | lldb::UnwindPlanSP |
306 | 351 | PlatformLinux::GetTrapHandlerUnwindPlan(const llvm::Triple &triple, |
307 | 352 | ConstString name) { |
308 | 353 | if (triple.isAArch64()) |
309 | 354 | return GetAArch64TrapHandlerUnwindPlan(name); |
310 | | - |
| 355 | + if (triple.isRISCV()) |
| 356 | + return GetRISCVTrapHandlerUnwindPlan(name); |
311 | 357 | return {}; |
312 | 358 | } |
313 | 359 |
|
|
0 commit comments