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)); }
static void bfin_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); CORE_ADDR sp = get_frame_sp (this_frame); CORE_ADDR pc = get_frame_pc (this_frame); CORE_ADDR sigcontext = sp + SIGCONTEXT_OFFSET; const int *reg_offset = bfin_linux_sigcontext_reg_offset; int i; if (gdbarch == NULL) { ; /* ??? */ } for (i = 0; i < BFIN_NUM_REGS; i++) if (reg_offset[i] != -1) trad_frame_set_reg_addr (this_cache, i, sigcontext + reg_offset[i]); /* This would come after the LINK instruction in the ret_from_signal function, hence the frame id would be SP + 8. */ trad_frame_set_id (this_cache, frame_id_build (sp + 8, pc)); }
static int derive_stack_segment (bfd_vma *bottom, bfd_vma *top) { struct frame_info *fi, *tmp_fi; gdb_assert (bottom); gdb_assert (top); /* Can't succeed without stack and registers. */ if (!target_has_stack || !target_has_registers) return 0; /* Can't succeed without current frame. */ fi = get_current_frame (); if (fi == NULL) return 0; /* Save frame pointer of TOS frame. */ *top = get_frame_base (fi); /* If current stack pointer is more "inner", use that instead. */ if (gdbarch_inner_than (current_gdbarch, get_frame_sp (fi), *top)) *top = get_frame_sp (fi); /* Find prev-most frame. */ while ((tmp_fi = get_prev_frame (fi)) != NULL) fi = tmp_fi; /* Save frame pointer of prev-most frame. */ *bottom = get_frame_base (fi); /* Now canonicalize their order, so that BOTTOM is a lower address (as opposed to a lower stack frame). */ if (*bottom > *top) { bfd_vma tmp_vma; tmp_vma = *top; *top = *bottom; *bottom = tmp_vma; } return 1; }
static void mips_linux_n32n64_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 ireg, reg_position; CORE_ADDR frame_sp = get_frame_sp (this_frame); CORE_ADDR sigcontext_base; const struct mips_regnum *regs = mips_regnum (gdbarch); if (self == &mips_linux_n32_rt_sigframe) sigcontext_base = frame_sp + N32_SIGFRAME_SIGCONTEXT_OFFSET; else sigcontext_base = frame_sp + N64_SIGFRAME_SIGCONTEXT_OFFSET; if (mips_linux_restart_reg_p (gdbarch)) trad_frame_set_reg_addr (this_cache, (MIPS_RESTART_REGNUM + gdbarch_num_regs (gdbarch)), sigcontext_base + N64_SIGCONTEXT_REGS); for (ireg = 1; ireg < 32; ireg++) trad_frame_set_reg_addr (this_cache, ireg + MIPS_ZERO_REGNUM + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_REGS + ireg * N64_SIGCONTEXT_REG_SIZE); for (ireg = 0; ireg < 32; ireg++) trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_FPREGS + ireg * N64_SIGCONTEXT_REG_SIZE); trad_frame_set_reg_addr (this_cache, regs->pc + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_PC); trad_frame_set_reg_addr (this_cache, regs->fp_control_status + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_FPCSR); trad_frame_set_reg_addr (this_cache, regs->hi + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_HI); trad_frame_set_reg_addr (this_cache, regs->lo + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_LO); /* Choice of the bottom of the sigframe is somewhat arbitrary. */ trad_frame_set_id (this_cache, frame_id_build (frame_sp, func)); }
static void mips_linux_o32_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 ireg, reg_position; CORE_ADDR frame_sp = get_frame_sp (this_frame); CORE_ADDR sigcontext_base; const struct mips_regnum *regs = mips_regnum (gdbarch); CORE_ADDR regs_base; if (self == &mips_linux_o32_sigframe) sigcontext_base = frame_sp + SIGFRAME_SIGCONTEXT_OFFSET; else sigcontext_base = frame_sp + RTSIGFRAME_SIGCONTEXT_OFFSET; /* I'm not proud of this hack. Eventually we will have the infrastructure to indicate the size of saved registers on a per-frame basis, but right now we don't; the kernel saves eight bytes but we only want four. Use regs_base to access any 64-bit fields. */ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) regs_base = sigcontext_base + 4; else regs_base = sigcontext_base; if (mips_linux_restart_reg_p (gdbarch)) trad_frame_set_reg_addr (this_cache, (MIPS_RESTART_REGNUM + gdbarch_num_regs (gdbarch)), regs_base + SIGCONTEXT_REGS); for (ireg = 1; ireg < 32; ireg++) trad_frame_set_reg_addr (this_cache, ireg + MIPS_ZERO_REGNUM + gdbarch_num_regs (gdbarch), regs_base + SIGCONTEXT_REGS + ireg * SIGCONTEXT_REG_SIZE); /* The way that floating point registers are saved, unfortunately, depends on the architecture the kernel is built for. For the r3000 and tx39, four bytes of each register are at the beginning of each of the 32 eight byte slots. For everything else, the registers are saved using double precision; only the even-numbered slots are initialized, and the high bits are the odd-numbered register. Assume the latter layout, since we can't tell, and it's much more common. Which bits are the "high" bits depends on endianness. */ for (ireg = 0; ireg < 32; ireg++) if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (ireg & 1)) trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + gdbarch_num_regs (gdbarch), sigcontext_base + SIGCONTEXT_FPREGS + 4 + (ireg & ~1) * SIGCONTEXT_REG_SIZE); else trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + gdbarch_num_regs (gdbarch), sigcontext_base + SIGCONTEXT_FPREGS + (ireg & ~1) * SIGCONTEXT_REG_SIZE); trad_frame_set_reg_addr (this_cache, regs->pc + gdbarch_num_regs (gdbarch), regs_base + SIGCONTEXT_PC); trad_frame_set_reg_addr (this_cache, regs->fp_control_status + gdbarch_num_regs (gdbarch), sigcontext_base + SIGCONTEXT_FPCSR); trad_frame_set_reg_addr (this_cache, regs->hi + gdbarch_num_regs (gdbarch), regs_base + SIGCONTEXT_HI); trad_frame_set_reg_addr (this_cache, regs->lo + gdbarch_num_regs (gdbarch), regs_base + SIGCONTEXT_LO); trad_frame_set_reg_addr (this_cache, regs->cause + gdbarch_num_regs (gdbarch), sigcontext_base + SIGCONTEXT_CAUSE); trad_frame_set_reg_addr (this_cache, regs->badvaddr + gdbarch_num_regs (gdbarch), sigcontext_base + SIGCONTEXT_BADVADDR); /* Choice of the bottom of the sigframe is somewhat arbitrary. */ trad_frame_set_id (this_cache, frame_id_build (frame_sp, func)); }