static int mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno) { return (regno == MIPS_ZERO_REGNUM || regno == mips_regnum (gdbarch)->fp_implementation_revision); }
static bool getregs_supplies (struct gdbarch *gdbarch, int regnum) { return (regnum >= MIPS_ZERO_REGNUM && regnum <= mips_regnum (gdbarch)->pc); }
static bool getfpregs_supplies (struct gdbarch *gdbarch, int regnum) { return (regnum >= mips_regnum (gdbarch)->fp0 && regnum <= mips_regnum (gdbarch)->fp_implementation_revision); }
static void mips_linux_o32_sigframe_init (const struct tramp_frame *self, struct frame_info *next_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { int ireg, reg_position; CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET; const struct mips_regnum *regs = mips_regnum (current_gdbarch); CORE_ADDR regs_base; if (self == &mips_linux_o32_sigframe) sigcontext_base += SIGFRAME_SIGCONTEXT_OFFSET; else sigcontext_base += 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 (current_gdbarch) == BFD_ENDIAN_BIG) regs_base = sigcontext_base + 4; else regs_base = sigcontext_base; if (mips_linux_restart_reg_p (current_gdbarch)) trad_frame_set_reg_addr (this_cache, (MIPS_RESTART_REGNUM + gdbarch_num_regs (current_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 (current_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 (current_gdbarch) == BFD_ENDIAN_BIG) != (ireg & 1)) trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + gdbarch_num_regs (current_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 (current_gdbarch), sigcontext_base + SIGCONTEXT_FPREGS + (ireg & ~1) * SIGCONTEXT_REG_SIZE); trad_frame_set_reg_addr (this_cache, regs->pc + gdbarch_num_regs (current_gdbarch), regs_base + SIGCONTEXT_PC); trad_frame_set_reg_addr (this_cache, regs->fp_control_status + gdbarch_num_regs (current_gdbarch), sigcontext_base + SIGCONTEXT_FPCSR); trad_frame_set_reg_addr (this_cache, regs->hi + gdbarch_num_regs (current_gdbarch), regs_base + SIGCONTEXT_HI); trad_frame_set_reg_addr (this_cache, regs->lo + gdbarch_num_regs (current_gdbarch), regs_base + SIGCONTEXT_LO); trad_frame_set_reg_addr (this_cache, regs->cause + gdbarch_num_regs (current_gdbarch), sigcontext_base + SIGCONTEXT_CAUSE); trad_frame_set_reg_addr (this_cache, regs->badvaddr + gdbarch_num_regs (current_gdbarch), sigcontext_base + SIGCONTEXT_BADVADDR); /* Choice of the bottom of the sigframe is somewhat arbitrary. */ trad_frame_set_id (this_cache, frame_id_build (func - SIGFRAME_CODE_OFFSET, func)); }
void mips64_fill_fpregset (const struct regcache *regcache, mips64_elf_fpregset_t *fpregsetp, int regno) { gdb_byte *to; if ((regno >= gdbarch_fp0_regnum (current_gdbarch)) && (regno < gdbarch_fp0_regnum (current_gdbarch) + 32)) { /* See mips_linux_o32_sigframe_init for a description of the peculiar FP register layout. */ if (register_size (current_gdbarch, regno) == 4) { int regi = regno - gdbarch_fp0_regnum (current_gdbarch); to = (gdb_byte *) (*fpregsetp + (regi & ~1)); if ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) != (regi & 1)) to += 4; regcache_raw_collect (regcache, regno, to); } else { to = (gdb_byte *) (*fpregsetp + regno - gdbarch_fp0_regnum (current_gdbarch)); regcache_raw_collect (regcache, regno, to); } } else if (regno == mips_regnum (current_gdbarch)->fp_control_status) { gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regno, buf); val = extract_signed_integer (buf, register_size (current_gdbarch, regno)); to = (gdb_byte *) (*fpregsetp + 32); store_signed_integer (to, 4, val); } else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision) { gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regno, buf); val = extract_signed_integer (buf, register_size (current_gdbarch, regno)); to = (gdb_byte *) (*fpregsetp + 32) + 4; store_signed_integer (to, 4, val); } else if (regno == -1) { int regi; for (regi = 0; regi < 32; regi++) mips64_fill_fpregset (regcache, fpregsetp, gdbarch_fp0_regnum (current_gdbarch) + regi); mips64_fill_fpregset (regcache, fpregsetp, mips_regnum (current_gdbarch)->fp_control_status); mips64_fill_fpregset (regcache, fpregsetp, (mips_regnum (current_gdbarch) ->fp_implementation_revision)); } }
static void mips_linux_n32n64_sigframe_init (const struct tramp_frame *self, struct frame_info *next_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { int ireg, reg_position; CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET; const struct mips_regnum *regs = mips_regnum (current_gdbarch); if (self == &mips_linux_n32_rt_sigframe) sigcontext_base += N32_SIGFRAME_SIGCONTEXT_OFFSET; else sigcontext_base += N64_SIGFRAME_SIGCONTEXT_OFFSET; if (mips_linux_restart_reg_p (current_gdbarch)) trad_frame_set_reg_addr (this_cache, (MIPS_RESTART_REGNUM + gdbarch_num_regs (current_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 (current_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 (current_gdbarch), sigcontext_base + N64_SIGCONTEXT_FPREGS + ireg * N64_SIGCONTEXT_REG_SIZE); trad_frame_set_reg_addr (this_cache, regs->pc + gdbarch_num_regs (current_gdbarch), sigcontext_base + N64_SIGCONTEXT_PC); trad_frame_set_reg_addr (this_cache, regs->fp_control_status + gdbarch_num_regs (current_gdbarch), sigcontext_base + N64_SIGCONTEXT_FPCSR); trad_frame_set_reg_addr (this_cache, regs->hi + gdbarch_num_regs (current_gdbarch), sigcontext_base + N64_SIGCONTEXT_HI); trad_frame_set_reg_addr (this_cache, regs->lo + gdbarch_num_regs (current_gdbarch), sigcontext_base + N64_SIGCONTEXT_LO); trad_frame_set_reg_addr (this_cache, regs->cause + gdbarch_num_regs (current_gdbarch), sigcontext_base + N64_SIGCONTEXT_CAUSE); trad_frame_set_reg_addr (this_cache, regs->badvaddr + gdbarch_num_regs (current_gdbarch), sigcontext_base + N64_SIGCONTEXT_BADVADDR); /* Choice of the bottom of the sigframe is somewhat arbitrary. */ trad_frame_set_id (this_cache, frame_id_build (func - SIGFRAME_CODE_OFFSET, 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; 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); if (regs->dspacc != -1) { trad_frame_set_reg_addr (this_cache, regs->dspacc + 0 + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_HI1); trad_frame_set_reg_addr (this_cache, regs->dspacc + 1 + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_LO1); trad_frame_set_reg_addr (this_cache, regs->dspacc + 2 + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_HI2); trad_frame_set_reg_addr (this_cache, regs->dspacc + 3 + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_LO2); trad_frame_set_reg_addr (this_cache, regs->dspacc + 4 + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_HI3); trad_frame_set_reg_addr (this_cache, regs->dspacc + 5 + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_LO3); } if (regs->dspctl != -1) trad_frame_set_reg_addr (this_cache, regs->dspctl + gdbarch_num_regs (gdbarch), sigcontext_base + N64_SIGCONTEXT_DSPCTL); /* Choice of the bottom of the sigframe is somewhat arbitrary. */ trad_frame_set_id (this_cache, frame_id_build (frame_sp, func)); }
static struct trad_frame_cache * mips_sde_frame_cache (struct frame_info *this_frame, void **this_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); const struct mips_regnum *regs = mips_regnum (gdbarch); const int sizeof_reg_t = mips_abi_regsize (gdbarch); enum mips_abi abi = mips_abi (gdbarch); struct trad_frame_cache *cache; CORE_ADDR xcpt_frame; CORE_ADDR start_addr; CORE_ADDR stack_addr; CORE_ADDR pc; int i; if (*this_cache != NULL) return (struct trad_frame_cache *) *this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; /* The previous registers are held in struct xcptcontext which is at $sp+offs struct xcptcontext { reg_t sr; CP0 Status reg_t cr; CP0 Cause reg_t epc; CP0 EPC reg_t vaddr; CP0 BadVAddr reg_t regs[32]; General registers reg_t mdlo; LO reg_t mdhi; HI reg_t mdex; ACX ... }; */ stack_addr = get_frame_register_signed (this_frame, gdbarch_sp_regnum (gdbarch)); switch (abi) { case MIPS_ABI_O32: /* 40: XCPTCONTEXT 24: xcpt_gen() argspace (16 bytes) 16: _xcptcall() saved ra, rounded up ( 8 bytes) 00: _xcptcall() argspace (16 bytes) */ xcpt_frame = stack_addr + 40; break; case MIPS_ABI_N32: case MIPS_ABI_N64: default: /* Wild guess. */ /* 16: XCPTCONTEXT 16: xcpt_gen() argspace ( 0 bytes) 00: _xcptcall() saved ra, rounded up (16 bytes) */ xcpt_frame = stack_addr + 16; break; } trad_frame_set_reg_addr (cache, MIPS_PS_REGNUM + gdbarch_num_regs (gdbarch), xcpt_frame + 0 * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->cause + gdbarch_num_regs (gdbarch), xcpt_frame + 1 * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->pc + gdbarch_num_regs (gdbarch), xcpt_frame + 2 * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->badvaddr + gdbarch_num_regs (gdbarch), xcpt_frame + 3 * sizeof_reg_t); for (i = 0; i < MIPS_NUMREGS; i++) trad_frame_set_reg_addr (cache, i + MIPS_ZERO_REGNUM + gdbarch_num_regs (gdbarch), xcpt_frame + (4 + i) * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->lo + gdbarch_num_regs (gdbarch), xcpt_frame + 36 * sizeof_reg_t); trad_frame_set_reg_addr (cache, regs->hi + gdbarch_num_regs (gdbarch), xcpt_frame + 37 * sizeof_reg_t); pc = get_frame_pc (this_frame); find_pc_partial_function (pc, NULL, &start_addr, NULL); trad_frame_set_id (cache, frame_id_build (start_addr, stack_addr)); return cache; }