Ejemplo n.º 1
0
CORE_ADDR
h8500_frame_chain (struct frame_info *thisframe)
{
  if (!inside_entry_file (thisframe->pc))
    return (read_memory_integer (FRAME_FP (thisframe), PTR_SIZE));
  else
    return 0;
}
Ejemplo n.º 2
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.º 3
0
static void
metrowerks_step (CORE_ADDR range_start, CORE_ADDR range_stop, int step_into)
{
  struct frame_info *frame = NULL;
  CORE_ADDR pc = 0;

  /* When single stepping in assembly, the plugin passes (start + 1)
     as the stop address. Round the stop address up to the next valid
     instruction */

  if ((range_stop & ~0x3) != range_stop)
      range_stop = ((range_stop + 4) & ~0x3);

  pc = read_pc();

  if (range_start >= range_stop)
    error ("invalid step range (the stop address must be greater than the start address)");

  if (pc < range_start)
    error ("invalid step range ($pc is 0x%lx, less than the stop address of 0x%lx)",
	   (unsigned long) pc, (unsigned long) range_start);
  if (pc == range_stop)
    error ("invalid step range ($pc is 0x%lx, equal to the stop address of 0x%lx)",
	   (unsigned long) pc, (unsigned long) range_stop);
  if (pc > range_stop)
    error ("invalid step range ($pc is 0x%lx, greater than the stop address of 0x%lx)",
	   (unsigned long) pc, (unsigned long) range_stop);

  clear_proceed_status ();

  frame = get_current_frame ();
  if (frame == NULL)
    error ("No current frame");
  step_frame_address = FRAME_FP (frame);
  step_sp = read_sp ();

  step_range_start = range_start;
  step_range_end = range_stop;
  step_over_calls = step_into ? STEP_OVER_NONE : STEP_OVER_ALL;

  step_multi = 0;

  metrowerks_stepping = 1;
  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 1);
  make_exec_cleanup (metrowerks_stepping_cleanup, NULL);
}
Ejemplo n.º 4
0
struct frame_info *
find_frame_addr_in_frame_chain (CORE_ADDR frame_addr)
{
  struct frame_info *frame = NULL;

  if (frame_addr == (CORE_ADDR) 0)
    return NULL;

  while (1)
    {
      frame = get_prev_frame (frame);
      if (frame == NULL)
	return NULL;
      if (FRAME_FP (frame) == frame_addr)
	return frame;
    }
}
Ejemplo n.º 5
0
/* generic_pop_current_frame calls this function if the current
   frame isn't a dummy frame.  */
