Exemple #1
0
/* Simple frame_unwind_cache.  
   This finds the "extra info" for the frame.  */
struct trad_frame_cache *
mn10300_frame_unwind_cache (struct frame_info *next_frame,
			    void **this_prologue_cache)
{
  struct trad_frame_cache *cache;
  CORE_ADDR pc, start, end;

  if (*this_prologue_cache)
    return (*this_prologue_cache);

  cache = trad_frame_cache_zalloc (next_frame);
  pc = gdbarch_unwind_pc (current_gdbarch, next_frame);
  mn10300_analyze_prologue (next_frame, (void **) &cache, pc);
  if (find_pc_partial_function (pc, NULL, &start, &end))
    trad_frame_set_id (cache, 
		       frame_id_build (trad_frame_get_this_base (cache), 
				       start));
  else
    trad_frame_set_id (cache, 
		       frame_id_build (trad_frame_get_this_base (cache), 
				       frame_func_unwind (next_frame)));

  (*this_prologue_cache) = cache;
  return cache;
}
Exemple #2
0
struct m88k_frame_cache *
m88k_frame_cache (struct frame_info *next_frame, void **this_cache)
{
  struct m88k_frame_cache *cache;
  CORE_ADDR frame_sp;

  if (*this_cache)
    return *this_cache;

  cache = FRAME_OBSTACK_ZALLOC (struct m88k_frame_cache);
  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);
  cache->fp_offset = -1;

  cache->pc = frame_func_unwind (next_frame);
  if (cache->pc != 0)
    {
      CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame);
      m88k_analyze_prologue (cache->pc, addr_in_block, cache);
    }

  /* Calculate the stack pointer used in the prologue.  */
  if (cache->fp_offset != -1)
    {
      CORE_ADDR fp;

      fp = frame_unwind_register_unsigned (next_frame, M88K_R30_REGNUM);
      frame_sp = fp - cache->fp_offset;
    }
  else
    {
      /* If we know where the return address is saved, we can take a
         solid guess at what the frame pointer should be.  */
      if (cache->saved_regs[M88K_R1_REGNUM].addr != -1)
	cache->fp_offset = cache->saved_regs[M88K_R1_REGNUM].addr - 4;
      frame_sp = frame_unwind_register_unsigned (next_frame, M88K_R31_REGNUM);
    }

  /* Now that we know the stack pointer, adjust the location of the
     saved registers.  */
  {
    int regnum;

    for (regnum = M88K_R0_REGNUM; regnum < M88K_R31_REGNUM; regnum ++)
      if (cache->saved_regs[regnum].addr != -1)
	cache->saved_regs[regnum].addr += frame_sp;
  }

  /* Calculate the frame's base.  */
  cache->base = frame_sp - cache->sp_offset;
  trad_frame_set_value (cache->saved_regs, M88K_R31_REGNUM, cache->base);

  /* Identify SXIP with the return address in R1.  */
  cache->saved_regs[M88K_SXIP_REGNUM] = cache->saved_regs[M88K_R1_REGNUM];

  *this_cache = cache;
  return cache;
}
Exemple #3
0
static struct libunwind_frame_cache *
libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
{
  unw_accessors_t *acc;
  unw_addr_space_t as;
  unw_word_t fp;
  unw_regnum_t uw_sp_regnum;
  struct libunwind_frame_cache *cache;
  struct libunwind_descr *descr;
  int i, ret;

  if (*this_cache)
    return *this_cache;

  /* Allocate a new cache.  */
  cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache);

  cache->func_addr = frame_func_unwind (next_frame);

  /* Get a libunwind cursor to the previous frame.  We do this by initializing
     a cursor.  Libunwind treats a new cursor as the top of stack and will get
     the current register set via the libunwind register accessor.  Now, we
     provide the platform-specific accessors and we set up the register accessor to use
     the frame register unwinding interfaces so that we properly get the registers for
     the current frame rather than the top.  We then use the  unw_step function to 
     move the libunwind cursor back one frame.  We can later use this cursor to find previous 
     registers via the unw_get_reg interface which will invoke libunwind's special logic.  */
  descr = libunwind_descr (get_frame_arch (next_frame));
  acc = descr->accessors;
  as =  unw_create_addr_space_p (acc,
				 TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
				 ? __BIG_ENDIAN
				 : __LITTLE_ENDIAN);

  unw_init_remote_p (&cache->cursor, as, next_frame);
  unw_step_p (&cache->cursor);

  /* To get base address, get sp from previous frame.  */
  uw_sp_regnum = descr->gdb2uw (SP_REGNUM);
  ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp);
  if (ret < 0)
    error ("Can't get libunwind sp register.");

  cache->base = (CORE_ADDR)fp;

  *this_cache = cache;
  return cache;
}
static struct trad_frame_cache *
amd64obsd_trapframe_cache(struct frame_info *next_frame, void **this_cache)
{
  struct trad_frame_cache *cache;
  CORE_ADDR func, sp, addr;
  ULONGEST cs;
  char *name;
  int i;

  if (*this_cache)
    return *this_cache;

  cache = trad_frame_cache_zalloc (next_frame);
  *this_cache = cache;

  /* NORMAL_FRAME matches the type in amd64obsd_trapframe_unwind, but
     SIGTRAMP_FRAME might be more appropriate.  */
  func = frame_func_unwind (next_frame, NORMAL_FRAME);
  sp = frame_unwind_register_unsigned (next_frame, AMD64_RSP_REGNUM);

  find_pc_partial_function (func, &name, NULL, NULL);
  if (name && strncmp (name, "Xintr", 5) == 0)
    addr = sp + 8;		/* It's an interrupt frame.  */
  else
    addr = sp;

  for (i = 0; i < ARRAY_SIZE (amd64obsd_tf_reg_offset); i++)
    if (amd64obsd_tf_reg_offset[i] != -1)
      trad_frame_set_reg_addr (cache, i, addr + amd64obsd_tf_reg_offset[i]);

  /* Read %cs from trap frame.  */
  addr += amd64obsd_tf_reg_offset[AMD64_CS_REGNUM];
  cs = read_memory_unsigned_integer (addr, 8); 
  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
    {
      /* Trap from user space; terminate backtrace.  */
      trad_frame_set_id (cache, null_frame_id);
    }
  else
    {
      /* Construct the frame ID using the function start.  */
      trad_frame_set_id (cache, frame_id_build (sp + 16, func));
    }

  return cache;
}
struct sparc_frame_cache *
sparc_frame_cache (struct frame_info *next_frame, void **this_cache)
{
  struct sparc_frame_cache *cache;

  if (*this_cache)
    return *this_cache;

  cache = sparc_alloc_frame_cache ();
  *this_cache = cache;

  cache->pc = frame_func_unwind (next_frame);
  if (cache->pc != 0)
    {
      CORE_ADDR addr_in_block = frame_unwind_address_in_block (next_frame);
      sparc_analyze_prologue (cache->pc, addr_in_block, cache);
    }

  if (cache->frameless_p)
    {
      /* This function is frameless, so %fp (%i6) holds the frame
         pointer for our calling frame.  Use %sp (%o6) as this frame's
         base address.  */
      cache->base =
	frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
    }
  else
    {
      /* For normal frames, %fp (%i6) holds the frame pointer, the
         base address for the current stack frame.  */
      cache->base =
	frame_unwind_register_unsigned (next_frame, SPARC_FP_REGNUM);
    }

  if (cache->base & 1)
    cache->base += BIAS;

  return cache;
}