コード例 #1
0
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);
}
コード例 #2
0
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;
}