static void aarch64_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_register_unsigned (this_frame, AARCH64_SP_REGNUM); CORE_ADDR sigcontext_addr = sp + AARCH64_RT_SIGFRAME_UCONTEXT_OFFSET + AARCH64_UCONTEXT_SIGCONTEXT_OFFSET; int i; for (i = 0; i < 31; i++) { trad_frame_set_reg_addr (this_cache, AARCH64_X0_REGNUM + i, sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET + i * AARCH64_SIGCONTEXT_REG_SIZE); } trad_frame_set_reg_addr (this_cache, AARCH64_SP_REGNUM, sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET + 31 * AARCH64_SIGCONTEXT_REG_SIZE); trad_frame_set_reg_addr (this_cache, AARCH64_PC_REGNUM, sigcontext_addr + AARCH64_SIGCONTEXT_XO_OFFSET + 32 * AARCH64_SIGCONTEXT_REG_SIZE); trad_frame_set_id (this_cache, frame_id_build (sp, func)); }
static struct trad_frame_cache * vaxobsd_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) { struct trad_frame_cache *cache; CORE_ADDR addr, base, func; if (*this_cache) return *this_cache; cache = trad_frame_cache_zalloc (next_frame); *this_cache = cache; func = frame_pc_unwind (next_frame); func &= ~(vaxobsd_page_size - 1); base = frame_unwind_register_unsigned (next_frame, VAX_SP_REGNUM); addr = get_frame_memory_unsigned (next_frame, base - 4, 4); trad_frame_set_reg_addr (cache, VAX_SP_REGNUM, addr + 8); trad_frame_set_reg_addr (cache, VAX_FP_REGNUM, addr + 12); trad_frame_set_reg_addr (cache, VAX_AP_REGNUM, addr + 16); trad_frame_set_reg_addr (cache, VAX_PC_REGNUM, addr + 20); trad_frame_set_reg_addr (cache, VAX_PS_REGNUM, addr + 24); /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (base, func)); return cache; }
static void m68kobsd_sigtramp_cache_init (const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { CORE_ADDR addr, base, pc; int regnum; base = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM); /* The 'addql #4,%sp' instruction at offset 8 adjusts the stack pointer. Adjust the frame base accordingly. */ pc = get_frame_register_unsigned (this_frame, M68K_PC_REGNUM); if ((pc - func) > 8) base -= 4; /* Get frame pointer, stack pointer, program counter and processor state from `struct sigcontext'. */ addr = get_frame_memory_unsigned (this_frame, base + 8, 4); trad_frame_set_reg_addr (this_cache, M68K_FP_REGNUM, addr + 8); trad_frame_set_reg_addr (this_cache, M68K_SP_REGNUM, addr + 12); trad_frame_set_reg_addr (this_cache, M68K_PC_REGNUM, addr + 20); trad_frame_set_reg_addr (this_cache, M68K_PS_REGNUM, addr + 24); /* The sc_ap member of `struct sigcontext' points to additional hardware state. Here we find the missing registers. */ addr = get_frame_memory_unsigned (this_frame, addr + 16, 4) + 4; for (regnum = M68K_D0_REGNUM; regnum < M68K_FP_REGNUM; regnum++, addr += 4) trad_frame_set_reg_addr (this_cache, regnum, addr); /* Construct the frame ID using the function start. */ trad_frame_set_id (this_cache, frame_id_build (base, func)); }
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 alphanbsd_sigtramp_cache_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); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); CORE_ADDR addr, sp; int i; sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM); if (self == &alphanbsd_sigtramp_sc1) { addr = sp; } else { addr = sp + 128 + 56; } for (i = 0; i < 32; i++, addr += ALPHA_REGISTER_SIZE) { trad_frame_set_reg_addr (this_cache, i, addr); } trad_frame_set_reg_addr (this_cache, ALPHA_PC_REGNUM, addr); /* Construct the frame ID using the function start. */ trad_frame_set_id (this_cache, frame_id_build (sp, func)); }
static struct trad_frame_cache * aix_sighandle_frame_cache (struct frame_info *this_frame, void **this_cache) { LONGEST backchain; CORE_ADDR base, base_orig, func; struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *this_trad_cache; if ((*this_cache) != NULL) return (struct trad_frame_cache *) (*this_cache); this_trad_cache = trad_frame_cache_zalloc (this_frame); (*this_cache) = this_trad_cache; base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); base_orig = base; if (tdep->wordsize == 4) { func = read_memory_unsigned_integer (base_orig + SIG_FRAME_PC_OFFSET + 8, tdep->wordsize, byte_order); safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET + 8, tdep->wordsize, byte_order, &backchain); base = (CORE_ADDR)backchain; } else { func = read_memory_unsigned_integer (base_orig + SIG_FRAME_LR_OFFSET64, tdep->wordsize, byte_order); safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET64, tdep->wordsize, byte_order, &backchain); base = (CORE_ADDR)backchain; } trad_frame_set_reg_value (this_trad_cache, gdbarch_pc_regnum (gdbarch), func); trad_frame_set_reg_value (this_trad_cache, gdbarch_sp_regnum (gdbarch), base); if (tdep->wordsize == 4) trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum, base_orig + 0x38 + 52 + 8); else trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum, base_orig + 0x70 + 320); trad_frame_set_id (this_trad_cache, frame_id_build (base, func)); trad_frame_set_this_base (this_trad_cache, base); return this_trad_cache; }
static void tic6x_linux_rt_sigreturn_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_register_unsigned (this_frame, TIC6X_SP_REGNUM); /* The base of struct sigcontext is computed by examining the definition of struct rt_sigframe in linux kernel source arch/c6x/kernel/signal.c. */ CORE_ADDR base = (sp + TIC6X_SP_RT_SIGFRAME /* Pointer type *pinfo and *puc in struct rt_sigframe. */ + 4 + 4 + TIC6X_SIGINFO_SIZE + 4 + 4 /* uc_flags and *uc_link in struct ucontext. */ + TIC6X_STACK_T_SIZE); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); unsigned int reg_offset; unsigned int i; for (i = 0; i < 10; i++) /* A0 - A9 */ { reg_offset = tic6x_register_sigcontext_offset (i, gdbarch); gdb_assert (reg_offset != 0); trad_frame_set_reg_addr (this_cache, i, base + reg_offset); } for (i = TIC6X_B0_REGNUM; i < TIC6X_B0_REGNUM + 10; i++) /* B0 - B9 */ { reg_offset = tic6x_register_sigcontext_offset (i, gdbarch); gdb_assert (reg_offset != 0); trad_frame_set_reg_addr (this_cache, i, base + reg_offset); } if (tdep->has_gp) for (i = 34; i < 34 + 32; i++) /* A16 - A31, B16 - B31 */ { reg_offset = tic6x_register_sigcontext_offset (i, gdbarch); gdb_assert (reg_offset != 0); trad_frame_set_reg_addr (this_cache, i, base + reg_offset); } trad_frame_set_reg_addr (this_cache, TIC6X_PC_REGNUM, base + tic6x_register_sigcontext_offset (TIC6X_PC_REGNUM, gdbarch)); trad_frame_set_reg_addr (this_cache, TIC6X_SP_REGNUM, base + tic6x_register_sigcontext_offset (TIC6X_SP_REGNUM, gdbarch)); /* Save a frame ID. */ trad_frame_set_id (this_cache, frame_id_build (sp, func)); }
static void sh_linux_sigtramp_cache (struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func, int regs_offset) { int i; struct gdbarch *gdbarch = get_frame_arch (this_frame); CORE_ADDR base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); CORE_ADDR regs = base + regs_offset; for (i = 0; i < 18; i++) trad_frame_set_reg_addr (this_cache, i, regs + i * 4); trad_frame_set_reg_addr (this_cache, SR_REGNUM, regs + 18 * 4); trad_frame_set_reg_addr (this_cache, GBR_REGNUM, regs + 19 * 4); trad_frame_set_reg_addr (this_cache, MACH_REGNUM, regs + 20 * 4); trad_frame_set_reg_addr (this_cache, MACL_REGNUM, regs + 21 * 4); /* Restore FP state if we have an FPU. */ if (gdbarch_fp0_regnum (gdbarch) != -1) { CORE_ADDR fpregs = regs + 22 * 4; for (i = FR0_REGNUM; i <= FP_LAST_REGNUM; i++) trad_frame_set_reg_addr (this_cache, i, fpregs + i * 4); trad_frame_set_reg_addr (this_cache, FPSCR_REGNUM, fpregs + 32 * 4); trad_frame_set_reg_addr (this_cache, FPUL_REGNUM, fpregs + 33 * 4); } /* Save a frame ID. */ trad_frame_set_id (this_cache, frame_id_build (base, func)); }
static void ppc_linux_sigtramp_cache (struct frame_info *next_frame, struct trad_frame_cache *this_cache, CORE_ADDR func, LONGEST offset, int bias) { CORE_ADDR base; CORE_ADDR regs; CORE_ADDR gpregs; CORE_ADDR fpregs; int i; struct gdbarch *gdbarch = get_frame_arch (next_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); base = frame_unwind_register_unsigned (next_frame, gdbarch_sp_regnum (current_gdbarch)); if (bias > 0 && frame_pc_unwind (next_frame) != func) /* See below, some signal trampolines increment the stack as their first instruction, need to compensate for that. */ base -= bias; /* Find the address of the register buffer pointer. */ regs = base + offset; /* Use that to find the address of the corresponding register buffers. */ gpregs = read_memory_unsigned_integer (regs, tdep->wordsize); fpregs = gpregs + 48 * tdep->wordsize; /* General purpose. */ for (i = 0; i < 32; i++) { int regnum = i + tdep->ppc_gp0_regnum; trad_frame_set_reg_addr (this_cache, regnum, gpregs + i * tdep->wordsize); } trad_frame_set_reg_addr (this_cache, gdbarch_pc_regnum (current_gdbarch), gpregs + 32 * tdep->wordsize); trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, gpregs + 35 * tdep->wordsize); trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, gpregs + 36 * tdep->wordsize); trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, gpregs + 37 * tdep->wordsize); trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, gpregs + 38 * tdep->wordsize); if (ppc_floating_point_unit_p (gdbarch)) { /* Floating point registers. */ for (i = 0; i < 32; i++) { int regnum = i + gdbarch_fp0_regnum (current_gdbarch); trad_frame_set_reg_addr (this_cache, regnum, fpregs + i * tdep->wordsize); } trad_frame_set_reg_addr (this_cache, tdep->ppc_fpscr_regnum, fpregs + 32 * tdep->wordsize); } trad_frame_set_id (this_cache, frame_id_build (base, func)); }
static void microblaze_linux_sigtramp_cache (struct frame_info *next_frame, struct trad_frame_cache *this_cache, CORE_ADDR func, LONGEST offset, int bias) { CORE_ADDR base; CORE_ADDR gpregs; int regnum; base = frame_unwind_register_unsigned (next_frame, MICROBLAZE_SP_REGNUM); if (bias > 0 && get_frame_address_in_block (next_frame) != func) /* See below, some signal trampolines increment the stack as their first instruction, need to compensate for that. */ base -= bias; /* Find the address of the register buffer. */ gpregs = base + offset; /* Registers saved on stack. */ for (regnum = 0; regnum < MICROBLAZE_BTR_REGNUM; regnum++) trad_frame_set_reg_addr (this_cache, regnum, gpregs + regnum * MICROBLAZE_REGISTER_SIZE); trad_frame_set_id (this_cache, frame_id_build (base, 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 void hppanbsd_sigtramp_cache_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); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); CORE_ADDR sp = get_frame_register_unsigned (this_frame, HPPA_SP_REGNUM); CORE_ADDR base; int *reg_offset; int num_regs; int i; reg_offset = hppanbsd_mc_reg_offset; num_regs = ARRAY_SIZE (hppanbsd_mc_reg_offset); /* frame pointer */ base = sp - 0x280; /* offsetof(struct sigframe_siginfo, sf_uc) = 128 */ base += 128; /* offsetof(ucontext_t, uc_mcontext) == 40 */ base += 40; for (i = 0; i < num_regs; i++) if (reg_offset[i] != -1) trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]); /* Construct the frame ID using the function start. */ trad_frame_set_id (this_cache, frame_id_build (sp, func)); }
static void tilegx_linux_sigframe_init (const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { CORE_ADDR sp = get_frame_register_unsigned (this_frame, 54); /* Base address of register save area. */ CORE_ADDR base = sp + 16 /* Skip ABI_SAVE_AREA. */ + 128 /* Skip SIGINFO. */ + 40; /* Skip UCONTEXT. */ /* Address of saved LR register (R56) which holds previous PC. */ CORE_ADDR prev_pc = base + 56 * 8; int i; for (i = 0; i < 56; i++) trad_frame_set_reg_addr (this_cache, i, base + i * 8); trad_frame_set_reg_value (this_cache, 64, get_frame_memory_unsigned (this_frame, prev_pc, 8)); /* Save a frame ID. */ trad_frame_set_id (this_cache, frame_id_build (base, func)); }
static void mips64_fbsd_sigframe_init (const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *cache, CORE_ADDR func) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR sp, ucontext_addr, addr; int regnum; gdb_byte buf[4]; /* We find the appropriate instance of `ucontext_t' at a fixed offset in the signal frame. */ sp = get_frame_register_signed (this_frame, MIPS_SP_REGNUM + gdbarch_num_regs (gdbarch)); ucontext_addr = sp + N64_SIGFRAME_UCONTEXT_OFFSET; /* PC. */ regnum = mips_regnum (gdbarch)->pc; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), ucontext_addr + N64_UCONTEXT_PC); /* GPRs. */ for (regnum = MIPS_ZERO_REGNUM, addr = ucontext_addr + N64_UCONTEXT_REGS; regnum <= MIPS_RA_REGNUM; regnum++, addr += N64_UCONTEXT_REG_SIZE) trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), addr); regnum = MIPS_PS_REGNUM; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), ucontext_addr + N64_UCONTEXT_SR); /* HI and LO. */ regnum = mips_regnum (gdbarch)->lo; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), ucontext_addr + N64_UCONTEXT_LO); regnum = mips_regnum (gdbarch)->hi; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (gdbarch), ucontext_addr + N64_UCONTEXT_HI); if (target_read_memory (ucontext_addr + N64_UCONTEXT_FPUSED, buf, 4) == 0 && extract_unsigned_integer (buf, 4, byte_order) != 0) { for (regnum = 0, addr = ucontext_addr + N64_UCONTEXT_FPREGS; regnum < 32; regnum++, addr += N64_UCONTEXT_REG_SIZE) trad_frame_set_reg_addr (cache, regnum + gdbarch_fp0_regnum (gdbarch), addr); trad_frame_set_reg_addr (cache, mips_regnum (gdbarch)->fp_control_status, addr); } trad_frame_set_id (cache, frame_id_build (sp, func)); }
static void mips64obsd_sigframe_init (const struct tramp_frame *self, struct frame_info *next_frame, struct trad_frame_cache *cache, CORE_ADDR func) { struct gdbarch *gdbarch = get_frame_arch (next_frame); CORE_ADDR sp, sigcontext_addr, addr; int regnum; /* We find the appropriate instance of `struct sigcontext' at a fixed offset in the signal frame. */ sp = frame_unwind_register_signed (next_frame, MIPS_SP_REGNUM + gdbarch_num_regs (current_gdbarch)); sigcontext_addr = sp + 32; /* PC. */ regnum = mips_regnum (gdbarch)->pc; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (current_gdbarch), sigcontext_addr + 16); /* GPRs. */ for (regnum = MIPS_AT_REGNUM, addr = sigcontext_addr + 32; regnum <= MIPS_RA_REGNUM; regnum++, addr += 8) trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (current_gdbarch), addr); /* HI and LO. */ regnum = mips_regnum (gdbarch)->lo; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (current_gdbarch), sigcontext_addr + 280); regnum = mips_regnum (gdbarch)->hi; trad_frame_set_reg_addr (cache, regnum + gdbarch_num_regs (current_gdbarch), sigcontext_addr + 288); /* TODO: Handle the floating-point registers. */ trad_frame_set_id (cache, frame_id_build (sp, func)); }
static void arm_linux_sigtramp_cache (struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func, int regs_offset) { CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM); CORE_ADDR base = sp + regs_offset; int i; for (i = 0; i < 16; i++) trad_frame_set_reg_addr (this_cache, i, base + i * 4); trad_frame_set_reg_addr (this_cache, ARM_PS_REGNUM, base + 16 * 4); /* The VFP or iWMMXt registers may be saved on the stack, but there's no reliable way to restore them (yet). */ /* Save a frame ID. */ trad_frame_set_id (this_cache, frame_id_build (sp, func)); }
static void csky_linux_rt_sigreturn_init (const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { int i; CORE_ADDR sp = get_frame_register_unsigned (this_frame, 14); CORE_ADDR base = sp + CSKY_SIGINFO_OFFSET + CSKY_SIGINFO_SIZE + CSKY_UCONTEXT_SIGCONTEXT + CSKY_SIGCONTEXT_SC_USP + CSKY_SIGCONTEXT_SC_A0; /* Set addrs of R0 ~ R13. */ for (i = 0; i < 14; i++) trad_frame_set_reg_addr (this_cache, i, base + i * 4); /* Set addrs of SP(R14) and R15. */ trad_frame_set_reg_addr (this_cache, 14, base - 4); trad_frame_set_reg_addr (this_cache, 15, base + 4 * 14); /* Set addrs of R16 ~ R31. */ for (i = 15; i < 31; i++) trad_frame_set_reg_addr (this_cache, i, base + i * 4); /* Set addrs of PSR and PC. */ trad_frame_set_reg_addr (this_cache, 89, base + 4 * 33); trad_frame_set_reg_addr (this_cache, 72, base + 4 * 34); trad_frame_set_id (this_cache, frame_id_build (sp, func)); }
static void ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self, struct frame_info *next_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { CORE_ADDR base; CORE_ADDR offset; int i; struct gdbarch *gdbarch = get_frame_arch (next_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); base = frame_unwind_register_unsigned (next_frame, SP_REGNUM); offset = base + 0x18 + 2 * tdep->wordsize; for (i = 0; i < ppc_num_gprs; i++) { int regnum = i + tdep->ppc_gp0_regnum; trad_frame_set_reg_addr (this_cache, regnum, offset); offset += tdep->wordsize; } trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, offset); offset += tdep->wordsize; trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, offset); offset += tdep->wordsize; trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, offset); offset += tdep->wordsize; trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, offset); offset += tdep->wordsize; trad_frame_set_reg_addr (this_cache, PC_REGNUM, offset); /* SRR0? */ offset += tdep->wordsize; /* Construct the frame ID using the function start. */ trad_frame_set_id (this_cache, frame_id_build (base, func)); }
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 arm_linux_restart_syscall_init (const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM); trad_frame_set_reg_addr (this_cache, ARM_PC_REGNUM, sp); trad_frame_set_reg_value (this_cache, ARM_SP_REGNUM, sp + 12); /* Save a frame ID. */ trad_frame_set_id (this_cache, frame_id_build (sp, func)); }
static struct trad_frame_cache * amd64fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, func, pc, sp; const char *name; int i; if (*this_cache != NULL) return (*this_cache); cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func) { /* fork_exit hasn't been called (kthread has never run), so %rsp in the pcb points to the trapframe. GDB has auto-adjusted %rsp for this frame to account for the "call" into fork_trampoline, so "undo" the adjustment. */ sp += 8; } for (i = 0; i < ARRAY_SIZE (amd64fbsd_trapframe_offset); i++) if (amd64fbsd_trapframe_offset[i] != -1) trad_frame_set_reg_addr (cache, i, sp + amd64fbsd_trapframe_offset[i]); /* Read %rip from trap frame. */ addr = sp + amd64fbsd_trapframe_offset[AMD64_RIP_REGNUM]; pc = read_memory_unsigned_integer (addr, 8, byte_order); if (pc == 0 && strcmp(name, "fork_trampoline") == 0) { /* Initial frame of a kthread; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + TRAPFRAME_SIZE, func)); } return cache; }
static void armobsd_sigframe_init (const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *cache, CORE_ADDR func) { CORE_ADDR sp, sigcontext_addr, addr; int regnum; /* We find the appropriate instance of `struct sigcontext' at a fixed offset in the signal frame. */ sp = get_frame_register_signed (this_frame, ARM_SP_REGNUM); sigcontext_addr = sp + 16; /* PC. */ trad_frame_set_reg_addr (cache, ARM_PC_REGNUM, sigcontext_addr + 76); /* GPRs. */ for (regnum = ARM_A1_REGNUM, addr = sigcontext_addr + 12; regnum <= ARM_LR_REGNUM; regnum++, addr += 4) trad_frame_set_reg_addr (cache, regnum, addr); trad_frame_set_id (cache, frame_id_build (sp, func)); }
static struct trad_frame_cache * amd64obsd_trapframe_cache(struct frame_info *next_frame, void **this_cache) { struct trad_frame_cache *cache; CORE_ADDR func, sp, addr; ULONGEST cs; char *name; int i; if (*this_cache) return *this_cache; cache = trad_frame_cache_zalloc (next_frame); *this_cache = cache; /* NORMAL_FRAME matches the type in amd64obsd_trapframe_unwind, but SIGTRAMP_FRAME might be more appropriate. */ func = frame_func_unwind (next_frame, NORMAL_FRAME); sp = frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (name && strncmp (name, "Xintr", 5) == 0) addr = sp + 8; /* It's an interrupt frame. */ else addr = sp; for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++) if (amd64obsd_tf_reg_offset[i] != -1) trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]); /* Read %cs from trap frame. */ addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM]; cs = read_memory_unsigned_integer (addr, 8); if ((cs & I386_SEL_RPL) == I386_SEL_UPL) { /* Trap from user space; terminate backtrace. */ trad_frame_set_id (cache, null_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 16, func)); } return cache; }
static struct trad_frame_cache * amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR func, sp, addr; ULONGEST cs; const char *name; int i; if (*this_cache) return (struct trad_frame_cache *) *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (name && startswith (name, "Xintr")) addr = sp + 8; /* It's an interrupt frame. */ else addr = sp; for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++) if (amd64obsd_tf_reg_offset[i] != -1) trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]); /* Read %cs from trap frame. */ addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM]; cs = read_memory_unsigned_integer (addr, 8, byte_order); if ((cs & I386_SEL_RPL) == I386_SEL_UPL) { /* Trap from user space; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 16, func)); } return cache; }
static struct trad_frame_cache * ppcobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, base, func; gdb_byte buf[PPC_INSN_SIZE]; unsigned long insn, sigcontext_offset; int i; if (*this_cache) return (struct trad_frame_cache *) *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_pc (this_frame); func &= ~(ppcobsd_page_size - 1); if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf)) return cache; /* Calculate the offset where we can find `struct sigcontext'. We base our calculation on the amount of stack space reserved by the first instruction of the signal trampoline. */ insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order); sigcontext_offset = (0x10000 - (insn & 0x0000ffff)) + 8; base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); addr = base + sigcontext_offset + 2 * tdep->wordsize; for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize) { int regnum = i + tdep->ppc_gp0_regnum; trad_frame_set_reg_addr (cache, regnum, addr); } trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr); /* SRR0? */ addr += tdep->wordsize; /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (base, func)); return cache; }
static void sparc64_linux_sigframe_init (const struct tramp_frame *self, struct frame_info *this_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { CORE_ADDR base, addr, sp_addr; int regnum; base = get_frame_register_unsigned (this_frame, SPARC_O1_REGNUM); base += 128; /* Offsets from <bits/sigcontext.h>. */ /* Since %g0 is always zero, keep the identity encoding. */ addr = base + 8; sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8); for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++) { trad_frame_set_reg_addr (this_cache, regnum, addr); addr += 8; } trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0); trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8); trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16); trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24); trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28); base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM); if (base & 1) base += BIAS; addr = get_frame_memory_unsigned (this_frame, sp_addr, 8); if (addr & 1) addr += BIAS; for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++) { trad_frame_set_reg_addr (this_cache, regnum, addr); addr += 8; } trad_frame_set_id (this_cache, frame_id_build (base, func)); }
static void i386nbsd_sigtramp_cache_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); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); CORE_ADDR base; int *reg_offset; int num_regs; int i; if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2) { reg_offset = i386nbsd_sc_reg_offset; num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset); /* Read in the sigcontext address */ base = read_memory_unsigned_integer (sp + 8, 4, byte_order); } else { reg_offset = i386nbsd_mc_reg_offset; num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset); /* Read in the ucontext address */ base = read_memory_unsigned_integer (sp + 8, 4, byte_order); /* offsetof(ucontext_t, uc_mcontext) == 36 */ base += 36; } for (i = 0; i < num_regs; i++) if (reg_offset[i] != -1) trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]); /* Construct the frame ID using the function start. */ trad_frame_set_id (this_cache, frame_id_build (sp, func)); }
static void nios2_linux_sigreturn_init (const struct tramp_frame *self, struct frame_info *next_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { CORE_ADDR base = func + 16; int i; for (i = 0; i < 8; i++) trad_frame_set_reg_addr (this_cache, i + 8, base + i * 4); for (i = 0; i < 7; i++) trad_frame_set_reg_addr (this_cache, i + 1, base + (i + 8) * 4); trad_frame_set_reg_addr (this_cache, NIOS2_RA_REGNUM, base + 16 * 4); trad_frame_set_reg_addr (this_cache, NIOS2_FP_REGNUM, base + 17 * 4); trad_frame_set_reg_addr (this_cache, NIOS2_SP_REGNUM, base + 18 * 4); trad_frame_set_reg_addr (this_cache, NIOS2_GP_REGNUM, base + 19 * 4); trad_frame_set_reg_addr (this_cache, NIOS2_ESTATUS_REGNUM, base + 20 * 4); trad_frame_set_reg_addr (this_cache, NIOS2_PC_REGNUM, base + 21 * 4); /* Save a frame ID. */ trad_frame_set_id (this_cache, frame_id_build (base, func)); }
static struct trad_frame_cache * frv_linux_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr; gdb_byte buf[4]; int regnum; CORE_ADDR sc_addr_cache_val = 0; struct frame_id this_id; if (*this_cache) return (struct trad_frame_cache *) *this_cache; cache = trad_frame_cache_zalloc (this_frame); /* FIXME: cagney/2004-05-01: This is is long standing broken code. The frame ID's code address should be the start-address of the signal trampoline and not the current PC within that trampoline. */ get_frame_register (this_frame, sp_regnum, buf); addr = extract_unsigned_integer (buf, sizeof buf, byte_order); this_id = frame_id_build (addr, get_frame_pc (this_frame)); trad_frame_set_id (cache, this_id); for (regnum = 0; regnum < frv_num_regs; regnum++) { LONGEST reg_addr = frv_linux_sigcontext_reg_addr (this_frame, regnum, &sc_addr_cache_val); if (reg_addr != -1) trad_frame_set_reg_addr (cache, regnum, reg_addr); } *this_cache = cache; return cache; }
static struct trad_frame_cache * ppcfbsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct trad_frame_cache *cache; CORE_ADDR addr, base, func; gdb_byte buf[PPC_INSN_SIZE]; int i; if (*this_cache) return *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_pc (this_frame); func &= ~(ppcfbsd_page_size - 1); if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf)) return cache; base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); addr = base + 0x10 + 2 * tdep->wordsize; for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize) { int regnum = i + tdep->ppc_gp0_regnum; trad_frame_set_reg_addr (cache, regnum, addr); } trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr); addr += tdep->wordsize; trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr); /* SRR0? */ addr += tdep->wordsize; /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (base, func)); return cache; }