Beispiel #1
0
void
arm_linux_supply_gregset (const struct regset *regset,
			  struct regcache *regcache,
			  int regnum, const void *gregs_buf, size_t len)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  const gdb_byte *gregs = gregs_buf;
  int regno;
  CORE_ADDR reg_pc;
  gdb_byte pc_buf[INT_REGISTER_SIZE];

  for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
    if (regnum == -1 || regnum == regno)
      regcache_raw_supply (regcache, regno,
			   gregs + INT_REGISTER_SIZE * regno);

  if (regnum == ARM_PS_REGNUM || regnum == -1)
    {
      if (arm_apcs_32)
	regcache_raw_supply (regcache, ARM_PS_REGNUM,
			     gregs + INT_REGISTER_SIZE * ARM_CPSR_GREGNUM);
      else
	regcache_raw_supply (regcache, ARM_PS_REGNUM,
			     gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
    }

  if (regnum == ARM_PC_REGNUM || regnum == -1)
    {
      reg_pc = extract_unsigned_integer (gregs
					 + INT_REGISTER_SIZE * ARM_PC_REGNUM,
					 INT_REGISTER_SIZE, byte_order);
      reg_pc = gdbarch_addr_bits_remove (gdbarch, reg_pc);
      store_unsigned_integer (pc_buf, INT_REGISTER_SIZE, byte_order, reg_pc);
      regcache_raw_supply (regcache, ARM_PC_REGNUM, pc_buf);
    }
}
static void
ppcnbsd_store_inferior_registers (struct regcache *regcache, int regnum)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

  if (regnum == -1 || getregs_supplies (gdbarch, regnum))
    {
      struct reg regs;

      if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
	perror_with_name (_("Couldn't get registers"));

      ppc_collect_gregset (&ppcnbsd_gregset, regcache,
			   regnum, &regs, sizeof regs);

      if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
	perror_with_name (_("Couldn't write registers"));
    }

  if (regnum == -1 || getfpregs_supplies (gdbarch, regnum))
    {
      struct fpreg fpregs;

      if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't get FP registers"));

      ppc_collect_fpregset (&ppcnbsd_fpregset, regcache,
			    regnum, &fpregs, sizeof fpregs);

      if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't set FP registers"));
    }
}
Beispiel #3
0
static void
alphabsd_store_inferior_registers (struct target_ops *ops,
				   struct regcache *regcache, int regno)
{
  if (regno == -1 || getregs_supplies (regno))
    {
      struct reg gregs;
      if (ptrace (PT_GETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
                  (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
        perror_with_name (_("Couldn't get registers"));

      alphabsd_fill_reg (regcache, (char *) &gregs, regno);

      if (ptrace (PT_SETREGS, ptid_get_pid (regcache_get_ptid (regcache)),
                  (PTRACE_TYPE_ARG3) &gregs, 0) == -1)
        perror_with_name (_("Couldn't write registers"));

      if (regno != -1)
	return;
    }

  if (regno == -1
      || regno >= gdbarch_fp0_regnum (get_regcache_arch (regcache)))
    {
      struct fpreg fpregs;

      if (ptrace (PT_GETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't get floating point status"));

      alphabsd_fill_fpreg (regcache, (char *) &fpregs, regno);

      if (ptrace (PT_SETFPREGS, ptid_get_pid (regcache_get_ptid (regcache)),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't write floating point status"));
    }
}
Beispiel #4
0
static void
supply_vrregset (struct regcache *regcache, gdb_vrregset_t *vrregsetp)
{
  int i;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int num_of_vrregs = tdep->ppc_vrsave_regnum - tdep->ppc_vr0_regnum + 1;
  int vrregsize = register_size (gdbarch, tdep->ppc_vr0_regnum);
  int offset = vrregsize - register_size (gdbarch, tdep->ppc_vrsave_regnum);

  for (i = 0; i < num_of_vrregs; i++)
    {
      /* The last 2 registers of this set are only 32 bit long, not
         128.  However an offset is necessary only for VSCR because it
         occupies a whole vector, while VRSAVE occupies a full 4 bytes
         slot.  */
      if (i == (num_of_vrregs - 2))
        regcache_raw_supply (regcache, tdep->ppc_vr0_regnum + i,
			     *vrregsetp + i * vrregsize + offset);
      else
        regcache_raw_supply (regcache, tdep->ppc_vr0_regnum + i,
			     *vrregsetp + i * vrregsize);
    }
}
static void
ppc_linux_supply_gregset (const struct regset *regset,
			  struct regcache *regcache,
			  int regnum, const void *gregs, size_t len)
{
  const struct ppc_reg_offsets *offsets = regset->descr;

  ppc_supply_gregset (regset, regcache, regnum, gregs, len);

  if (ppc_linux_trap_reg_p (get_regcache_arch (regcache)))
    {
      /* "orig_r3" is stored 2 slots after "pc".  */
      if (regnum == -1 || regnum == PPC_ORIG_R3_REGNUM)
	ppc_supply_reg (regcache, PPC_ORIG_R3_REGNUM, gregs,
			offsets->pc_offset + 2 * offsets->gpr_size,
			offsets->gpr_size);

      /* "trap" is stored 8 slots after "pc".  */
      if (regnum == -1 || regnum == PPC_TRAP_REGNUM)
	ppc_supply_reg (regcache, PPC_TRAP_REGNUM, gregs,
			offsets->pc_offset + 8 * offsets->gpr_size,
			offsets->gpr_size);
    }
}
/* Write into appropriate registers a function return value of type
   TYPE, given in virtual format.  */
static void
lm32_store_return_value (struct type *type, struct regcache *regcache,
			 const gdb_byte *valbuf)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  ULONGEST val;
  int len = TYPE_LENGTH (type);

  if (len <= 4)
    {
      val = extract_unsigned_integer (valbuf, len, byte_order);
      regcache_cooked_write_unsigned (regcache, SIM_LM32_R1_REGNUM, val);
    }
  else if (len <= 8)
    {
      val = extract_unsigned_integer (valbuf, 4, byte_order);
      regcache_cooked_write_unsigned (regcache, SIM_LM32_R1_REGNUM, val);
      val = extract_unsigned_integer (valbuf + 4, len - 4, byte_order);
      regcache_cooked_write_unsigned (regcache, SIM_LM32_R2_REGNUM, val);
    }
  else
    error (_("lm32_store_return_value: type length too large."));
}
Beispiel #7
0
void
mips64_supply_gregset (struct regcache *regcache,
		       const mips64_elf_gregset_t *gregsetp)
{
  int regi;
  const mips64_elf_greg_t *regp = *gregsetp;
  gdb_byte zerobuf[MAX_REGISTER_SIZE];
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

  memset (zerobuf, 0, MAX_REGISTER_SIZE);

  for (regi = MIPS64_EF_REG0 + 1; regi <= MIPS64_EF_REG31; regi++)
    supply_64bit_reg (regcache, regi - MIPS64_EF_REG0,
		      (const gdb_byte *)(regp + regi));

  if (mips_linux_restart_reg_p (gdbarch))
    supply_64bit_reg (regcache, MIPS_RESTART_REGNUM,
		      (const gdb_byte *)(regp + MIPS64_EF_REG0));

  supply_64bit_reg (regcache, mips_regnum (gdbarch)->lo,
		    (const gdb_byte *) (regp + MIPS64_EF_LO));
  supply_64bit_reg (regcache, mips_regnum (gdbarch)->hi,
		    (const gdb_byte *) (regp + MIPS64_EF_HI));

  supply_64bit_reg (regcache, mips_regnum (gdbarch)->pc,
		    (const gdb_byte *) (regp + MIPS64_EF_CP0_EPC));
  supply_64bit_reg (regcache, mips_regnum (gdbarch)->badvaddr,
		    (const gdb_byte *) (regp + MIPS64_EF_CP0_BADVADDR));
  supply_64bit_reg (regcache, MIPS_PS_REGNUM,
		    (const gdb_byte *) (regp + MIPS64_EF_CP0_STATUS));
  supply_64bit_reg (regcache, mips_regnum (gdbarch)->cause,
		    (const gdb_byte *) (regp + MIPS64_EF_CP0_CAUSE));

  /* Fill the inaccessible zero register with zero.  */
  regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf);
}
Beispiel #8
0
static void
shnbsd_store_inferior_registers (struct target_ops *ops,
                                 struct regcache *regcache, int regno)
{
    if (regno == -1 || GETREGS_SUPPLIES (get_regcache_arch (regcache), regno))
    {
        struct reg inferior_registers;

        if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
                    (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
            perror_with_name (_("Couldn't get registers"));

        sh_corefile_collect_regset (&sh_corefile_gregset, regcache, regno,
                                    (char *) &inferior_registers,
                                    SHNBSD_SIZEOF_GREGS);

        if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
                    (PTRACE_TYPE_ARG3) &inferior_registers, 0) == -1)
            perror_with_name (_("Couldn't set registers"));

        if (regno != -1)
            return;
    }
}
Beispiel #9
0
void
fill_fpregset (const struct regcache *regcache, fpregset_t *fpregsetp, int regno)
{
  int regi;
  char *from, *to;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

  /* FIXME, this is wrong for the N32 ABI which has 64 bit FP regs. */

  for (regi = gdbarch_fp0_regnum (gdbarch);
       regi < gdbarch_fp0_regnum (gdbarch) + 32; regi++)
    {
      if ((regno == -1) || (regno == regi))
	{
	  to = (char *) &(fpregsetp->fp_r.fp_regs[regi - gdbarch_fp0_regnum
							 (gdbarch)]);
          regcache_raw_collect (regcache, regi, to);
	}
    }

  if (regno == -1
      || regno == mips_regnum (gdbarch)->fp_control_status)
    {
      char fsrbuf[8];

      /* We can't fill the FSR register directly from the regcache,
         because there is a size issue: On one hand, fpregsetp->fp_csr
         is 32bits long, while the regcache expects a 64bits long buffer.
         So we use a buffer of the correct size and copy the register
         value from that buffer.  */
      regcache_raw_collect (regcache,
			    mips_regnum (gdbarch)->fp_control_status, fsrbuf);

      memcpy (&fpregsetp->fp_csr, fsrbuf + 4, 4);
    }
}
Beispiel #10
0
/* The Linux kernel ptrace interface for POWER7 VSX registers uses the
   registers set mechanism, as opposed to the interface for all the
   other registers, that stores/fetches each register individually.  */
static void
fetch_vsx_register (struct regcache *regcache, int tid, int regno)
{
  int ret;
  gdb_vsxregset_t regs;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  int vsxregsize = register_size (gdbarch, tdep->ppc_vsr0_upper_regnum);

  ret = ptrace (PTRACE_GETVSXREGS, tid, 0, &regs);
  if (ret < 0)
    {
      if (errno == EIO)
	{
	  have_ptrace_getsetvsxregs = 0;
	  return;
	}
      perror_with_name (_("Unable to fetch VSX register"));
    }

  regcache_raw_supply (regcache, regno,
		       regs + (regno - tdep->ppc_vsr0_upper_regnum)
		       * vsxregsize);
}
void
mips_supply_fpregset (struct regcache *regcache,
		      const mips_elf_fpregset_t *fpregsetp)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int regi;
  char zerobuf[MAX_REGISTER_SIZE];

  memset (zerobuf, 0, MAX_REGISTER_SIZE);

  for (regi = 0; regi < 32; regi++)
    regcache_raw_supply (regcache,
			 gdbarch_fp0_regnum (gdbarch) + regi,
			 *fpregsetp + regi);

  regcache_raw_supply (regcache,
		       mips_regnum (gdbarch)->fp_control_status,
		       *fpregsetp + 32);

  /* FIXME: how can we supply FCRIR?  The ABI doesn't tell us.  */
  regcache_raw_supply (regcache,
		       mips_regnum (gdbarch)->fp_implementation_revision,
		       zerobuf);
}
Beispiel #12
0
static void
fetch_core_registers (struct regcache *regcache,
		      char *core_reg_sect, unsigned core_reg_size,
		      int which, CORE_ADDR reg_addr)
{
  char *srcp = core_reg_sect;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int regsize = mips_isa_regsize (gdbarch);
  int regno;

  /* If regsize is 8, this is a N32 or N64 core file.
     If regsize is 4, this is an O32 core file.  */
  if (core_reg_size != regsize * gdbarch_num_regs (gdbarch))
    {
      warning (_("wrong size gregset struct in core file"));
      return;
    }

  for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
    {
      regcache_raw_supply (regcache, regno, srcp);
      srcp += regsize;
    }
}
static void
mipsnbsd_supply_gregset (const struct regset *regset,
			 struct regcache *regcache, int regnum,
			 const void *gregs, size_t len)
{
  size_t regsize = mips_isa_regsize (get_regcache_arch (regcache));
  const char *regs = gregs;
  int i;

  gdb_assert (len >= MIPSNBSD_NUM_GREGS * regsize);

  for (i = 0; i <= MIPS_PC_REGNUM; i++)
    {
      if (regnum == i || regnum == -1)
	regcache_raw_supply (regcache, i, regs + i * regsize);
    }

  if (len >= (MIPSNBSD_NUM_GREGS + MIPSNBSD_NUM_FPREGS) * regsize)
    {
      regs += MIPSNBSD_NUM_GREGS * regsize;
      len -= MIPSNBSD_NUM_GREGS * regsize;
      mipsnbsd_supply_fpregset (regset, regcache, regnum, regs, len);
    }
}
Beispiel #14
0
static void
fetch_register (struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  pid_t tid;
  int val;

  if (gdbarch_cannot_fetch_register (gdbarch, regno))
    {
      regcache_raw_supply (regcache, regno, NULL);
      return;
    }

  tid = get_ptrace_pid (regcache_get_ptid (regcache));

  errno = 0;
  val = ptrace (PTRACE_PEEKUSER, tid, hppa_linux_register_addr (regno, 0), 0);
  if (errno != 0)
    error (_("Couldn't read register %s (#%d): %s."), 
	   gdbarch_register_name (gdbarch, regno),
	   regno, safe_strerror (errno));

  regcache_raw_supply (regcache, regno, &val);
}
static int
ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  struct switchframe sf;
  struct callframe cf;
  int i, regnum;

  /* The following is true for OpenBSD 3.7:

     The pcb contains %r1 (the stack pointer) at the point of the
     context switch in cpu_switch().  At that point we have a stack
     frame as described by `struct switchframe', and below that a call
     frame as described by `struct callframe'.  From this information
     we reconstruct the register state as it would look when we are in
     cpu_switch().  */

  /* The stack pointer shouldn't be zero.  */
  if (pcb->pcb_sp == 0)
    return 0;

  read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
  regcache_raw_supply (regcache, gdbarch_sp_regnum (gdbarch), &sf.sp);
  regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
  for (i = 0, regnum = tdep->ppc_gp0_regnum + 13; i < 19; i++, regnum++)
    regcache_raw_supply (regcache, regnum, &sf.fixreg[i]);

  read_memory (sf.sp, (gdb_byte *)&cf, sizeof cf);
  regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);

  return 1;
}
static void
store_register (const struct regcache *regcache, int regno)
{
  int tid;
  int val;

  gdb_assert (!have_ptrace_getregs);
  if (i386_linux_gregset_reg_offset[regno] == -1)
    return;

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = ptid_get_lwp (inferior_ptid);
  if (tid == 0)
    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */

  errno = 0;
  regcache_raw_collect (regcache, regno, &val);
  ptrace (PTRACE_POKEUSER, tid,
	  i386_linux_gregset_reg_offset[regno], val);
  if (errno != 0)
    error (_("Couldn't write register %s (#%d): %s."),
	   gdbarch_register_name (get_regcache_arch (regcache), regno),
	   regno, safe_strerror (errno));
}
static int
picobug_dumpregs (struct regcache *regcache)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  char buf[1024];
  int resp_len;
  char *p;