static void
mn10300_pop_frame_regular (struct frame_info *frame)
{
  int regnum;

  write_register (PC_REGNUM, FRAME_SAVED_PC (frame));

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

        value = read_memory_unsigned_integer (frame->saved_regs[regnum],
                                              REGISTER_RAW_SIZE (regnum));
        write_register (regnum, value);
      }

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

  /* Don't we need to set the PC?!?  XXX FIXME.  */
}
Ejemplo n.º 6
0
CORE_ADDR
frame_saved_pc (struct frame_info *frame)
{
  return read_memory_integer (FRAME_FP (frame) + 2, PTR_SIZE);
}
Ejemplo n.º 7
0
struct frame_info *
get_prev_frame (struct frame_info *next_frame)
{
  CORE_ADDR address = 0;
  struct frame_info *prev;
  int fromleaf = 0;
  char *name;

  /* If the requested entry is in the cache, return it.
     Otherwise, figure out what the address should be for the entry
     we're about to add to the cache. */

  if (!next_frame)
    {
#if 0
      /* This screws value_of_variable, which just wants a nice clean
         NULL return from block_innermost_frame if there are no frames.
         I don't think I've ever seen this message happen otherwise.
         And returning NULL here is a perfectly legitimate thing to do.  */
      if (!current_frame)
	{
	  error ("You haven't set up a process's stack to examine.");
	}
#endif

      return current_frame;
    }

  /* If we have the prev one, return it */
  if (next_frame->prev)
    return next_frame->prev;

  /* On some machines it is possible to call a function without
     setting up a stack frame for it.  On these machines, we
     define this macro to take two args; a frameinfo pointer
     identifying a frame and a variable to set or clear if it is
     or isn't leafless.  */

  /* Still don't want to worry about this except on the innermost
     frame.  This macro will set FROMLEAF if NEXT_FRAME is a
     frameless function invocation.  */
  if (!(next_frame->next))
    {
      fromleaf = FRAMELESS_FUNCTION_INVOCATION (next_frame);
      if (fromleaf)
	address = FRAME_FP (next_frame);
    }

  if (!fromleaf)
    {
      /* Two macros defined in tm.h specify the machine-dependent
         actions to be performed here.
         First, get the frame's chain-pointer.
         If that is zero, the frame is the outermost frame or a leaf
         called by the outermost frame.  This means that if start
         calls main without a frame, we'll return 0 (which is fine
         anyway).

         Nope; there's a problem.  This also returns when the current
         routine is a leaf of main.  This is unacceptable.  We move
         this to after the ffi test; I'd rather have backtraces from
         start go curfluy than have an abort called from main not show
         main.  */
      address = FRAME_CHAIN (next_frame);
      if (!FRAME_CHAIN_VALID (address, next_frame))
	return 0;
      address = FRAME_CHAIN_COMBINE (address, next_frame);
    }
  if (address == 0)
    return 0;

  prev = (struct frame_info *)
    obstack_alloc (&frame_cache_obstack,
		   sizeof (struct frame_info));

  /* Zero all fields by default.  */
  memset (prev, 0, sizeof (struct frame_info));

  if (next_frame)
    next_frame->prev = prev;
  prev->next = next_frame;
  prev->frame = address;

/* This change should not be needed, FIXME!  We should
   determine whether any targets *need* INIT_FRAME_PC to happen
   after INIT_EXTRA_FRAME_INFO and come up with a simple way to
   express what goes on here.

   INIT_EXTRA_FRAME_INFO is called from two places: create_new_frame
   (where the PC is already set up) and here (where it isn't).
   INIT_FRAME_PC is only called from here, always after
   INIT_EXTRA_FRAME_INFO.

   The catch is the MIPS, where INIT_EXTRA_FRAME_INFO requires the PC
   value (which hasn't been set yet).  Some other machines appear to
   require INIT_EXTRA_FRAME_INFO before they can do INIT_FRAME_PC.  Phoo.

   We shouldn't need INIT_FRAME_PC_FIRST to add more complication to
   an already overcomplicated part of GDB.   [email protected], 15Sep92.

   Assuming that some machines need INIT_FRAME_PC after
   INIT_EXTRA_FRAME_INFO, one possible scheme:

   SETUP_INNERMOST_FRAME()
   Default version is just create_new_frame (read_fp ()),
   read_pc ()).  Machines with extra frame info would do that (or the
   local equivalent) and then set the extra fields.
   SETUP_ARBITRARY_FRAME(argc, argv)
   Only change here is that create_new_frame would no longer init extra
   frame info; SETUP_ARBITRARY_FRAME would have to do that.
   INIT_PREV_FRAME(fromleaf, prev)
   Replace INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC.  This should
   also return a flag saying whether to keep the new frame, or
   whether to discard it, because on some machines (e.g.  mips) it
   is really awkward to have FRAME_CHAIN_VALID called *before*
   INIT_EXTRA_FRAME_INFO (there is no good way to get information
   deduced in FRAME_CHAIN_VALID into the extra fields of the new frame).
   std_frame_pc(fromleaf, prev)
   This is the default setting for INIT_PREV_FRAME.  It just does what
   the default INIT_FRAME_PC does.  Some machines will call it from
   INIT_PREV_FRAME (either at the beginning, the end, or in the middle).
   Some machines won't use it.
   [email protected], 13Apr93, 31Jan94, 14Dec94.  */

  INIT_FRAME_PC_FIRST (fromleaf, prev);

#ifdef INIT_EXTRA_FRAME_INFO
  INIT_EXTRA_FRAME_INFO (fromleaf, prev);
#endif

  /* This entry is in the frame queue now, which is good since
     FRAME_SAVED_PC may use that queue to figure out its value
     (see tm-sparc.h).  We want the pc saved in the inferior frame. */
  INIT_FRAME_PC (fromleaf, prev);

  /* If ->frame and ->pc are unchanged, we are in the process of getting
     ourselves into an infinite backtrace.  Some architectures check this
     in FRAME_CHAIN or thereabouts, but it seems like there is no reason
     this can't be an architecture-independent check.  */
  if (next_frame != NULL)
    {
      if (prev->frame == next_frame->frame
	  && prev->pc == next_frame->pc)
	{
	  next_frame->prev = NULL;
	  obstack_free (&frame_cache_obstack, prev);
	  return NULL;
	}
    }

  find_pc_partial_function (prev->pc, &name,
			    (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
  if (IN_SIGTRAMP (prev->pc, name))
    prev->signal_handler_caller = 1;

  return prev;
}