static void 
fetch_ppc_registers (int tid)
{
  int i;
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);

  for (i = 0; i < ppc_num_gprs; i++)
    fetch_register (tid, tdep->ppc_gp0_regnum + i);
  if (tdep->ppc_fp0_regnum >= 0)
    for (i = 0; i < ppc_num_fprs; i++)
      fetch_register (tid, tdep->ppc_fp0_regnum + i);
  fetch_register (tid, PC_REGNUM);
  if (tdep->ppc_ps_regnum != -1)
    fetch_register (tid, tdep->ppc_ps_regnum);
  if (tdep->ppc_cr_regnum != -1)
    fetch_register (tid, tdep->ppc_cr_regnum);
  if (tdep->ppc_lr_regnum != -1)
    fetch_register (tid, tdep->ppc_lr_regnum);
  if (tdep->ppc_ctr_regnum != -1)
    fetch_register (tid, tdep->ppc_ctr_regnum);
  if (tdep->ppc_xer_regnum != -1)
    fetch_register (tid, tdep->ppc_xer_regnum);
  if (tdep->ppc_mq_regnum != -1)
    fetch_register (tid, tdep->ppc_mq_regnum);
  if (tdep->ppc_fpscr_regnum != -1)
    fetch_register (tid, tdep->ppc_fpscr_regnum);
  if (have_ptrace_getvrregs)
    if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
      fetch_altivec_registers (tid);
  if (tdep->ppc_ev0_upper_regnum >= 0)
    fetch_spe_register (tid, -1);
}
示例#2
0
static void 
fetch_ppc_registers (struct regcache *regcache, int tid)
{
  int i;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  for (i = 0; i < ppc_num_gprs; i++)
    fetch_register (regcache, tid, tdep->ppc_gp0_regnum + i);
  if (tdep->ppc_fp0_regnum >= 0)
    for (i = 0; i < ppc_num_fprs; i++)
      fetch_register (regcache, tid, tdep->ppc_fp0_regnum + i);
  fetch_register (regcache, tid, gdbarch_pc_regnum (gdbarch));
  if (tdep->ppc_ps_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_ps_regnum);
  if (tdep->ppc_cr_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_cr_regnum);
  if (tdep->ppc_lr_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_lr_regnum);
  if (tdep->ppc_ctr_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_ctr_regnum);
  if (tdep->ppc_xer_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_xer_regnum);
  if (tdep->ppc_mq_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_mq_regnum);
  if (ppc_linux_trap_reg_p (gdbarch))
    {
      fetch_register (regcache, tid, PPC_ORIG_R3_REGNUM);
      fetch_register (regcache, tid, PPC_TRAP_REGNUM);
    }
  if (tdep->ppc_fpscr_regnum != -1)
    fetch_register (regcache, tid, tdep->ppc_fpscr_regnum);
  if (have_ptrace_getvrregs)
    if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1)
      fetch_altivec_registers (regcache, tid);
  if (have_ptrace_getsetvsxregs)
    if (tdep->ppc_vsr0_upper_regnum != -1)
      fetch_vsx_registers (regcache, tid);
  if (tdep->ppc_ev0_upper_regnum >= 0)
    fetch_spe_register (regcache, tid, -1);
}
static void
fetch_register (int tid, int regno)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
  /* This isn't really an address.  But ptrace thinks of it as one.  */
  CORE_ADDR regaddr = ppc_register_u_addr (regno);
  int bytes_transferred;
  unsigned int offset;         /* Offset of registers within the u area. */
  char buf[MAX_REGISTER_SIZE];

  if (altivec_register_p (regno))
    {
      /* If this is the first time through, or if it is not the first
         time through, and we have comfirmed that there is kernel
         support for such a ptrace request, then go and fetch the
         register.  */
      if (have_ptrace_getvrregs)
       {
         fetch_altivec_register (tid, regno);
         return;
       }
     /* If we have discovered that there is no ptrace support for
        AltiVec registers, fall through and return zeroes, because
        regaddr will be -1 in this case.  */
    }
  else if (spe_register_p (regno))
    {
      fetch_spe_register (tid, regno);
      return;
    }

  if (regaddr == -1)
    {
      memset (buf, '\0', register_size (current_gdbarch, regno));   /* Supply zeroes */
      regcache_raw_supply (current_regcache, regno, buf);
      return;
    }

  /* Read the raw register using sizeof(long) sized chunks.  On a
     32-bit platform, 64-bit floating-point registers will require two
     transfers.  */
  for (bytes_transferred = 0;
       bytes_transferred < register_size (current_gdbarch, regno);
       bytes_transferred += sizeof (long))
    {
      errno = 0;
      *(long *) &buf[bytes_transferred]
        = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0);
      regaddr += sizeof (long);
      if (errno != 0)
	{
          char message[128];
	  sprintf (message, "reading register %s (#%d)", 
		   REGISTER_NAME (regno), regno);
	  perror_with_name (message);
	}
    }

  /* Now supply the register.  Keep in mind that the regcache's idea
     of the register's size may not be a multiple of sizeof
     (long).  */
  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
    {
      /* Little-endian values are always found at the left end of the
         bytes transferred.  */
      regcache_raw_supply (current_regcache, regno, buf);
    }
  else if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
    {
      /* Big-endian values are found at the right end of the bytes
         transferred.  */
      size_t padding = (bytes_transferred
                        - register_size (current_gdbarch, regno));
      regcache_raw_supply (current_regcache, regno, buf + padding);
    }
  else 
    internal_error (__FILE__, __LINE__,
                    _("fetch_register: unexpected byte order: %d"),
                    gdbarch_byte_order (current_gdbarch));
}