Exemple #1
0
static void
m68kobsd_sigtramp_cache_init (const struct tramp_frame *self,
			      struct frame_info *this_frame,
			      struct trad_frame_cache *this_cache,
			      CORE_ADDR func)
{
  CORE_ADDR addr, base, pc;
  int regnum;

  base = get_frame_register_unsigned (this_frame, M68K_SP_REGNUM);

  /* The 'addql #4,%sp' instruction at offset 8 adjusts the stack
     pointer.  Adjust the frame base accordingly.  */
  pc = get_frame_register_unsigned (this_frame, M68K_PC_REGNUM);
  if ((pc - func) > 8)
    base -= 4;

  /* Get frame pointer, stack pointer, program counter and processor
     state from `struct sigcontext'.  */
  addr = get_frame_memory_unsigned (this_frame, base + 8, 4);
  trad_frame_set_reg_addr (this_cache, M68K_FP_REGNUM, addr + 8);
  trad_frame_set_reg_addr (this_cache, M68K_SP_REGNUM, addr + 12);
  trad_frame_set_reg_addr (this_cache, M68K_PC_REGNUM, addr + 20);
  trad_frame_set_reg_addr (this_cache, M68K_PS_REGNUM, addr + 24);

  /* The sc_ap member of `struct sigcontext' points to additional
     hardware state.  Here we find the missing registers.  */
  addr = get_frame_memory_unsigned (this_frame, addr + 16, 4) + 4;
  for (regnum = M68K_D0_REGNUM; regnum < M68K_FP_REGNUM; regnum++, addr += 4)
    trad_frame_set_reg_addr (this_cache, regnum, addr);

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}
static struct sparc_frame_cache *
sparc64_sol2_sigtramp_frame_cache (struct frame_info *this_frame,
				   void **this_cache)
{
  struct sparc_frame_cache *cache;
  CORE_ADDR mcontext_addr, addr;
  int regnum;

  if (*this_cache)
    return *this_cache;

  cache = sparc_frame_cache (this_frame, this_cache);
  gdb_assert (cache == *this_cache);

  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  /* The third argument is a pointer to an instance of `ucontext_t',
     which has a member `uc_mcontext' that contains the saved
     registers.  */
  regnum =
    (cache->copied_regs_mask & 0x04) ? SPARC_I2_REGNUM : SPARC_O2_REGNUM;
  mcontext_addr = get_frame_register_unsigned (this_frame, regnum) + 64;

  cache->saved_regs[SPARC64_CCR_REGNUM].addr = mcontext_addr + 0 * 8;
  cache->saved_regs[SPARC64_PC_REGNUM].addr = mcontext_addr + 1 * 8;
  cache->saved_regs[SPARC64_NPC_REGNUM].addr = mcontext_addr + 2 * 8;
  cache->saved_regs[SPARC64_Y_REGNUM].addr = mcontext_addr + 3 * 8;
  cache->saved_regs[SPARC64_ASI_REGNUM].addr = mcontext_addr + 19 * 8; 
  cache->saved_regs[SPARC64_FPRS_REGNUM].addr = mcontext_addr + 20 * 8;

  /* Since %g0 is always zero, keep the identity encoding.  */
  for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 8;
       regnum <= SPARC_O7_REGNUM; regnum++, addr += 8)
    cache->saved_regs[regnum].addr = addr;

  if (get_frame_memory_unsigned (this_frame, mcontext_addr + 21 * 8, 8))
    {
      /* The register windows haven't been flushed.  */
      for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
	trad_frame_set_unknown (cache->saved_regs, regnum);
    }
  else
    {
      CORE_ADDR sp;

      addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
      sp = get_frame_memory_unsigned (this_frame, addr, 8);
      for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
	   regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
	cache->saved_regs[regnum].addr = addr;
    }

  return cache;
}
static struct sparc_frame_cache *
sparc32_sol2_sigtramp_frame_cache (struct frame_info *next_frame,
				   void **this_cache)
{
  struct sparc_frame_cache *cache;
  CORE_ADDR mcontext_addr, addr;
  int regnum;

  if (*this_cache)
    return *this_cache;

  cache = sparc_frame_cache (next_frame, this_cache);
  gdb_assert (cache == *this_cache);

  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);

  /* The third argument is a pointer to an instance of `ucontext_t',
     which has a member `uc_mcontext' that contains the saved
     registers.  */
  regnum = (cache->frameless_p ? SPARC_O2_REGNUM : SPARC_I2_REGNUM);
  mcontext_addr = frame_unwind_register_unsigned (next_frame, regnum) + 40;

  cache->saved_regs[SPARC32_PSR_REGNUM].addr = mcontext_addr + 0 * 4;
  cache->saved_regs[SPARC32_PC_REGNUM].addr = mcontext_addr + 1 * 4;
  cache->saved_regs[SPARC32_NPC_REGNUM].addr = mcontext_addr + 2 * 4;
  cache->saved_regs[SPARC32_Y_REGNUM].addr = mcontext_addr + 3 * 4;

  /* Since %g0 is always zero, keep the identity encoding.  */
  for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 4 * 4;
       regnum <= SPARC_O7_REGNUM; regnum++, addr += 4)
    cache->saved_regs[regnum].addr = addr;

  if (get_frame_memory_unsigned (next_frame, mcontext_addr + 19 * 4, 4))
    {
      /* The register windows haven't been flushed.  */
      for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
	trad_frame_set_unknown (cache->saved_regs, regnum);
    }
  else
    {
      addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
      addr = get_frame_memory_unsigned (next_frame, addr, 4);
      for (regnum = SPARC_L0_REGNUM;
	   regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
	cache->saved_regs[regnum].addr = addr;
    }

  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;
}
static void
tilegx_linux_sigframe_init (const struct tramp_frame *self,
			    struct frame_info *this_frame,
			    struct trad_frame_cache *this_cache,
			    CORE_ADDR func)
{
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, 54);

  /* Base address of register save area.  */
  CORE_ADDR base = sp
                   + 16    /* Skip ABI_SAVE_AREA.  */
                   + 128   /* Skip SIGINFO.  */
                   + 40;   /* Skip UCONTEXT.  */

  /* Address of saved LR register (R56) which holds previous PC.  */
  CORE_ADDR prev_pc = base + 56 * 8;

  int i;

  for (i = 0; i < 56; i++)
    trad_frame_set_reg_addr (this_cache, i, base + i * 8);

  trad_frame_set_reg_value (this_cache, 64,
                            get_frame_memory_unsigned (this_frame, prev_pc, 8));

  /* Save a frame ID.  */
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}
Exemple #6
0
static CORE_ADDR
amd64_sol2_mcontext_addr (struct frame_info *this_frame)
{
  CORE_ADDR sp, ucontext_addr;

  sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);
  ucontext_addr = get_frame_memory_unsigned (this_frame, sp + 8, 8);

  return ucontext_addr + 72;
}
static CORE_ADDR
i386_sol2_mcontext_addr (struct frame_info *next_frame)
{
  CORE_ADDR sp, ucontext_addr;

  sp = frame_unwind_register_unsigned (next_frame, I386_ESP_REGNUM);
  ucontext_addr = get_frame_memory_unsigned (next_frame, sp + 8, 4);

  return ucontext_addr + 36;
}
Exemple #8
0
struct trad_frame_saved_reg *
sparc64nbsd_sigcontext_saved_regs (CORE_ADDR sigcontext_addr,
				   struct frame_info *next_frame)
{
  struct trad_frame_saved_reg *saved_regs;
  CORE_ADDR addr, sp;
  int regnum, delta;