  /* Send the dump register command to the monitor and
     get the reply.  */
  monitor_printf (picobug_cmds.dump_registers);
  resp_len = monitor_expect_prompt (buf, sizeof (buf));

  p = strtok (buf, " \t\r\n");
  while (p)
    {
      if (strchr (p, '-'))
	{
	  /* Got a range.  Either r0-r7, r8-r15 or ss0-ss4.  */
	  if (strncmp (p, "r0", 2) == 0 || strncmp (p, "r8", 2) == 0)
	    {
	      int rn = (p[1] == '0' ? 0 : 8);
	      int i = 0;

	      /* Get the next 8 values and record them.  */
	      while (i < 8)
		{
		  p = strtok (NULL, " \t\r\n");
		  if (p)
		    monitor_supply_register (regcache, rn + i, p);
		  i++;
		}
	    }
	  else if (strncmp (p, "ss", 2) == 0)
	    {
	      /* Get the next five values, ignoring the first.  */
	      int rn;
	      p = strtok (NULL, " \t\r\n");
	      for (rn = 39; rn < 43; rn++)
		{
		  p = strtok (NULL, " \t\r\n");
		  if (p)
		    monitor_supply_register (regcache, rn, p);
		}
	    }
	  else
	    {
	      break;
	    }
	}
      else
	{
	  /* Simple register type, paired.  */
	  char *name = p;
	  int i;

	  /* Get and record value.  */
	  p = strtok (NULL, " \t\r\n");
	  if (p)
	    {
	      for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
		{
		  if (picobug_regnames[i]
		      && strcmp (picobug_regnames[i], name) == 0)
		    break;
		}

	      if (i <= gdbarch_num_regs (gdbarch))
		monitor_supply_register (regcache, i, p);
	    }
	}
      p = strtok (NULL, " \t\r\n");
    }

