示例#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;
}
static struct trad_frame_cache *
vaxobsd_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
{
  struct trad_frame_cache *cache;
  CORE_ADDR addr, base, func;

  if (*this_cache)
    return *this_cache;

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

  func = frame_pc_unwind (next_frame);
  func &= ~(vaxobsd_page_size - 1);

  base = frame_unwind_register_unsigned (next_frame, VAX_SP_REGNUM);
  addr = get_frame_memory_unsigned (next_frame, base - 4, 4);

  trad_frame_set_reg_addr (cache, VAX_SP_REGNUM, addr + 8);
  trad_frame_set_reg_addr (cache, VAX_FP_REGNUM, addr + 12);
  trad_frame_set_reg_addr (cache, VAX_AP_REGNUM, addr + 16);
  trad_frame_set_reg_addr (cache, VAX_PC_REGNUM, addr + 20);
  trad_frame_set_reg_addr (cache, VAX_PS_REGNUM, addr + 24);

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (cache, frame_id_build (base, func));

  return cache;
}
示例#3
0
static struct trad_frame_cache *
aix_sighandle_frame_cache (struct frame_info *this_frame,
			   void **this_cache)
{
  LONGEST backchain;
  CORE_ADDR base, base_orig, func;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *this_trad_cache;

  if ((*this_cache) != NULL)
    return (struct trad_frame_cache *) (*this_cache);

  this_trad_cache = trad_frame_cache_zalloc (this_frame);
  (*this_cache) = this_trad_cache;

  base = get_frame_register_unsigned (this_frame,
                                      gdbarch_sp_regnum (gdbarch));
  base_orig = base;

  if (tdep->wordsize == 4)
    {
      func = read_memory_unsigned_integer (base_orig +
					   SIG_FRAME_PC_OFFSET + 8,
					   tdep->wordsize, byte_order);
      safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET + 8,
				tdep->wordsize, byte_order, &backchain);
      base = (CORE_ADDR)backchain;
    }
  else
    {
      func = read_memory_unsigned_integer (base_orig +
					   SIG_FRAME_LR_OFFSET64,
					   tdep->wordsize, byte_order);
      safe_read_memory_integer (base_orig + SIG_FRAME_FP_OFFSET64,
				tdep->wordsize, byte_order, &backchain);
      base = (CORE_ADDR)backchain;
    }

  trad_frame_set_reg_value (this_trad_cache, gdbarch_pc_regnum (gdbarch), func);
  trad_frame_set_reg_value (this_trad_cache, gdbarch_sp_regnum (gdbarch), base);

  if (tdep->wordsize == 4)
    trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum,
                             base_orig + 0x38 + 52 + 8);
  else
    trad_frame_set_reg_addr (this_trad_cache, tdep->ppc_lr_regnum,
                             base_orig + 0x70 + 320);

  trad_frame_set_id (this_trad_cache, frame_id_build (base, func));
  trad_frame_set_this_base (this_trad_cache, base);

  return this_trad_cache;
}
示例#4
0
static struct trad_frame_cache *
ppcobsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR addr, base, func;
  gdb_byte buf[PPC_INSN_SIZE];
  unsigned long insn, sigcontext_offset;
  int i;

  if (*this_cache)
    return (struct trad_frame_cache *) *this_cache;

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

  func = get_frame_pc (this_frame);
  func &= ~(ppcobsd_page_size - 1);
  if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf))
    return cache;

  /* Calculate the offset where we can find `struct sigcontext'.  We
     base our calculation on the amount of stack space reserved by the
     first instruction of the signal trampoline.  */
  insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
  sigcontext_offset = (0x10000 - (insn & 0x0000ffff)) + 8;

  base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
  addr = base + sigcontext_offset + 2 * tdep->wordsize;
  for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
    {
      int regnum = i + tdep->ppc_gp0_regnum;
      trad_frame_set_reg_addr (cache, regnum, addr);
    }
  trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr);
  /* SRR0?  */
  addr += tdep->wordsize;

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (cache, frame_id_build (base, func));

  return cache;
}
示例#5
0
static struct trad_frame_cache *
amd64fbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
{
    struct gdbarch *gdbarch = get_frame_arch (this_frame);
    enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
    struct trad_frame_cache *cache;
    CORE_ADDR addr, func, pc, sp;
    const char *name;
    int i;

    if (*this_cache != NULL)
        return (*this_cache);

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

    func = get_frame_func (this_frame);
    sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);

    find_pc_partial_function (func, &name, NULL, NULL);
    if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func)
    {
        /* fork_exit hasn't been called (kthread has never run), so %rsp
        in the pcb points to the trapframe.  GDB has auto-adjusted
         %rsp for this frame to account for the "call" into
         fork_trampoline, so "undo" the adjustment.  */
        sp += 8;
    }

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

    /* Read %rip from trap frame.  */
    addr = sp + amd64fbsd_trapframe_offset[AMD64_RIP_REGNUM];
    pc = read_memory_unsigned_integer (addr, 8, byte_order);

    if (pc == 0 && strcmp(name, "fork_trampoline") == 0)
    {
        /* Initial frame of a kthread; terminate backtrace.  */
        trad_frame_set_id (cache, outer_frame_id);
    }
    else
    {
        /* Construct the frame ID using the function start.  */
        trad_frame_set_id (cache, frame_id_build (sp + TRAPFRAME_SIZE, func));
    }

    return cache;
}
static int
arm_android_sigreturn_frame_sniffer (const struct frame_unwind *self,
				     struct frame_info *this_frame,
				     void **this_cache)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  struct trad_frame_cache *trad_cache;

  if (pc != 0xffff0500)
    return 0;

  trad_cache = trad_frame_cache_zalloc (this_frame);
  arm_android_sigreturn_init (this_frame, trad_cache, pc);
  (*this_cache) = trad_cache;
  return 1;
}
static struct trad_frame_cache *
tramp_frame_cache (struct frame_info *this_frame,
		   void **this_cache)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  struct tramp_frame_cache *tramp_cache = (*this_cache);
  if (tramp_cache->trad_cache == NULL)
    {
      tramp_cache->trad_cache = trad_frame_cache_zalloc (this_frame);
      tramp_cache->tramp_frame->init (tramp_cache->tramp_frame,
				      this_frame,
				      tramp_cache->trad_cache,
				      tramp_cache->func);
    }
  return tramp_cache->trad_cache;
}
示例#8
0
static struct trad_frame_cache *
amd64obsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR func, sp, addr;
  ULONGEST cs;
  const char *name;
  int i;

  if (*this_cache)
    return (struct trad_frame_cache *) *this_cache;

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

  func = get_frame_func (this_frame);
  sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);

  find_pc_partial_function (func, &name, NULL, NULL);
  if (name && startswith (name, "Xintr"))
    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, byte_order);
  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
    {
      /* Trap from user space; terminate backtrace.  */
      trad_frame_set_id (cache, outer_frame_id);
    }
  else
    {
      /* Construct the frame ID using the function start.  */
      trad_frame_set_id (cache, frame_id_build (sp + 16, func));
    }

  return cache;
}
static struct trad_frame_cache *
ppcfbsd_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR addr, base, func;
  gdb_byte buf[PPC_INSN_SIZE];
  int i;

  if (*this_cache)
    return *this_cache;

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

  func = get_frame_pc (this_frame);
  func &= ~(ppcfbsd_page_size - 1);
  if (!safe_frame_unwind_memory (this_frame, func, buf, sizeof buf))
    return cache;

  base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
  addr = base + 0x10 + 2 * tdep->wordsize;
  for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
    {
      int regnum = i + tdep->ppc_gp0_regnum;
      trad_frame_set_reg_addr (cache, regnum, addr);
    }
  trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), addr);
  /* SRR0?  */
  addr += tdep->wordsize;

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (cache, frame_id_build (base, func));

  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;
}
示例#11
0
static struct trad_frame_cache *
ppcfbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR base;
  int i, regnum;

  if (*this_cache)
    return *this_cache;

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

  base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
  if (tdep->wordsize == 8)
    base += 48;
  else
    base += 8;

  for (i = 0; i < ppc_num_gprs; i++)
    trad_frame_set_reg_addr (cache, tdep->ppc_gp0_regnum + i, base
			     + (OFF_FIXREG + i) * tdep->wordsize);
  trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, base
			   + OFF_LR * tdep->wordsize);
  trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, base
			   + OFF_CR * tdep->wordsize);
  trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, base
			   + OFF_XER * tdep->wordsize);
  trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, base
			   + OFF_CTR * tdep->wordsize);
  /* SRR0?  */
  trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), base
			   + OFF_SRR0 * tdep->wordsize);

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (cache, frame_id_build (base, get_frame_func (this_frame)));
  
  return cache;
}
示例#12
0
static struct trad_frame_cache *
frv_linux_sigtramp_frame_cache (struct frame_info *this_frame,
				void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR addr;
  gdb_byte buf[4];
  int regnum;
  CORE_ADDR sc_addr_cache_val = 0;
  struct frame_id this_id;

  if (*this_cache)
    return (struct trad_frame_cache *) *this_cache;

  cache = trad_frame_cache_zalloc (this_frame);

  /* FIXME: cagney/2004-05-01: This is is long standing broken code.
     The frame ID's code address should be the start-address of the
     signal trampoline and not the current PC within that
     trampoline.  */
  get_frame_register (this_frame, sp_regnum, buf);
  addr = extract_unsigned_integer (buf, sizeof buf, byte_order);
  this_id = frame_id_build (addr, get_frame_pc (this_frame));
  trad_frame_set_id (cache, this_id);

  for (regnum = 0; regnum < frv_num_regs; regnum++)
    {
      LONGEST reg_addr = frv_linux_sigcontext_reg_addr (this_frame, regnum,
							&sc_addr_cache_val);
      if (reg_addr != -1)
	trad_frame_set_reg_addr (cache, regnum, reg_addr);
    }

  *this_cache = cache;
  return cache;
}
static struct trad_frame_cache *
frv_linux_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
{
  struct trad_frame_cache *cache;
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
  CORE_ADDR addr;
  char buf[4];
  int regnum;
  CORE_ADDR sc_addr_cache_val = 0;
  struct frame_id this_id;

  if (*this_cache)
    return *this_cache;

  cache = trad_frame_cache_zalloc (next_frame);

  /* FIXME: cagney/2004-05-01: This is is long standing broken code.
     The frame ID's code address should be the start-address of the
     signal trampoline and not the current PC within that
     trampoline.  */
  frame_unwind_register (next_frame, sp_regnum, buf);
  this_id = frame_id_build (extract_unsigned_integer (buf, sizeof buf),
			    frame_pc_unwind (next_frame));
  trad_frame_set_id (cache, this_id);

  for (regnum = 0; regnum < frv_num_regs; regnum++)
    {
      LONGEST reg_addr = frv_linux_sigcontext_reg_addr (next_frame, regnum,
							&sc_addr_cache_val);
      if (reg_addr != -1)
	trad_frame_set_reg_addr (cache, regnum, reg_addr);
    }

  *this_cache = cache;
  return cache;
}
示例#14
0
static struct trad_frame_cache *
mips_sde_frame_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  const struct mips_regnum *regs = mips_regnum (gdbarch);
  const int sizeof_reg_t = mips_abi_regsize (gdbarch);
  enum mips_abi abi = mips_abi (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR xcpt_frame;
  CORE_ADDR start_addr;
  CORE_ADDR stack_addr;
  CORE_ADDR pc;
  int i;

  if (*this_cache != NULL)
    return (struct trad_frame_cache *) *this_cache;
  cache = trad_frame_cache_zalloc (this_frame);
  *this_cache = cache;

  /* The previous registers are held in struct xcptcontext
     which is at $sp+offs

     struct xcptcontext {
       reg_t	sr;		CP0 Status
       reg_t	cr;		CP0 Cause
       reg_t	epc;		CP0 EPC
       reg_t	vaddr;		CP0 BadVAddr
       reg_t	regs[32];	General registers
       reg_t	mdlo;		LO
       reg_t	mdhi;		HI
       reg_t	mdex;		ACX
       ...
     };
  */

  stack_addr = get_frame_register_signed (this_frame,
					  gdbarch_sp_regnum (gdbarch));
  switch (abi)
    {
    case MIPS_ABI_O32:
      /* 40: XCPTCONTEXT
	 24: xcpt_gen() argspace		(16 bytes)
	 16: _xcptcall() saved ra, rounded up	( 8 bytes)
	 00: _xcptcall() argspace 		(16 bytes)  */
      xcpt_frame = stack_addr + 40;
      break;
    case MIPS_ABI_N32:
    case MIPS_ABI_N64:
    default:			/* Wild guess.  */
      /* 16: XCPTCONTEXT
	 16: xcpt_gen() argspace 		( 0 bytes)
	 00: _xcptcall() saved ra, rounded up	(16 bytes)  */
      xcpt_frame = stack_addr + 16;
      break;
    }

  trad_frame_set_reg_addr (cache,
			   MIPS_PS_REGNUM + gdbarch_num_regs (gdbarch),
			   xcpt_frame + 0 * sizeof_reg_t);
  trad_frame_set_reg_addr (cache,
			   regs->cause + gdbarch_num_regs (gdbarch),
			   xcpt_frame + 1 * sizeof_reg_t);
  trad_frame_set_reg_addr (cache,
			   regs->pc + gdbarch_num_regs (gdbarch),
			   xcpt_frame + 2 * sizeof_reg_t);
  trad_frame_set_reg_addr (cache,
			   regs->badvaddr + gdbarch_num_regs (gdbarch),
			   xcpt_frame + 3 * sizeof_reg_t);
  for (i = 0; i < MIPS_NUMREGS; i++)
    trad_frame_set_reg_addr (cache,
			     i + MIPS_ZERO_REGNUM + gdbarch_num_regs (gdbarch),
			     xcpt_frame + (4 + i) * sizeof_reg_t);
  trad_frame_set_reg_addr (cache,
			   regs->lo + gdbarch_num_regs (gdbarch),
			   xcpt_frame + 36 * sizeof_reg_t);
  trad_frame_set_reg_addr (cache,
			   regs->hi + gdbarch_num_regs (gdbarch),
			   xcpt_frame + 37 * sizeof_reg_t);

  pc = get_frame_pc (this_frame);
  find_pc_partial_function (pc, NULL, &start_addr, NULL);
  trad_frame_set_id (cache, frame_id_build (start_addr, stack_addr));

  return cache;
}
示例#15
0
static struct trad_frame_cache *
amd64nbsd_trapframe_cache(struct frame_info *this_frame, void **this_cache)
{
  struct trad_frame_cache *cache;
  CORE_ADDR func, sp, addr;
  ULONGEST cs = 0, rip = 0;
  const char *name;
  int i;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  if (*this_cache)
    return *this_cache;

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

  func = get_frame_func (this_frame);
  sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);

  find_pc_partial_function (func, &name, NULL, NULL);

  /* There is an extra 'call' in the interrupt sequence - ignore the extra
   * return address */
  if (name && strncmp (name, "Xintr", 5) == 0)
    addr = sp + 8;		/* It's an interrupt frame.  */
  else
    addr = sp;

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

  /* Read %cs and %rip when we have the addresses to hand */
  cs = read_memory_unsigned_integer (addr
    + amd64nbsd_tf_reg_offset[AMD64_CS_REGNUM], 8, byte_order);
  rip = read_memory_unsigned_integer (addr
    + amd64nbsd_tf_reg_offset[AMD64_RIP_REGNUM], 8, byte_order);

  /* The trap frame layout was changed lf the %rip value is less than 2^16 it
   * is almost certainly the %ss of the old format. */
  if (rip < (1 << 16))
    {

      for (i = 0; i < ARRAY_SIZE (amd64nbsd_tf_reg_offset); i++)
        {

          if (amd64nbsd_tf_reg_offset[i] == -1)
            continue;

          trad_frame_set_reg_addr (cache, i, addr + amd64nbsd_r_reg_offset[i]);

          /* Read %cs when we have the address to hand */
          if (i == AMD64_CS_REGNUM)
	    cs = read_memory_unsigned_integer (addr + amd64nbsd_r_reg_offset[i],
	    8, byte_order);
        }
    }

  if ((cs & I386_SEL_RPL) == I386_SEL_UPL ||
	(name && strncmp(name, "Xsoft", 5) == 0))
    {
      /* Trap from user space or soft interrupt; terminate backtrace.  */
      trad_frame_set_id (cache, outer_frame_id);
    }
  else
    {
      /* Construct the frame ID using the function start.  */
      trad_frame_set_id (cache, frame_id_build (sp + 16, func));
    }

  return cache;
}
示例#16
0
static struct trad_frame_cache *
i386nbsd_trapframe_cache(struct frame_info *this_frame, void **this_cache)
{
  struct trad_frame_cache *cache;
  CORE_ADDR func, sp, addr, tmp;
  ULONGEST cs;
  const char *name;
  int i;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  if (*this_cache)
    return (struct trad_frame_cache *)*this_cache;

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

  func = get_frame_func (this_frame);
  sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);

  find_pc_partial_function (func, &name, NULL, NULL);
  if (name && strncmp (name, "Xintr", 5) == 0)
    {
      /* It's an interrupt frame. */
      tmp = read_memory_unsigned_integer (sp + 4, 4, byte_order);
      if (tmp < 15)
        {
          /* Reasonable value for 'ppl': already on interrupt stack. */
          addr = sp + 8;
        }
      else
        {
          /* Switch to previous stack. */
          addr = tmp + 4;
        }
    }
  else
    {
      /* It's a trap frame. */
      addr = sp + 4;
    }

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

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

  return cache;
}