  saved_regs = trad_frame_alloc_saved_regs (next_frame);

  /* The registers are saved in bits and pieces scattered all over the
     place.  The code below records their location on the assumption
     that the part of the signal trampoline that saves the state has
     been executed.  */

  saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
  saved_regs[SPARC64_PC_REGNUM].addr = sigcontext_addr + 16;
  saved_regs[SPARC64_NPC_REGNUM].addr = sigcontext_addr + 24;
  saved_regs[SPARC64_STATE_REGNUM].addr = sigcontext_addr + 32;
  saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 40;
  saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 48;

  /* The remaining `global' registers and %y are saved in the `local'
     registers.  */
  delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
  for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
    saved_regs[regnum].realreg = regnum + delta;
  saved_regs[SPARC64_Y_REGNUM].realreg = SPARC_L1_REGNUM;

  /* The remaining `out' registers can be found in the current frame's
     `in' registers.  */
  delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
  for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
    saved_regs[regnum].realreg = regnum + delta;
  saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;

  /* The `local' and `in' registers have been saved in the register
     save area.  */
  addr = saved_regs[SPARC_SP_REGNUM].addr;
  sp = get_frame_memory_unsigned (next_frame, addr, 8);
  for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
       regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
    saved_regs[regnum].addr = addr;