  return 0;
}
/* Read register values from the inferior process.
   If REGNO is -1, do this for all registers.
   Otherwise, REGNO specifies which register (so we can save time).  */
static void
i386_darwin_fetch_inferior_registers (struct target_ops *ops,
				      struct regcache *regcache, int regno)
{
  thread_t current_thread = ptid_get_tid (inferior_ptid);
  int fetched = 0;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

#ifdef BFD64
  if (gdbarch_ptr_bit (gdbarch) == 64)
    {
      if (regno == -1 || amd64_native_gregset_supplies_p (gdbarch, regno))
        {
          x86_thread_state_t gp_regs;
          unsigned int gp_count = x86_THREAD_STATE_COUNT;
          kern_return_t ret;

	  ret = thread_get_state
            (current_thread, x86_THREAD_STATE, (thread_state_t) & gp_regs,
             &gp_count);
	  if (ret != KERN_SUCCESS)
	    {
	      printf_unfiltered (_("Error calling thread_get_state for "
				   "GP registers for thread 0x%ulx"),
				 current_thread);
	      MACH_CHECK_ERROR (ret);
	    }
	  amd64_supply_native_gregset (regcache, &gp_regs.uts, -1);
          fetched++;
        }

      if (regno == -1 || !amd64_native_gregset_supplies_p (gdbarch, regno))
        {
          x86_float_state_t fp_regs;
          unsigned int fp_count = x86_FLOAT_STATE_COUNT;
          kern_return_t ret;

	  ret = thread_get_state
            (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs,
             &fp_count);
	  if (ret != KERN_SUCCESS)
	    {
	      printf_unfiltered (_("Error calling thread_get_state for "
				   "float registers for thread 0x%ulx"),
				 current_thread);
	      MACH_CHECK_ERROR (ret);
	    }
          amd64_supply_fxsave (regcache, -1, &fp_regs.ufs.fs64.__fpu_fcw);
          fetched++;
        }
    }
  else
#endif
    {
      if (regno == -1 || regno < I386_NUM_GREGS)
        {
          i386_thread_state_t gp_regs;
          unsigned int gp_count = i386_THREAD_STATE_COUNT;
          kern_return_t ret;
	  int i;

	  ret = thread_get_state
            (current_thread, i386_THREAD_STATE, (thread_state_t) & gp_regs,
             &gp_count);
	  if (ret != KERN_SUCCESS)
	    {
	      printf_unfiltered (_("Error calling thread_get_state for "
				   "GP registers for thread 0x%ulx"),
				 current_thread);
	      MACH_CHECK_ERROR (ret);
	    }
	  for (i = 0; i < I386_NUM_GREGS; i++)
	    regcache_raw_supply
	      (regcache, i,
	       (char *)&gp_regs + i386_darwin_thread_state_reg_offset[i]);

          fetched++;
        }

      if (regno == -1
	  || (regno >= I386_ST0_REGNUM && regno < I386_SSE_NUM_REGS))
        {
          i386_float_state_t fp_regs;
          unsigned int fp_count = i386_FLOAT_STATE_COUNT;
          kern_return_t ret;

	  ret = thread_get_state
            (current_thread, i386_FLOAT_STATE, (thread_state_t) & fp_regs,
             &fp_count);
	  if (ret != KERN_SUCCESS)
	    {
	      printf_unfiltered (_("Error calling thread_get_state for "
				   "float registers for thread 0x%ulx"),
				 current_thread);
	      MACH_CHECK_ERROR (ret);
	    }
          i387_supply_fxsave (regcache, -1, &fp_regs.__fpu_fcw);
          fetched++;
        }
    }

