Ejemplo n.º 1
0
CORE_ADDR
microblaze_frame_saved_pc (struct frame_info * fi)
{

  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
    return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
  else
    return microblaze_find_callers_reg (fi, PR_REGNUM);
  /*    return microblaze_find_callers_reg (fi, PC_REGNUM); */
}
Ejemplo n.º 2
0
int
generic_file_frame_chain_valid (CORE_ADDR fp, struct frame_info *fi)
{
  if (PC_IN_CALL_DUMMY (FRAME_SAVED_PC (fi), fp, fp))
    return 1;			/* don't prune CALL_DUMMY frames */
  else				/* fall back to default algorithm (see frame.h) */
    return (fp != 0
	    && (INNER_THAN (fi->frame, fp) || fi->frame == fp)
	    && !inside_entry_file (FRAME_SAVED_PC (fi)));
}
Ejemplo n.º 3
0
void
generic_pop_current_frame (void (*popper) (struct frame_info * frame))
{
  struct frame_info *frame = get_current_frame ();

  if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
    generic_pop_dummy_frame ();
  else
    (*popper) (frame);
}
Ejemplo n.º 4
0
void
microblaze_pop_frame (struct frame_info *fi)
{
  int rn;
  CORE_ADDR func_addr, func_end, addr;
  enum microblaze_instr op;
  int insn, rd, ra, rb, imm;
  int status;
  char *name;
  int offset = 0;	/* offset that the return instruction specifies */

  /* Find the start and end of this function. */
  /* siva/9/19/05: pop frame was not computing this offset. copied code from
     microblaze_fix_call_dummy to find the return insn & the offset */
  status = find_pc_partial_function (fi->pc, &name, &func_addr, &func_end);

  for (addr = func_addr; addr < func_end; addr += INST_WORD_SIZE) {
	  /* Start decoding the function looking for rtsd */
	  insn = get_insn (addr);
	  op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);

	  /* Check for return. */
	  if (IS_RETURN(op)) {
		  offset = imm;
		  break; 
	  }
  }

  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
    generic_pop_dummy_frame ();
  else
    {
      /* Write out the PC we saved. */
      write_register (PC_REGNUM, FRAME_SAVED_PC (fi) + offset);

      /* Restore any saved registers. */
      for (rn = 0; rn < NUM_REGS; rn++)
	{
	  if (fi->saved_regs[rn] != 0)
	    {
	      ULONGEST value;

	      value = read_memory_unsigned_integer (fi->saved_regs[rn],
						    REGISTER_SIZE);
	      write_register (rn, value);
	    }
	}

      /* Actually cut back the stack. */
      write_register (SP_REGNUM, FRAME_FP (fi));
    }

  /* Finally, throw away any cached frame information. */
  flush_cached_frames ();
}
Ejemplo n.º 5
0
CORE_ADDR
microblaze_find_callers_reg (struct frame_info *fi, int regnum)
{
  LONGEST ret;
  for (; fi != NULL; fi = fi->next)
    {
      if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
	return generic_read_register_dummy (fi->pc, fi->frame, regnum);
      else if (fi->saved_regs[regnum] != 0) 
	return microblaze_read_memory_integer (fi->saved_regs[regnum]);
    }

  return read_register (regnum);
}
Ejemplo n.º 6
0
int
inside_entry_file (CORE_ADDR addr)
{
  if (addr == 0)
    return 1;
  if (symfile_objfile == 0)
    return 0;
  if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
    {
      /* Do not stop backtracing if the pc is in the call dummy
         at the entry point.  */
      /* FIXME: Won't always work with zeros for the last two arguments */
      if (PC_IN_CALL_DUMMY (addr, 0, 0))
	return 0;
    }
  return (addr >= symfile_objfile->ei.entry_file_lowpc &&
	  addr < symfile_objfile->ei.entry_file_highpc);
}
Ejemplo n.º 7
0
void
microblaze_init_extra_frame_info (struct frame_info *fi)
{
  if (fi->next)
    fi->pc = FRAME_SAVED_PC (fi->next);

  frame_saved_regs_zalloc (fi);

  fi->extra_info = (struct frame_extra_info *)
    frame_obstack_alloc (sizeof (struct frame_extra_info));
  fi->extra_info->status = 0;
  fi->extra_info->framesize = 0;

  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
    {
      /* We need to setup fi->frame here because run_stack_dummy gets it wrong
         by assuming it's always FP.  */
      fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
    }
  else
    microblaze_analyze_prologue (fi, 0);
}
Ejemplo n.º 8
0
void
generic_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
			    struct frame_info *frame, int regnum,
			    enum lval_type *lval)
{
  if (!target_has_registers)
    error ("No registers.");

  /* Normal systems don't optimize out things with register numbers.  */
  if (optimized != NULL)
    *optimized = 0;

  if (addrp)			/* default assumption: not found in memory */
    *addrp = 0;

  /* Note: since the current frame's registers could only have been
     saved by frames INTERIOR TO the current frame, we skip examining
     the current frame itself: otherwise, we would be getting the
     previous frame's registers which were saved by the current frame.  */

  while (frame && ((frame = frame->next) != NULL))
    {
      if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
	{
	  if (lval)		/* found it in a CALL_DUMMY frame */
	    *lval = not_lval;
	  if (raw_buffer)
	    memcpy (raw_buffer,
		    generic_find_dummy_frame (frame->pc, frame->frame) +
		    REGISTER_BYTE (regnum),
		    REGISTER_RAW_SIZE (regnum));
	  return;
	}

      FRAME_INIT_SAVED_REGS (frame);
      if (frame->saved_regs != NULL
	  && frame->saved_regs[regnum] != 0)
	{
	  if (lval)		/* found it saved on the stack */
	    *lval = lval_memory;
	  if (regnum == SP_REGNUM)
	    {
	      if (raw_buffer)	/* SP register treated specially */
		store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
			       frame->saved_regs[regnum]);
	    }
	  else
	    {
	      if (addrp)	/* any other register */
		*addrp = frame->saved_regs[regnum];
	      if (raw_buffer)
		read_memory (frame->saved_regs[regnum], raw_buffer,
			     REGISTER_RAW_SIZE (regnum));
	    }
	  return;
	}
    }

  /* If we get thru the loop to this point, it means the register was
     not saved in any frame.  Return the actual live-register value.  */

  if (lval)			/* found it in a live register */
    *lval = lval_register;
  if (addrp)
    *addrp = REGISTER_BYTE (regnum);
  if (raw_buffer)
    read_register_gen (regnum, raw_buffer);
}