  /* TODO: Handle the floating-point registers.  */

  return saved_regs;
}
static void
sparc64_linux_sigframe_init (const struct tramp_frame *self,
			     struct frame_info *this_frame,
			     struct trad_frame_cache *this_cache,
			     CORE_ADDR func)
{
  CORE_ADDR base, addr, sp_addr;
  int regnum;

  base = get_frame_register_unsigned (this_frame, SPARC_O1_REGNUM);
  base += 128;

  /* Offsets from <bits/sigcontext.h>.  */

  /* Since %g0 is always zero, keep the identity encoding.  */
  addr = base + 8;
  sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8);
  for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
    {
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      addr += 8;
    }

  trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0);
  trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8);
  trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16);
  trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24);
  trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28);

  base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
  if (base & 1)
    base += BIAS;

  addr = get_frame_memory_unsigned (this_frame, sp_addr, 8);
  if (addr & 1)
    addr += BIAS;

  for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
    {
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      addr += 8;
    }
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}
Exemple #10
0
static void
arm_linux_restart_syscall_init (const struct tramp_frame *self,
				struct frame_info *this_frame,
				struct trad_frame_cache *this_cache,
				CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
  CORE_ADDR pc = get_frame_memory_unsigned (this_frame, sp, 4);
  CORE_ADDR cpsr = get_frame_register_unsigned (this_frame, ARM_PS_REGNUM);
  ULONGEST t_bit = arm_psr_thumb_bit (gdbarch);
  int sp_offset;

  /* There are two variants of this trampoline; with older kernels, the
     stub is placed on the stack, while newer kernels use the stub from
     the vector page.  They are identical except that the older version
     increments SP by 12 (to skip stored PC and the stub itself), while
     the newer version increments SP only by 4 (just the stored PC).  */
  if (self->insn[1].bytes == ARM_LDR_PC_SP_4)
    sp_offset = 4;
  else
    sp_offset = 12;

  /* Update Thumb bit in CPSR.  */
  if (pc & 1)
    cpsr |= t_bit;
  else
    cpsr &= ~t_bit;

  /* Remove Thumb bit from PC.  */
  pc = gdbarch_addr_bits_remove (gdbarch, pc);

  /* Save previous register values.  */
  trad_frame_set_reg_value (this_cache, ARM_SP_REGNUM, sp + sp_offset);
  trad_frame_set_reg_value (this_cache, ARM_PC_REGNUM, pc);
  trad_frame_set_reg_value (this_cache, ARM_PS_REGNUM, cpsr);

  /* Save a frame ID.  */
  trad_frame_set_id (this_cache, frame_id_build (sp, func));
}
Exemple #11
0
static void
sparc32_linux_sigframe_init (const struct tramp_frame *self,
			     struct frame_info *this_frame,
			     struct trad_frame_cache *this_cache,
			     CORE_ADDR func)
{
  CORE_ADDR base, addr, sp_addr;
  int regnum;

  base = get_frame_register_unsigned (this_frame, SPARC_O1_REGNUM);
  if (self == &sparc32_linux_rt_sigframe)
    base += 128;

  /* Offsets from <bits/sigcontext.h>.  */

  trad_frame_set_reg_addr (this_cache, SPARC32_PSR_REGNUM, base + 0);
  trad_frame_set_reg_addr (this_cache, SPARC32_PC_REGNUM, base + 4);
  trad_frame_set_reg_addr (this_cache, SPARC32_NPC_REGNUM, base + 8);
  trad_frame_set_reg_addr (this_cache, SPARC32_Y_REGNUM, base + 12);

  /* Since %g0 is always zero, keep the identity encoding.  */
  addr = base + 20;
  sp_addr = base + 16 + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 4);
  for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
    {
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      addr += 4;
    }

  base = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
  addr = get_frame_memory_unsigned (this_frame, sp_addr, 4);

  for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
    {
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      addr += 4;
    }
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}
Exemple #12
0
static CORE_ADDR
alphaobsd_sigcontext_addr (struct frame_info *this_frame)
{
  CORE_ADDR pc = get_frame_pc (this_frame);

  if (alphaobsd_sigtramp_offset (pc) < 3 * ALPHA_INSN_SIZE)
    {
      /* On entry, a pointer the `struct sigcontext' is passed in %a2.  */
      return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM + 2);
    }
  else if (alphaobsd_sigtramp_offset (pc) < 4 * ALPHA_INSN_SIZE)
    {
      /* It is stored on the stack Before calling the signal handler.  */
      CORE_ADDR sp;
      sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
      return get_frame_memory_unsigned (this_frame, sp, 8);
    }
  else
    {
      /* It is reloaded into %a0 for the sigreturn(2) call.  */
      return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM);
    }
}
static void
sparc32_frame_prev_register (struct frame_info *next_frame, void **this_cache,
			     int regnum, int *optimizedp,
			     enum lval_type *lvalp, CORE_ADDR *addrp,
			     int *realnump, gdb_byte *valuep)
{
  struct sparc_frame_cache *cache =
    sparc32_frame_cache (next_frame, this_cache);

  if (regnum == SPARC32_PC_REGNUM || regnum == SPARC32_NPC_REGNUM)
    {
      *optimizedp = 0;
      *lvalp = not_lval;
      *addrp = 0;
      *realnump = -1;
      if (valuep)
	{
	  CORE_ADDR pc = (regnum == SPARC32_NPC_REGNUM) ? 4 : 0;

	  /* If this functions has a Structure, Union or
             Quad-Precision return value, we have to skip the UNIMP
             instruction that encodes the size of the structure.  */
	  if (cache->struct_return_p)
	    pc += 4;

	  regnum = cache->frameless_p ? SPARC_O7_REGNUM : SPARC_I7_REGNUM;
	  pc += frame_unwind_register_unsigned (next_frame, regnum) + 8;
	  store_unsigned_integer (valuep, 4, pc);
	}
      return;
    }

  /* Handle StackGhost.  */
  {
    ULONGEST wcookie = sparc_fetch_wcookie ();

    if (wcookie != 0 && !cache->frameless_p && regnum == SPARC_I7_REGNUM)
      {
	*optimizedp = 0;
	*lvalp = not_lval;
	*addrp = 0;
	*realnump = -1;
	if (valuep)
	  {
	    CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
	    ULONGEST i7;

	    /* Read the value in from memory.  */
	    i7 = get_frame_memory_unsigned (next_frame, addr, 4);
	    store_unsigned_integer (valuep, 4, i7 ^ wcookie);
	  }
	return;
      }
  }

  /* The previous frame's `local' and `in' registers have been saved
     in the register save area.  */
  if (!cache->frameless_p
      && regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM)
    {
      *optimizedp = 0;
      *lvalp = lval_memory;
      *addrp = cache->base + (regnum - SPARC_L0_REGNUM) * 4;
      *realnump = -1;
      if (valuep)
	{
	  struct gdbarch *gdbarch = get_frame_arch (next_frame);

	  /* Read the value in from memory.  */
	  read_memory (*addrp, valuep, register_size (gdbarch, regnum));
	}
      return;
    }

  /* The previous frame's `out' registers are accessable as the
     current frame's `in' registers.  */
  if (!cache->frameless_p
      && regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM)
    regnum += (SPARC_I0_REGNUM - SPARC_O0_REGNUM);

  *optimizedp = 0;
  *lvalp = lval_register;
  *addrp = 0;
  *realnump = regnum;
  if (valuep)
    frame_unwind_register (next_frame, (*realnump), valuep);
}
Exemple #14
0
static void
am33_linux_sigframe_cache_init (const struct tramp_frame *self,
                                struct frame_info *this_frame,
			        struct trad_frame_cache *this_cache,
			        CORE_ADDR func)
{
  CORE_ADDR sc_base, fpubase;
  int i;

  sc_base = get_frame_register_unsigned (this_frame, E_SP_REGNUM);
  if (self == &am33_linux_sigframe)
    {
      sc_base += 8;
      sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
    }
  else
    {
      sc_base += 12;
      sc_base = get_frame_memory_unsigned (this_frame, sc_base, 4);
      sc_base += 20;
    }

  trad_frame_set_reg_addr (this_cache, E_D0_REGNUM,
                           sc_base + AM33_SIGCONTEXT_D0);
  trad_frame_set_reg_addr (this_cache, E_D1_REGNUM,
                           sc_base + AM33_SIGCONTEXT_D1);
  trad_frame_set_reg_addr (this_cache, E_D2_REGNUM,
                           sc_base + AM33_SIGCONTEXT_D2);
  trad_frame_set_reg_addr (this_cache, E_D3_REGNUM,
                           sc_base + AM33_SIGCONTEXT_D3);

  trad_frame_set_reg_addr (this_cache, E_A0_REGNUM,
                           sc_base + AM33_SIGCONTEXT_A0);
  trad_frame_set_reg_addr (this_cache, E_A1_REGNUM,
                           sc_base + AM33_SIGCONTEXT_A1);
  trad_frame_set_reg_addr (this_cache, E_A2_REGNUM,
                           sc_base + AM33_SIGCONTEXT_A2);
  trad_frame_set_reg_addr (this_cache, E_A3_REGNUM,
                           sc_base + AM33_SIGCONTEXT_A3);

  trad_frame_set_reg_addr (this_cache, E_E0_REGNUM,
                           sc_base + AM33_SIGCONTEXT_E0);
  trad_frame_set_reg_addr (this_cache, E_E1_REGNUM,
                           sc_base + AM33_SIGCONTEXT_E1);
  trad_frame_set_reg_addr (this_cache, E_E2_REGNUM,
                           sc_base + AM33_SIGCONTEXT_E2);
  trad_frame_set_reg_addr (this_cache, E_E3_REGNUM,
                           sc_base + AM33_SIGCONTEXT_E3);
  trad_frame_set_reg_addr (this_cache, E_E4_REGNUM,
                           sc_base + AM33_SIGCONTEXT_E4);
  trad_frame_set_reg_addr (this_cache, E_E5_REGNUM,
                           sc_base + AM33_SIGCONTEXT_E5);
  trad_frame_set_reg_addr (this_cache, E_E6_REGNUM,
                           sc_base + AM33_SIGCONTEXT_E6);
  trad_frame_set_reg_addr (this_cache, E_E7_REGNUM,
                           sc_base + AM33_SIGCONTEXT_E7);

  trad_frame_set_reg_addr (this_cache, E_LAR_REGNUM,
                           sc_base + AM33_SIGCONTEXT_LAR);
  trad_frame_set_reg_addr (this_cache, E_LIR_REGNUM,
                           sc_base + AM33_SIGCONTEXT_LIR);
  trad_frame_set_reg_addr (this_cache, E_MDR_REGNUM,
                           sc_base + AM33_SIGCONTEXT_MDR);
  trad_frame_set_reg_addr (this_cache, E_MCVF_REGNUM,
                           sc_base + AM33_SIGCONTEXT_MCVF);
  trad_frame_set_reg_addr (this_cache, E_MCRL_REGNUM,
                           sc_base + AM33_SIGCONTEXT_MCRL);
  trad_frame_set_reg_addr (this_cache, E_MDRQ_REGNUM,
                           sc_base + AM33_SIGCONTEXT_MDRQ);

  trad_frame_set_reg_addr (this_cache, E_SP_REGNUM,
                           sc_base + AM33_SIGCONTEXT_SP);
  trad_frame_set_reg_addr (this_cache, E_PSW_REGNUM,
                           sc_base + AM33_SIGCONTEXT_EPSW);
  trad_frame_set_reg_addr (this_cache, E_PC_REGNUM,
                           sc_base + AM33_SIGCONTEXT_PC);

  fpubase = get_frame_memory_unsigned (this_frame,
                                       sc_base + AM33_SIGCONTEXT_FPUCONTEXT,
				       4);
  if (fpubase)
    {
      for (i = 0; i < 32; i++)
	{
	  trad_frame_set_reg_addr (this_cache, E_FS0_REGNUM + i,
	                           fpubase + 4 * i);
	}
      trad_frame_set_reg_addr (this_cache, E_FPCR_REGNUM, fpubase + 4 * 32);
    }

  trad_frame_set_id (this_cache, frame_id_build (sc_base, func));
}
Exemple #15
0
struct trad_frame_saved_reg *
sparc32nbsd_sigcontext_saved_regs (struct frame_info *this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct trad_frame_saved_reg *saved_regs;
  CORE_ADDR addr, sigcontext_addr;
  int regnum, delta;
  ULONGEST psr;

  saved_regs = trad_frame_alloc_saved_regs (this_frame);

  /* We find the appropriate instance of `struct sigcontext' at a
     fixed offset in the signal frame.  */
  addr = get_frame_register_unsigned (this_frame, SPARC_FP_REGNUM);
  sigcontext_addr = addr + 64 + 16;

  /* The registers are saved in bits and pieces scattered all over the
     place.  The code below records their location on the assumption
     that the part of the signal trampoline that saves the state has
     been executed.  */

  saved_regs[SPARC_SP_REGNUM].addr = sigcontext_addr + 8;
  saved_regs[SPARC32_PC_REGNUM].addr = sigcontext_addr + 12;
  saved_regs[SPARC32_NPC_REGNUM].addr = sigcontext_addr + 16;
  saved_regs[SPARC32_PSR_REGNUM].addr = sigcontext_addr + 20;
  saved_regs[SPARC_G1_REGNUM].addr = sigcontext_addr + 24;
  saved_regs[SPARC_O0_REGNUM].addr = sigcontext_addr + 28;

  /* The remaining `global' registers and %y are saved in the `local'
     registers.  */
  delta = SPARC_L0_REGNUM - SPARC_G0_REGNUM;
  for (regnum = SPARC_G2_REGNUM; regnum <= SPARC_G7_REGNUM; regnum++)
    saved_regs[regnum].realreg = regnum + delta;
  saved_regs[SPARC32_Y_REGNUM].realreg = SPARC_L1_REGNUM;

  /* The remaining `out' registers can be found in the current frame's
     `in' registers.  */
  delta = SPARC_I0_REGNUM - SPARC_O0_REGNUM;
  for (regnum = SPARC_O1_REGNUM; regnum <= SPARC_O5_REGNUM; regnum++)
    saved_regs[regnum].realreg = regnum + delta;
  saved_regs[SPARC_O7_REGNUM].realreg = SPARC_I7_REGNUM;

  /* The `local' and `in' registers have been saved in the register
     save area.  */
  addr = saved_regs[SPARC_SP_REGNUM].addr;
  addr = get_frame_memory_unsigned (this_frame, addr, 4);
  for (regnum = SPARC_L0_REGNUM;
       regnum <= SPARC_I7_REGNUM; regnum++, addr += 4)
    saved_regs[regnum].addr = addr;

  /* Handle StackGhost.  */
  {
    ULONGEST wcookie = sparc_fetch_wcookie (gdbarch);

    if (wcookie != 0)
      {
	ULONGEST i7;

	addr = saved_regs[SPARC_I7_REGNUM].addr;
	i7 = get_frame_memory_unsigned (this_frame, addr, 4);
	trad_frame_set_value (saved_regs, SPARC_I7_REGNUM, i7 ^ wcookie);
      }
  }

  /* The floating-point registers are only saved if the EF bit in %prs
     has been set.  */

#define PSR_EF	0x00001000

  addr = saved_regs[SPARC32_PSR_REGNUM].addr;
  psr = get_frame_memory_unsigned (this_frame, addr, 4);
  if (psr & PSR_EF)
    {
      CORE_ADDR sp;

      sp = get_frame_register_unsigned (this_frame, SPARC_SP_REGNUM);
      saved_regs[SPARC32_FSR_REGNUM].addr = sp + 96;
      for (regnum = SPARC_F0_REGNUM, addr = sp + 96 + 8;
	   regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
	saved_regs[regnum].addr = addr;
    }

  return saved_regs;
}
static struct sparc_frame_cache *
sparc64fbsd_sigtramp_frame_cache(struct frame_info *next_frame,
				 void **this_cache)
{
  struct sparc_frame_cache *cache;
  CORE_ADDR addr, mcontext_addr, sp;
  LONGEST fprs;
  int regnum;

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

  cache = sparc_frame_cache (next_frame, this_cache);
  gdb_assert (cache == *this_cache);

  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);

  /* The third argument is a pointer to an instance of `ucontext_t',
     which has a member `uc_mcontext' that contains the saved
     registers.  */
  addr = frame_unwind_register_unsigned (next_frame, SPARC_O2_REGNUM);
  mcontext_addr = addr + 64;

  /* The following registers travel in the `mc_local' slots of
     `mcontext_t'.  */
  addr = mcontext_addr + 16 * 8;
  cache->saved_regs[SPARC64_FPRS_REGNUM].addr = addr + 0 * 8;
  cache->saved_regs[SPARC64_FSR_REGNUM].addr = addr + 1 * 8;

  /* The following registers travel in the `mc_in' slots of
     `mcontext_t'.  */
  addr = mcontext_addr + 24 * 8;
  cache->saved_regs[SPARC64_NPC_REGNUM].addr = addr + 0 * 8;
  cache->saved_regs[SPARC64_PC_REGNUM].addr = addr + 1 * 8;
  cache->saved_regs[SPARC64_STATE_REGNUM].addr = addr + 2 * 8;
  cache->saved_regs[SPARC64_Y_REGNUM].addr = addr + 4 * 8;

  /* The `global' and `out' registers travel in the `mc_global' and
     `mc_out' slots of `mcontext_t', except for %g0.  Since %g0 is
     always zero, keep the identity encoding.  */
  for (regnum = SPARC_G1_REGNUM, addr = mcontext_addr + 8;
       regnum <= SPARC_O7_REGNUM; regnum++, addr += 8)
    cache->saved_regs[regnum].addr = addr;

  /* The `local' and `in' registers have been saved in the register
     save area.  */
  addr = cache->saved_regs[SPARC_SP_REGNUM].addr;
  sp = get_frame_memory_unsigned (next_frame, addr, 8);
  for (regnum = SPARC_L0_REGNUM, addr = sp + BIAS;
       regnum <= SPARC_I7_REGNUM; regnum++, addr += 8)
    cache->saved_regs[regnum].addr = addr;

  /* The floating-point registers are only saved if the FEF bit in
     %fprs has been set.  */

#define FPRS_FEF	(1 << 2)

  addr = cache->saved_regs[SPARC64_FPRS_REGNUM].addr;
  fprs = get_frame_memory_unsigned (next_frame, addr, 8);
  if (fprs & FPRS_FEF)
    {
      for (regnum = SPARC_F0_REGNUM, addr = mcontext_addr + 32 * 8;
	   regnum <= SPARC_F31_REGNUM; regnum++, addr += 4)
	cache->saved_regs[regnum].addr = addr;

      for (regnum = SPARC64_F32_REGNUM;
	   regnum <= SPARC64_F62_REGNUM; regnum++, addr += 8)
	cache->saved_regs[regnum].addr = addr;
    }

  return cache;
}