  if (! fetched)
    {
      warning (_("unknown register %d"), regno);
      regcache_raw_supply (regcache, regno, NULL);
    }
}
static void
i386_darwin_store_inferior_registers (struct target_ops *ops,
				      struct regcache *regcache, int regno)
{
  thread_t current_thread = ptid_get_tid (inferior_ptid);
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

#ifdef BFD64
  if (gdbarch_ptr_bit (gdbarch) == 64)
    {
      if (regno == -1 || amd64_native_gregset_supplies_p (gdbarch, regno))
        {
          x86_thread_state_t gp_regs;
          kern_return_t ret;
	  unsigned int gp_count = x86_THREAD_STATE_COUNT;

	  ret = thread_get_state
	    (current_thread, x86_THREAD_STATE, (thread_state_t) &gp_regs,
	     &gp_count);
          MACH_CHECK_ERROR (ret);
	  gdb_assert (gp_regs.tsh.flavor == x86_THREAD_STATE64);
          gdb_assert (gp_regs.tsh.count == x86_THREAD_STATE64_COUNT);

	  amd64_collect_native_gregset (regcache, &gp_regs.uts, regno);

          ret = thread_set_state (current_thread, x86_THREAD_STATE,
                                  (thread_state_t) &gp_regs,
                                  x86_THREAD_STATE_COUNT);
          MACH_CHECK_ERROR (ret);
        }

      if (regno == -1 || !amd64_native_gregset_supplies_p (gdbarch, regno))
        {
          x86_float_state_t fp_regs;
          kern_return_t ret;
	  unsigned int fp_count = x86_FLOAT_STATE_COUNT;

	  ret = thread_get_state
	    (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs,
	     &fp_count);
          MACH_CHECK_ERROR (ret);
          gdb_assert (fp_regs.fsh.flavor == x86_FLOAT_STATE64);
          gdb_assert (fp_regs.fsh.count == x86_FLOAT_STATE64_COUNT);

	  amd64_collect_fxsave (regcache, regno, &fp_regs.ufs.fs64.__fpu_fcw);

	  ret = thread_set_state (current_thread, x86_FLOAT_STATE,
				  (thread_state_t) & fp_regs,
				  x86_FLOAT_STATE_COUNT);
	  MACH_CHECK_ERROR (ret);
        }
    }
  else
#endif
    {
      if (regno == -1 || regno < I386_NUM_GREGS)
        {
          i386_thread_state_t gp_regs;
          kern_return_t ret;
          unsigned int gp_count = i386_THREAD_STATE_COUNT;
	  int i;

          ret = thread_get_state
            (current_thread, i386_THREAD_STATE, (thread_state_t) & gp_regs,
             &gp_count);
	  MACH_CHECK_ERROR (ret);

	  for (i = 0; i < I386_NUM_GREGS; i++)
	    if (regno == -1 || regno == i)
	      regcache_raw_collect
		(regcache, i,
		 (char *)&gp_regs + i386_darwin_thread_state_reg_offset[i]);

          ret = thread_set_state (current_thread, i386_THREAD_STATE,
                                  (thread_state_t) & gp_regs,
                                  i386_THREAD_STATE_COUNT);
          MACH_CHECK_ERROR (ret);
        }

      if (regno == -1
	  || (regno >= I386_ST0_REGNUM && regno < I386_SSE_NUM_REGS))
        {
          i386_float_state_t fp_regs;
          unsigned int fp_count = i386_FLOAT_STATE_COUNT;
          kern_return_t ret;

	  ret = thread_get_state
            (current_thread, i386_FLOAT_STATE, (thread_state_t) & fp_regs,
             &fp_count);
	  MACH_CHECK_ERROR (ret);

	  i387_collect_fxsave (regcache, regno, &fp_regs.__fpu_fcw);

	  ret = thread_set_state (current_thread, i386_FLOAT_STATE,
				  (thread_state_t) & fp_regs,
				  i386_FLOAT_STATE_COUNT);
	  MACH_CHECK_ERROR (ret);
        }
    }
}
/* Store at least register REGNO, or all regs if REGNO == -1.  */
static void
gnu_store_registers (struct target_ops *ops,
		     struct regcache *regcache, int regno)
{
  struct proc *thread;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

