static CORE_ADDR lm32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { CORE_ADDR func_addr, limit_pc; struct symtab_and_line sal; struct lm32_frame_cache frame_info; struct trad_frame_saved_reg saved_regs[SIM_LM32_NUM_REGS]; /* See if we can determine the end of the prologue via the symbol table. If so, then return either PC, or the PC after the prologue, whichever is greater. */ if (find_pc_partial_function (pc, NULL, &func_addr, NULL)) { CORE_ADDR post_prologue_pc = skip_prologue_using_sal (gdbarch, func_addr); if (post_prologue_pc != 0) return max (pc, post_prologue_pc); } /* Can't determine prologue from the symbol table, need to examine instructions. */ /* Find an upper limit on the function prologue using the debug information. If the debug information could not be used to provide that bound, then use an arbitrary large number as the upper bound. */ limit_pc = skip_prologue_using_sal (gdbarch, pc); if (limit_pc == 0) limit_pc = pc + 100; /* Magic. */ frame_info.saved_regs = saved_regs; return lm32_analyze_prologue (gdbarch, pc, limit_pc, &frame_info); }
static struct lm32_frame_cache * lm32_frame_cache (struct frame_info *this_frame, void **this_prologue_cache) { CORE_ADDR prologue_pc; CORE_ADDR current_pc; ULONGEST prev_sp; ULONGEST this_base; struct lm32_frame_cache *info; int prefixed; unsigned long instruction; int op; int offsets[32]; int i; long immediate; if ((*this_prologue_cache)) return (*this_prologue_cache); info = FRAME_OBSTACK_ZALLOC (struct lm32_frame_cache); (*this_prologue_cache) = info; info->saved_regs = trad_frame_alloc_saved_regs (this_frame); info->pc = get_frame_func (this_frame); current_pc = get_frame_pc (this_frame); lm32_analyze_prologue (get_frame_arch (this_frame), info->pc, current_pc, info); /* Compute the frame's base, and the previous frame's SP. */ this_base = get_frame_register_unsigned (this_frame, SIM_LM32_SP_REGNUM); prev_sp = this_base + info->size; info->base = this_base; /* Convert callee save offsets into addresses. */ for (i = 0; i < gdbarch_num_regs (get_frame_arch (this_frame)) - 1; i++) { if (trad_frame_addr_p (info->saved_regs, i)) info->saved_regs[i].addr = this_base + info->saved_regs[i].addr; } /* The call instruction moves the caller's PC in the callee's RA register. Since this is an unwind, do the reverse. Copy the location of RA register into PC (the address / regnum) so that a request for PC will be converted into a request for the RA register. */ info->saved_regs[SIM_LM32_PC_REGNUM] = info->saved_regs[SIM_LM32_RA_REGNUM]; /* The previous frame's SP needed to be computed. Save the computed value. */ trad_frame_set_value (info->saved_regs, SIM_LM32_SP_REGNUM, prev_sp); return info; }