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 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 arm_linux_restart_syscall_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, ARM_SP_REGNUM); CORE_ADDR pc = get_frame_memory_unsigned (this_frame, sp, 4); CORE_ADDR cpsr = get_frame_register_unsigned (this_frame, ARM_PS_REGNUM); ULONGEST t_bit = arm_psr_thumb_bit (gdbarch); int sp_offset; /* There are two variants of this trampoline; with older kernels, the stub is placed on the stack, while newer kernels use the stub from the vector page. They are identical except that the older version increments SP by 12 (to skip stored PC and the stub itself), while the newer version increments SP only by 4 (just the stored PC). */ if (self->insn[1].bytes == ARM_LDR_PC_SP_4) sp_offset = 4; else sp_offset = 12; /* Update Thumb bit in CPSR. */ if (pc & 1) cpsr |= t_bit; else cpsr &= ~t_bit; /* Remove Thumb bit from PC. */ pc = gdbarch_addr_bits_remove (gdbarch, pc); /* Save previous register values. */ trad_frame_set_reg_value (this_cache, ARM_SP_REGNUM, sp + sp_offset); trad_frame_set_reg_value (this_cache, ARM_PC_REGNUM, pc); trad_frame_set_reg_value (this_cache, ARM_PS_REGNUM, cpsr); /* Save a frame ID. */ trad_frame_set_id (this_cache, frame_id_build (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 void set_movm_offsets (struct frame_info *fi, void **this_cache, int movm_args) { struct trad_frame_cache *cache; int offset = 0; CORE_ADDR base; if (fi == NULL || this_cache == NULL) return; cache = mn10300_frame_unwind_cache (fi, this_cache); if (cache == NULL) return; base = trad_frame_get_this_base (cache); if (movm_args & movm_other_bit) { /* The `other' bit leaves a blank area of four bytes at the beginning of its block of saved registers, making it 32 bytes long in total. */ trad_frame_set_reg_addr (cache, E_LAR_REGNUM, base + offset + 4); trad_frame_set_reg_addr (cache, E_LIR_REGNUM, base + offset + 8); trad_frame_set_reg_addr (cache, E_MDR_REGNUM, base + offset + 12); trad_frame_set_reg_addr (cache, E_A0_REGNUM + 1, base + offset + 16); trad_frame_set_reg_addr (cache, E_A0_REGNUM, base + offset + 20); trad_frame_set_reg_addr (cache, E_D0_REGNUM + 1, base + offset + 24); trad_frame_set_reg_addr (cache, E_D0_REGNUM, base + offset + 28); offset += 32; } if (movm_args & movm_a3_bit) { trad_frame_set_reg_addr (cache, E_A3_REGNUM, base + offset); offset += 4; } if (movm_args & movm_a2_bit) { trad_frame_set_reg_addr (cache, E_A2_REGNUM, base + offset); offset += 4; } if (movm_args & movm_d3_bit) { trad_frame_set_reg_addr (cache, E_D3_REGNUM, base + offset); offset += 4; } if (movm_args & movm_d2_bit) { trad_frame_set_reg_addr (cache, E_D2_REGNUM, base + offset); offset += 4; } if (AM33_MODE) { if (movm_args & movm_exother_bit) { trad_frame_set_reg_addr (cache, E_MCVF_REGNUM, base + offset); trad_frame_set_reg_addr (cache, E_MCRL_REGNUM, base + offset + 4); trad_frame_set_reg_addr (cache, E_MCRH_REGNUM, base + offset + 8); trad_frame_set_reg_addr (cache, E_MDRQ_REGNUM, base + offset + 12); trad_frame_set_reg_addr (cache, E_E1_REGNUM, base + offset + 16); trad_frame_set_reg_addr (cache, E_E0_REGNUM, base + offset + 20); offset += 24; } if (movm_args & movm_exreg1_bit) { trad_frame_set_reg_addr (cache, E_E7_REGNUM, base + offset); trad_frame_set_reg_addr (cache, E_E6_REGNUM, base + offset + 4); trad_frame_set_reg_addr (cache, E_E5_REGNUM, base + offset + 8); trad_frame_set_reg_addr (cache, E_E4_REGNUM, base + offset + 12); offset += 16; } if (movm_args & movm_exreg0_bit) { trad_frame_set_reg_addr (cache, E_E3_REGNUM, base + offset); trad_frame_set_reg_addr (cache, E_E2_REGNUM, base + offset + 4); offset += 8; } } /* The last (or first) thing on the stack will be the PC. */ trad_frame_set_reg_addr (cache, E_PC_REGNUM, base + offset); /* Save the SP in the 'traditional' way. This will be the same location where the PC is saved. */ trad_frame_set_reg_value (cache, E_SP_REGNUM, base + offset); }
static void set_reg_offsets (struct frame_info *fi, void **this_cache, int movm_args, int fpregmask, int stack_extra_size, int frame_in_fp) { struct trad_frame_cache *cache; int offset = 0; CORE_ADDR base; if (fi == NULL || this_cache == NULL) return; cache = mn10300_frame_unwind_cache (fi, this_cache); if (cache == NULL) return; if (frame_in_fp) { base = frame_unwind_register_unsigned (fi, E_A3_REGNUM); } else { base = frame_unwind_register_unsigned (fi, E_SP_REGNUM) + stack_extra_size; } trad_frame_set_this_base (cache, base); if (AM33_MODE == 2) { /* If bit N is set in fpregmask, fsN is saved on the stack. The floating point registers are saved in ascending order. For example: fs16 <- Frame Pointer fs17 Frame Pointer + 4 */ if (fpregmask != 0) { int i; for (i = 0; i < 32; i++) { if (fpregmask & (1 << i)) { trad_frame_set_reg_addr (cache, E_FS0_REGNUM + i, base + offset); offset += 4; } } } } if (movm_args & movm_other_bit) { /* The `other' bit leaves a blank area of four bytes at the beginning of its block of saved registers, making it 32 bytes long in total. */ trad_frame_set_reg_addr (cache, E_LAR_REGNUM, base + offset + 4); trad_frame_set_reg_addr (cache, E_LIR_REGNUM, base + offset + 8); trad_frame_set_reg_addr (cache, E_MDR_REGNUM, base + offset + 12); trad_frame_set_reg_addr (cache, E_A0_REGNUM + 1, base + offset + 16); trad_frame_set_reg_addr (cache, E_A0_REGNUM, base + offset + 20); trad_frame_set_reg_addr (cache, E_D0_REGNUM + 1, base + offset + 24); trad_frame_set_reg_addr (cache, E_D0_REGNUM, base + offset + 28); offset += 32; } if (movm_args & movm_a3_bit) { trad_frame_set_reg_addr (cache, E_A3_REGNUM, base + offset); offset += 4; } if (movm_args & movm_a2_bit) { trad_frame_set_reg_addr (cache, E_A2_REGNUM, base + offset); offset += 4; } if (movm_args & movm_d3_bit) { trad_frame_set_reg_addr (cache, E_D3_REGNUM, base + offset); offset += 4; } if (movm_args & movm_d2_bit) { trad_frame_set_reg_addr (cache, E_D2_REGNUM, base + offset); offset += 4; } if (AM33_MODE) { if (movm_args & movm_exother_bit) { trad_frame_set_reg_addr (cache, E_MCVF_REGNUM, base + offset); trad_frame_set_reg_addr (cache, E_MCRL_REGNUM, base + offset + 4); trad_frame_set_reg_addr (cache, E_MCRH_REGNUM, base + offset + 8); trad_frame_set_reg_addr (cache, E_MDRQ_REGNUM, base + offset + 12); trad_frame_set_reg_addr (cache, E_E1_REGNUM, base + offset + 16); trad_frame_set_reg_addr (cache, E_E0_REGNUM, base + offset + 20); offset += 24; } if (movm_args & movm_exreg1_bit) { trad_frame_set_reg_addr (cache, E_E7_REGNUM, base + offset); trad_frame_set_reg_addr (cache, E_E6_REGNUM, base + offset + 4); trad_frame_set_reg_addr (cache, E_E5_REGNUM, base + offset + 8); trad_frame_set_reg_addr (cache, E_E4_REGNUM, base + offset + 12); offset += 16; } if (movm_args & movm_exreg0_bit) { trad_frame_set_reg_addr (cache, E_E3_REGNUM, base + offset); trad_frame_set_reg_addr (cache, E_E2_REGNUM, base + offset + 4); offset += 8; } } /* The last (or first) thing on the stack will be the PC. */ trad_frame_set_reg_addr (cache, E_PC_REGNUM, base + offset); /* Save the SP in the 'traditional' way. This will be the same location where the PC is saved. */ trad_frame_set_reg_value (cache, E_SP_REGNUM, base + offset); }