  /* Make sure we know about new threads.  */
  inf_update_procs (gnu_current_inf);

  thread = inf_tid_to_thread (gnu_current_inf,
			      ptid_get_tid (inferior_ptid));
  if (!thread)
    error (_("Couldn't store registers into thread %s: No such thread"),
	   target_pid_to_str (inferior_ptid));

  if (regno < I386_NUM_GREGS || regno == -1)
    {
      thread_state_t state;
      thread_state_data_t old_state;
      int was_aborted = thread->aborted;
      int was_valid = thread->state_valid;
      int trace;

      if (!was_aborted && was_valid)
	memcpy (&old_state, &thread->state, sizeof (old_state));

      state = proc_get_state (thread, 1);
      if (!state)
	{
	  warning (_("Couldn't store registers into %s"), proc_string (thread));
	  return;
	}

      /* Save the T bit.  We might try to restore the %eflags register
         below, but changing the T bit would seriously confuse GDB.  */
      trace = ((struct i386_thread_state *)state)->efl & 0x100;

      if (!was_aborted && was_valid)
	/* See which registers have changed after aborting the thread.  */
	{
	  int check_regno;

	  for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++)
	    if ((thread->fetched_regs & (1 << check_regno))
		&& memcpy (REG_ADDR (&old_state, check_regno),
			   REG_ADDR (state, check_regno),
			   register_size (gdbarch, check_regno)))
	      /* Register CHECK_REGNO has changed!  Ack!  */
	      {
		warning (_("Register %s changed after the thread was aborted"),
			 gdbarch_register_name (gdbarch, check_regno));
		if (regno >= 0 && regno != check_regno)
		  /* Update GDB's copy of the register.  */
		  regcache_raw_supply (regcache, check_regno,
				       REG_ADDR (state, check_regno));
		else
		  warning (_("... also writing this register!  Suspicious..."));
	      }
	}

      if (regno == -1)
	{
	  int i;

	  proc_debug (thread, "storing all registers");

	  for (i = 0; i < I386_NUM_GREGS; i++)
	    if (regcache_valid_p (regcache, i))
	      regcache_raw_collect (regcache, i, REG_ADDR (state, i));
	}
      else
	{
	  proc_debug (thread, "storing register %s",
		      gdbarch_register_name (gdbarch, regno));

	  gdb_assert (regcache_valid_p (regcache, regno));
	  regcache_raw_collect (regcache, regno, REG_ADDR (state, regno));
	}

      /* Restore the T bit.  */
      ((struct i386_thread_state *)state)->efl &= ~0x100;
      ((struct i386_thread_state *)state)->efl |= trace;
    }

  if (regno >= I386_NUM_GREGS || regno == -1)
    {
      proc_debug (thread, "storing floating-point registers");

      store_fpregs (regcache, thread, regno);
    }
}
void
mips64_fill_fpregset (const struct regcache *regcache,
		      mips64_elf_fpregset_t *fpregsetp, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte *to;

  if ((regno >= gdbarch_fp0_regnum (gdbarch))
      && (regno < gdbarch_fp0_regnum (gdbarch) + 32))
    {
      /* See mips_linux_o32_sigframe_init for a description of the
	 peculiar FP register layout.  */
      if (register_size (gdbarch, regno) == 4)
	{
	  int regi = regno - gdbarch_fp0_regnum (gdbarch);

	  to = (gdb_byte *) (*fpregsetp + (regi & ~1));
	  if ((gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) != (regi & 1))
	    to += 4;
	  regcache_raw_collect (regcache, regno, to);
	}
      else
	{
	  to = (gdb_byte *) (*fpregsetp + regno - gdbarch_fp0_regnum (gdbarch));
	  regcache_raw_collect (regcache, regno, to);
	}
    }
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
    {
      gdb_byte buf[MAX_REGISTER_SIZE];
      LONGEST val;

      regcache_raw_collect (regcache, regno, buf);
      val = extract_signed_integer (buf, register_size (gdbarch, regno),
				    byte_order);
      to = (gdb_byte *) (*fpregsetp + 32);
      store_signed_integer (to, 4, byte_order, val);
    }
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
    {
      gdb_byte buf[MAX_REGISTER_SIZE];
      LONGEST val;

      regcache_raw_collect (regcache, regno, buf);
      val = extract_signed_integer (buf, register_size (gdbarch, regno),
				    byte_order);
      to = (gdb_byte *) (*fpregsetp + 32) + 4;
      store_signed_integer (to, 4, byte_order, val);
    }
  else if (regno == -1)
    {
      int regi;

      for (regi = 0; regi < 32; regi++)
	mips64_fill_fpregset (regcache, fpregsetp,
			      gdbarch_fp0_regnum (gdbarch) + regi);
      mips64_fill_fpregset (regcache, fpregsetp,
			    mips_regnum (gdbarch)->fp_control_status);
      mips64_fill_fpregset (regcache, fpregsetp,
			    (mips_regnum (gdbarch)
			      ->fp_implementation_revision));
    }
}
static void
i386_linux_fetch_inferior_registers (struct target_ops *ops,
				     struct regcache *regcache, int regno)
{
  int tid;

  /* Use the old method of peeking around in `struct user' if the
     GETREGS request isn't available.  */
  if (!have_ptrace_getregs)
    {
      int i;

      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
	if (regno == -1 || regno == i)
	  fetch_register (regcache, i);

      return;
    }

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = ptid_get_lwp (inferior_ptid);
  if (tid == 0)
    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */

