+#define SIGFRAME_SIGINFO_SIZE 128
+#define UCONTEXT_MCONTEXT_OFFSET 176
+
+static void
+riscv_linux_sigframe_init (const struct tramp_frame *self,
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ int xlen = riscv_isa_xlen (gdbarch);
+ int flen = riscv_isa_flen (gdbarch);
+ CORE_ADDR frame_sp = get_frame_sp (this_frame);
+ CORE_ADDR mcontext_base;
+ CORE_ADDR regs_base;
+
+ mcontext_base = frame_sp + SIGFRAME_SIGINFO_SIZE + UCONTEXT_MCONTEXT_OFFSET;
+
+ /* Handle the integer registers. The first one is PC, followed by x1
+ through x31. */
+ regs_base = mcontext_base;
+ trad_frame_set_reg_addr (this_cache, RISCV_PC_REGNUM, regs_base);
+ for (int i = 1; i < 32; i++)
+ trad_frame_set_reg_addr (this_cache, RISCV_ZERO_REGNUM + i,
+ regs_base + (i * xlen));
+
+ /* Handle the FP registers. First comes the 32 FP registers, followed by
+ fcsr. */
+ regs_base += 32 * xlen;
+ for (int i = 0; i < 32; i++)
+ trad_frame_set_reg_addr (this_cache, RISCV_FIRST_FP_REGNUM + i,
+ regs_base + (i * flen));
+ regs_base += 32 * flen;
+ trad_frame_set_reg_addr (this_cache, RISCV_CSR_FCSR_REGNUM, regs_base);
+
+ /* Choice of the bottom of the sigframe is somewhat arbitrary. */
+ trad_frame_set_id (this_cache, frame_id_build (frame_sp, func));