  /* Use the PTRACE_GETFPXREGS request whenever possible, since it
     transfers more registers in one system call, and we'll cache the
     results.  But remember that fetch_fpxregs can fail, and return
     zero.  */
  if (regno == -1)
    {
      fetch_regs (regcache, tid);

      /* The call above might reset `have_ptrace_getregs'.  */
      if (!have_ptrace_getregs)
	{
	  i386_linux_fetch_inferior_registers (ops, regcache, regno);
	  return;
	}

      if (fetch_xstateregs (regcache, tid))
	return;
      if (fetch_fpxregs (regcache, tid))
	return;
      fetch_fpregs (regcache, tid);
      return;
    }

  if (GETREGS_SUPPLIES (regno))
    {
      fetch_regs (regcache, tid);
      return;
    }

  if (GETXSTATEREGS_SUPPLIES (regno))
    {
      if (fetch_xstateregs (regcache, tid))
	return;
    }

  if (GETFPXREGS_SUPPLIES (regno))
    {
      if (fetch_fpxregs (regcache, tid))
	return;

      /* Either our processor or our kernel doesn't support the SSE
	 registers, so read the FP registers in the traditional way,
	 and fill the SSE registers with dummy values.  It would be
	 more graceful to handle differences in the register set using
	 gdbarch.  Until then, this will at least make things work
	 plausibly.  */
      fetch_fpregs (regcache, tid);
      return;
    }

  internal_error (__FILE__, __LINE__,
		  _("Got request for bad register number %d."), regno);
}
Beispiel #23
0
static CORE_ADDR
m88k_store_arguments (struct regcache *regcache, int nargs,
		      struct value **args, CORE_ADDR sp)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int num_register_words = 0;
  int num_stack_words = 0;
  int i;

  for (i = 0; i < nargs; i++)
    {
      struct type *type = value_type (args[i]);
      int len = TYPE_LENGTH (type);

      if (m88k_integral_or_pointer_p (type) && len < 4)
	{
	  args[i] = value_cast (builtin_type (gdbarch)->builtin_int32,
				args[i]);
	  type = value_type (args[i]);
	  len = TYPE_LENGTH (type);
	}

      if (m88k_in_register_p (type))
	{
	  int num_words = 0;

	  if (num_register_words % 2 == 1 && m88k_8_byte_align_p (type))
	    num_words++;

	  num_words += ((len + 3) / 4);
	  if (num_register_words + num_words <= 8)
	    {
	      num_register_words += num_words;
	      continue;
	    }

	  /* We've run out of available registers.  Pass the argument
             on the stack.  */
	}

      if (num_stack_words % 2 == 1 && m88k_8_byte_align_p (type))
	num_stack_words++;

      num_stack_words += ((len + 3) / 4);
    }

  /* Allocate stack space.  */
  sp = align_down (sp - 32 - num_stack_words * 4, 16);
  num_stack_words = num_register_words = 0;

  for (i = 0; i < nargs; i++)
    {
      const bfd_byte *valbuf = value_contents (args[i]);
      struct type *type = value_type (args[i]);
      int len = TYPE_LENGTH (type);
      int stack_word = num_stack_words;

      if (m88k_in_register_p (type))
	{
	  int register_word = num_register_words;

	  if (register_word % 2 == 1 && m88k_8_byte_align_p (type))
	    register_word++;

	  gdb_assert (len == 4 || len == 8);

	  if (register_word + len / 8 < 8)
	    {
	      int regnum = M88K_R2_REGNUM + register_word;

	      regcache_raw_write (regcache, regnum, valbuf);
	      if (len > 4)
		regcache_raw_write (regcache, regnum + 1, valbuf + 4);

	      num_register_words = (register_word + len / 4);
	      continue;
	    }
	}

      if (stack_word % 2 == -1 && m88k_8_byte_align_p (type))
	stack_word++;

      write_memory (sp + stack_word * 4, valbuf, len);
      num_stack_words = (stack_word + (len + 3) / 4);
    }

  return sp;
}
Beispiel #24
0
static void
store_register (struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int addr[MAX_REGISTER_SIZE];
  int nr, isfloat;

  /* Fetch the register's value from the register cache.  */
  regcache_raw_collect (regcache, regno, addr);

  /* -1 can be a successful return value, so infer errors from errno. */
  errno = 0;

  nr = regmap (gdbarch, regno, &isfloat);

  /* Floating-point registers. */
  if (isfloat)
    rs6000_ptrace32 (PT_WRITE_FPR, PIDGET (inferior_ptid), addr, nr, 0);

  /* Bogus register number. */
  else if (nr < 0)
    {
      if (regno >= gdbarch_num_regs (gdbarch))
	fprintf_unfiltered (gdb_stderr,
			    "gdb error: register no %d not implemented.\n",
			    regno);
    }

  /* Fixed-point registers. */
  else
    {
      if (regno == gdbarch_sp_regnum (gdbarch))
	/* Execute one dummy instruction (which is a breakpoint) in inferior
	   process to give kernel a chance to do internal housekeeping.
	   Otherwise the following ptrace(2) calls will mess up user stack
	   since kernel will get confused about the bottom of the stack
	   (%sp). */
	exec_one_dummy_insn (regcache);

      /* The PT_WRITE_GPR operation is rather odd.  For 32-bit inferiors,
         the register's value is passed by value, but for 64-bit inferiors,
	 the address of a buffer containing the value is passed.  */
      if (!ARCH64 ())
	rs6000_ptrace32 (PT_WRITE_GPR, PIDGET (inferior_ptid), (int *)nr, *addr, 0);
      else
	{
	  /* PT_WRITE_GPR requires the buffer parameter to point to an 8-byte
	     area, even if the register is really only 32 bits. */
	  long long buf;
	  if (register_size (gdbarch, regno) == 8)
	    memcpy (&buf, addr, 8);
	  else
	    buf = *addr;
	  rs6000_ptrace64 (PT_WRITE_GPR, PIDGET (inferior_ptid), nr, 0, &buf);
	}
    }

  if (errno)
    {
      perror ("ptrace write");
      errno = 0;
    }
}
Beispiel #25
0
static void
amd64_linux_store_inferior_registers (struct target_ops *ops,
				      struct regcache *regcache, int regnum)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int tid;

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = ptid_get_lwp (inferior_ptid);
  if (tid == 0)
    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */

  if (regnum == -1 || amd64_native_gregset_supplies_p (gdbarch, regnum))
    {
      elf_gregset_t regs;

      if (ptrace (PTRACE_GETREGS, tid, 0, (long) &regs) < 0)
	perror_with_name (_("Couldn't get registers"));

      amd64_collect_native_gregset (regcache, &regs, regnum);

      if (ptrace (PTRACE_SETREGS, tid, 0, (long) &regs) < 0)
	perror_with_name (_("Couldn't write registers"));

      if (regnum != -1)
	return;
    }

  if (regnum == -1 || !amd64_native_gregset_supplies_p (gdbarch, regnum))
    {
      elf_fpregset_t fpregs;

      if (have_ptrace_getregset)
	{
	  char xstateregs[I386_XSTATE_MAX_SIZE];
	  struct iovec iov;

	  iov.iov_base = xstateregs;
	  iov.iov_len = sizeof (xstateregs);
	  if (ptrace (PTRACE_GETREGSET, tid,
		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
	    perror_with_name (_("Couldn't get extended state status"));

	  amd64_collect_xsave (regcache, regnum, xstateregs, 0);

	  if (ptrace (PTRACE_SETREGSET, tid,
		      (unsigned int) NT_X86_XSTATE, (long) &iov) < 0)
	    perror_with_name (_("Couldn't write extended state status"));
	}
      else
	{
	  if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0)
	    perror_with_name (_("Couldn't get floating point status"));

	  amd64_collect_fxsave (regcache, regnum, &fpregs);

	  if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0)
	    perror_with_name (_("Couldn't write floating point status"));
	}
    }
}
static void
i386_linux_resume (struct target_ops *ops,
		   ptid_t ptid, int step, enum gdb_signal signal)
{
  int pid = ptid_get_pid (ptid);

  int request;

  if (catch_syscall_enabled () > 0)
   request = PTRACE_SYSCALL;
  else
    request = PTRACE_CONT;

  if (step)
    {
      struct regcache *regcache = get_thread_regcache (pid_to_ptid (pid));
      struct gdbarch *gdbarch = get_regcache_arch (regcache);
      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
      ULONGEST pc;
      gdb_byte buf[LINUX_SYSCALL_LEN];

      request = PTRACE_SINGLESTEP;

      regcache_cooked_read_unsigned (regcache,
				     gdbarch_pc_regnum (gdbarch), &pc);

      /* Returning from a signal trampoline is done by calling a
         special system call (sigreturn or rt_sigreturn, see
         i386-linux-tdep.c for more information).  This system call
         restores the registers that were saved when the signal was
         raised, including %eflags.  That means that single-stepping
         won't work.  Instead, we'll have to modify the signal context
         that's about to be restored, and set the trace flag there.  */

      /* First check if PC is at a system call.  */
      if (target_read_memory (pc, buf, LINUX_SYSCALL_LEN) == 0
	  && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0)
	{
	  ULONGEST syscall;
	  regcache_cooked_read_unsigned (regcache,
					 LINUX_SYSCALL_REGNUM, &syscall);

	  /* Then check the system call number.  */
	  if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn)
	    {
	      ULONGEST sp, addr;
	      unsigned long int eflags;

	      regcache_cooked_read_unsigned (regcache, I386_ESP_REGNUM, &sp);
	      if (syscall == SYS_rt_sigreturn)
		addr = read_memory_unsigned_integer (sp + 8, 4, byte_order)
		  + 20;
	      else
		addr = sp;

	      /* Set the trace flag in the context that's about to be
                 restored.  */
	      addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET;
	      read_memory (addr, (gdb_byte *) &eflags, 4);
	      eflags |= 0x0100;
	      write_memory (addr, (gdb_byte *) &eflags, 4);
	    }
	}
    }

  if (ptrace (request, pid, 0, gdb_signal_to_host (signal)) == -1)
    perror_with_name (("ptrace"));
}
Beispiel #27
0
void
sparc_store_inferior_registers (struct target_ops *ops,
				struct regcache *regcache, int regnum)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int pid;

  /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers
     about threaded assumptions.  */
  pid = TIDGET (inferior_ptid);
  if (pid == 0)
    pid = PIDGET (inferior_ptid);

  if (regnum == -1 || sparc_gregset_supplies_p (gdbarch, regnum))
    {
      gregset_t regs;

      if (ptrace (PTRACE_GETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
	perror_with_name (_("Couldn't get registers"));

      sparc_collect_gregset (sparc_gregset, regcache, regnum, &regs);

      if (ptrace (PTRACE_SETREGS, pid, (PTRACE_TYPE_ARG3) &regs, 0) == -1)
	perror_with_name (_("Couldn't write registers"));

      /* Deal with the stack regs.  */
      if (regnum == -1 || regnum == SPARC_SP_REGNUM
	  || (regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM))
	{
	  ULONGEST sp;

	  regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, &sp);
	  sparc_collect_rwindow (regcache, sp, regnum);
	}

      if (regnum != -1)
	return;
    }

  if (regnum == -1 || sparc_fpregset_supplies_p (gdbarch, regnum))
    {
      fpregset_t fpregs, saved_fpregs;

      if (ptrace (PTRACE_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't get floating-point registers"));

      memcpy (&saved_fpregs, &fpregs, sizeof (fpregs));
      sparc_collect_fpregset (regcache, regnum, &fpregs);

      /* Writing the floating-point registers will fail on NetBSD with
	 EINVAL if the inferior process doesn't have an FPU state
	 (i.e. if it didn't use the FPU yet).  Therefore we don't try
	 to write the registers if nothing changed.  */
      if (memcmp (&saved_fpregs, &fpregs, sizeof (fpregs)) != 0)
	{
	  if (ptrace (PTRACE_SETFPREGS, pid,
		      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	    perror_with_name (_("Couldn't write floating-point registers"));
	}

      if (regnum != -1)
	return;
    }
}
Beispiel #28
0
static void
ia64_linux_fetch_register (struct regcache *regcache, int regnum)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  CORE_ADDR addr;
  size_t size;
  PTRACE_TYPE_RET *buf;
  int pid, i;

  /* r0 cannot be fetched but is always zero.  */
  if (regnum == IA64_GR0_REGNUM)
    {
      const gdb_byte zero[8] = { 0 };

      gdb_assert (sizeof (zero) == register_size (gdbarch, regnum));
      regcache_raw_supply (regcache, regnum, zero);
      return;
    }

  /* fr0 cannot be fetched but is always zero.  */
  if (regnum == IA64_FR0_REGNUM)
    {
      const gdb_byte f_zero[16] = { 0 };

      gdb_assert (sizeof (f_zero) == register_size (gdbarch, regnum));
      regcache_raw_supply (regcache, regnum, f_zero);
      return;
    }

  /* fr1 cannot be fetched but is always one (1.0).  */
  if (regnum == IA64_FR1_REGNUM)
    {
      const gdb_byte f_one[16] =
	{ 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0 };

      gdb_assert (sizeof (f_one) == register_size (gdbarch, regnum));
      regcache_raw_supply (regcache, regnum, f_one);
      return;
    }

  if (ia64_cannot_fetch_register (gdbarch, regnum))
    {
      regcache_raw_supply (regcache, regnum, NULL);
      return;
    }

  /* Cater for systems like GNU/Linux, that implement threads as
     separate processes.  */
  pid = ptid_get_lwp (inferior_ptid);
  if (pid == 0)
    pid = ptid_get_pid (inferior_ptid);

  /* This isn't really an address, but ptrace thinks of it as one.  */
  addr = ia64_register_addr (gdbarch, regnum);
  size = register_size (gdbarch, regnum);

  gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
  buf = alloca (size);

  /* Read the register contents from the inferior a chunk at a time.  */
  for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
    {
      errno = 0;
      buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)addr, 0);
      if (errno != 0)
	error (_("Couldn't read register %s (#%d): %s."),
	       gdbarch_register_name (gdbarch, regnum),
	       regnum, safe_strerror (errno));

      addr += sizeof (PTRACE_TYPE_RET);
    }
  regcache_raw_supply (regcache, regnum, buf);
}
/* Store register REGNO back into the child process.  If REGNO is -1,
   do this for all registers (including the floating point and SSE
   registers).  */
static void
i386_linux_store_inferior_registers (struct target_ops *ops,
				     struct regcache *regcache, int regno)
{
  int tid;

  /* Use the old method of poking around in `struct user' if the
     SETREGS request isn't available.  */
  if (!have_ptrace_getregs)
    {
      int i;

      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
	if (regno == -1 || regno == i)
	  store_register (regcache, i);

      return;
    }

  /* GNU/Linux LWP ID's are process ID's.  */
  tid = ptid_get_lwp (inferior_ptid);
  if (tid == 0)
    tid = ptid_get_pid (inferior_ptid); /* Not a threaded program.  */

  /* Use the PTRACE_SETFPXREGS requests whenever possible, since it
     transfers more registers in one system call.  But remember that
     store_fpxregs can fail, and return zero.  */
  if (regno == -1)
    {
      store_regs (regcache, tid, regno);
      if (store_xstateregs (regcache, tid, regno))
	return;
      if (store_fpxregs (regcache, tid, regno))
	return;
      store_fpregs (regcache, tid, regno);
      return;
    }

  if (GETREGS_SUPPLIES (regno))
    {
      store_regs (regcache, tid, regno);
      return;
    }

  if (GETXSTATEREGS_SUPPLIES (regno))
    {
      if (store_xstateregs (regcache, tid, regno))
	return;
    }

  if (GETFPXREGS_SUPPLIES (regno))
    {
      if (store_fpxregs (regcache, tid, regno))
	return;

      /* Either our processor or our kernel doesn't support the SSE
	 registers, so just write the FP registers in the traditional
	 way.  */
      store_fpregs (regcache, tid, regno);
      return;
    }

  internal_error (__FILE__, __LINE__,
		  _("Got request to store bad register number %d."), regno);
}
Beispiel #30
0
static void
store_register (const struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct reg inferior_registers;
  int ret;

  ret = ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
		(PTRACE_TYPE_ARG3) &inferior_registers, 0);

  if (ret < 0)
    {
      warning (_("unable to fetch general registers"));
      return;
    }

  switch (regno)
    {
    case ARM_SP_REGNUM:
      regcache_raw_collect (regcache, ARM_SP_REGNUM,
			    (char *) &inferior_registers.r_sp);
      break;

    case ARM_LR_REGNUM:
      regcache_raw_collect (regcache, ARM_LR_REGNUM,
			    (char *) &inferior_registers.r_lr);
      break;

    case ARM_PC_REGNUM:
      if (arm_apcs_32)
	regcache_raw_collect (regcache, ARM_PC_REGNUM,
			      (char *) &inferior_registers.r_pc);
      else
	{
	  unsigned pc_val;

	  regcache_raw_collect (regcache, ARM_PC_REGNUM,
				(char *) &pc_val);
	  
	  pc_val = gdbarch_addr_bits_remove (gdbarch, pc_val);
	  inferior_registers.r_pc ^= gdbarch_addr_bits_remove
				       (gdbarch, inferior_registers.r_pc);
	  inferior_registers.r_pc |= pc_val;
	}
      break;

    case ARM_PS_REGNUM:
      if (arm_apcs_32)
	regcache_raw_collect (regcache, ARM_PS_REGNUM,
			      (char *) &inferior_registers.r_cpsr);
      else
	{
	  unsigned psr_val;

	  regcache_raw_collect (regcache, ARM_PS_REGNUM,
				(char *) &psr_val);

	  psr_val ^= gdbarch_addr_bits_remove (gdbarch, psr_val);
	  inferior_registers.r_pc = gdbarch_addr_bits_remove
				      (gdbarch, inferior_registers.r_pc);
	  inferior_registers.r_pc |= psr_val;
	}
      break;

    default:
      regcache_raw_collect (regcache, regno,
			    (char *) &inferior_registers.r[regno]);
      break;
    }

  ret = ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
		(PTRACE_TYPE_ARG3) &inferior_registers, 0);

  if (ret < 0)
    warning (_("unable to write register %d to inferior"), regno);
}