Пример #1
0
static void
bdm_ppc_store_registers (int regno)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
  int i;
  int first_regno, last_regno;
  int first_bdm_regno, last_bdm_regno;

  if (regno == -1)
    {
      first_regno = 0;
      last_regno = NUM_REGS - 1;

      first_bdm_regno = 0;
      last_bdm_regno = BDM_NUM_REGS - 1;
    }
  else
    {
      first_regno = regno;
      last_regno = regno;

      first_bdm_regno = bdm_regmap[regno];
      last_bdm_regno = bdm_regmap[regno];
    }

  if (first_bdm_regno == -1)
    return;			/* Unsupported register */

  /* FIXME: jimb/2004-05-04: I'm not sure how to adapt this code to
     processors that lack floating point registers, and I don't have
     have the equipment to test it.  So we'll leave that case for the
     next person who encounters it.  */
  gdb_assert (ppc_floating_point_unit_p (current_gdbarch));

  for (i = first_regno; i <= last_regno; i++)
    {
      int bdm_regno;

      bdm_regno = bdm_regmap[i];

      /* only attempt to write if it's a valid ppc 8xx register */
      /* (need to avoid FP regs and MQ reg) */
      if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) 
          && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum) 
          && ((i < tdep->ppc_fp0_regnum)
              || (i >= tdep->ppc_fp0_regnum + ppc_num_fprs)))
	{
/*          printf("write valid reg %d\n", bdm_regno); */
	  ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4);
	}
/*
   else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
   printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
   else
   printf("don't write invalid reg %d\n", bdm_regno);
 */
    }
}
Пример #2
0
static int
register_changed_p (int regnum)
{
  gdb_byte raw_buffer[MAX_REGISTER_SIZE];

  if (! frame_register_read (get_selected_frame (NULL), regnum, raw_buffer))
    return -1;

  if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer,
	      register_size (current_gdbarch, regnum)) == 0)
    return 0;

  /* Found a changed register. Return 1. */

  memcpy (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer,
	  register_size (current_gdbarch, regnum));

  return 1;
}
Пример #3
0
static int
register_changed_p (int regnum)
{
  char raw_buffer[MAX_REGISTER_SIZE];

  if (! frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
    return -1;

  if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer,
	      DEPRECATED_REGISTER_RAW_SIZE (regnum)) == 0)
    return 0;

  /* Found a changed register. Return 1. */

  memcpy (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer,
	  DEPRECATED_REGISTER_RAW_SIZE (regnum));

  return 1;
}
Пример #4
0
void
fill_fpregset (fpregset_t *fpregsetp, int regno)
{
  int regi;
  char *from, *to;

  for (regi = mips_regnum (current_gdbarch)->fp0;
       regi < mips_regnum (current_gdbarch)->fp0 + 32; regi++)
    {
      if ((regno == -1) || (regno == regi))
	{
	  from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regi)];
	  to = (char *) &(fpregsetp->fp_r.fp_regs[regi - mips_regnum (current_gdbarch)->fp0]);
	  memcpy (to, from, register_size (current_gdbarch, regi));
	}
    }

  if ((regno == -1)
      || (regno == mips_regnum (current_gdbarch)->fp_control_status))
    fpregsetp->fp_csr = *(unsigned *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->fp_control_status)];
}
Пример #5
0
void
fill_gregset (gregset_t *gregsetp, int regno)
{
  int regi;
  greg_t *regp = &(*gregsetp)[0];

  for (regi = 0; regi <= 32; regi++)
    if ((regno == -1) || (regno == regi))
      *(regp + regi) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (regi)];

  if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->pc))
    *(regp + CXT_EPC) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->pc)];

  if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->cause))
    *(regp + CXT_CAUSE) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->cause)];

  if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->hi))
    *(regp + CXT_MDHI) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->hi)];

  if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->lo))
    *(regp + CXT_MDLO) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->lo)];
}
Пример #6
0
static void
bdm_ppc_store_registers (int regno)
{
  int i;
  int first_regno, last_regno;
  int first_bdm_regno, last_bdm_regno;

  if (regno == -1)
    {
      first_regno = 0;
      last_regno = NUM_REGS - 1;

      first_bdm_regno = 0;
      last_bdm_regno = BDM_NUM_REGS - 1;
    }
  else
    {
      first_regno = regno;
      last_regno = regno;

      first_bdm_regno = bdm_regmap[regno];
      last_bdm_regno = bdm_regmap[regno];
    }

  if (first_bdm_regno == -1)
    return;			/* Unsupported register */

  for (i = first_regno; i <= last_regno; i++)
    {
      int bdm_regno;

      bdm_regno = bdm_regmap[i];

      /* only attempt to write if it's a valid ppc 8xx register */
      /* (need to avoid FP regs and MQ reg) */
      if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) 
          && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum) 
          && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM)))
	{
/*          printf("write valid reg %d\n", bdm_regno); */
	  ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4);
	}
/*
   else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum)
   printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno);
   else
   printf("don't write invalid reg %d\n", bdm_regno);
 */
    }
}
/* FIXME rearnsha/2002-02-23: This function shouldn't be necessary.
   The ARM generic one should be able to handle the model used by
   linux and the low-level formatting of the registers should be
   hidden behind the regcache abstraction.  */
static void
arm_linux_extract_return_value (struct type *type,
				char regbuf[],
				char *valbuf)
{
  /* ScottB: This needs to be looked at to handle the different
     floating point emulators on ARM GNU/Linux.  Right now the code
     assumes that fetch inferior registers does the right thing for
     GDB.  I suspect this won't handle NWFPE registers correctly, nor
     will the default ARM version (arm_extract_return_value()).  */

  int regnum = ((TYPE_CODE_FLT == TYPE_CODE (type))
		? ARM_F0_REGNUM : ARM_A1_REGNUM);
  memcpy (valbuf, &regbuf[DEPRECATED_REGISTER_BYTE (regnum)], TYPE_LENGTH (type));
}
void
store_inferior_registers (int regno)
{
  int reglo, reghi;
  int i;
  unsigned long ecp;

  if (regno == -1)
    {
      reglo = 0;
      reghi = NUM_REGS - 1;
    }
  else
    reglo = reghi = regno;

  ecp = registers_addr (PIDGET (inferior_ptid));

  for (regno = reglo; regno <= reghi; regno++)
    {
      int ptrace_fun = PTRACE_POKEUSER;

      if (CANNOT_STORE_REGISTER (regno))
	continue;

#ifdef M68K
      ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
#endif

      for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int))
	{
	  unsigned int reg;

	  reg = *(unsigned int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno) + i];

	  errno = 0;
	  ptrace (ptrace_fun, PIDGET (inferior_ptid),
		  (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg);
	  if (errno)
	    perror_with_name ("ptrace(PTRACE_POKEUSP)");
	}
    }
}
void
store_inferior_registers (int regno)
{
  unsigned int regaddr;
  char buf[80];
  int i;
  unsigned int offset = U_REGS_OFFSET;
  int scratch;

  if (regno >= 0)
    {
      unsigned int addr, len, offset;

      if (CANNOT_STORE_REGISTER (regno))
	return;

      offset = 0;
      len = DEPRECATED_REGISTER_RAW_SIZE (regno);

      /* Requests for register zero actually want the save_state's
	 ss_flags member.  As RM says: "Oh, what a hack!"  */
      if (regno == 0)
	{
	  save_state_t ss;
	  addr = HPPAH_OFFSETOF (save_state_t, ss_flags);
	  len = sizeof (ss.ss_flags);

	  /* Note that ss_flags is always an int, no matter what
	     DEPRECATED_REGISTER_RAW_SIZE(0) says.  Assuming all HP-UX
	     PA machines are big-endian, put it at the least
	     significant end of the value, and zap the rest of the
	     buffer.  */
	  offset = DEPRECATED_REGISTER_RAW_SIZE (0) - len;
	}

      /* Floating-point registers come from the ss_fpblock area.  */
      else if (regno >= HPPA_FP0_REGNUM)
	addr = (HPPAH_OFFSETOF (save_state_t, ss_fpblock) 
		+ (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (HPPA_FP0_REGNUM)));

      /* Wide registers come from the ss_wide area.
	 I think it's more PC to test (ss_flags & SS_WIDEREGS) to select
	 between ss_wide and ss_narrow than to use the raw register size.
	 But checking ss_flags would require an extra ptrace call for
	 every register reference.  Bleah.  */
      else if (len == 8)
	addr = (HPPAH_OFFSETOF (save_state_t, ss_wide) 
		+ DEPRECATED_REGISTER_BYTE (regno));

      /* Narrow registers come from the ss_narrow area.  Note that
	 ss_narrow starts with gr1, not gr0.  */
      else if (len == 4)
	addr = (HPPAH_OFFSETOF (save_state_t, ss_narrow)
		+ (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (1)));
      else
	internal_error (__FILE__, __LINE__,
			"hppah-nat.c (write_register): unexpected register size");

#ifdef GDB_TARGET_IS_HPPA_20W
      /* Unbelieveable.  The PC head and tail must be written in 64bit hunks
	 or we will get an error.  Worse yet, the oddball ptrace/ttrace
	 layering will not allow us to perform a 64bit register store.

	 What a crock.  */
      if (regno == HPPA_PCOQ_HEAD_REGNUM || regno == HPPA_PCOQ_TAIL_REGNUM && len == 8)
	{
	  CORE_ADDR temp;

	  temp = *(CORE_ADDR *)&deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)];

	  /* Set the priv level (stored in the low two bits of the PC.  */
	  temp |= 0x3;

	  ttrace_write_reg_64 (PIDGET (inferior_ptid), (CORE_ADDR)addr,
	                       (CORE_ADDR)&temp);

	  /* If we fail to write the PC, give a true error instead of
	     just a warning.  */
	  if (errno != 0)
	    {
	      char *err = safe_strerror (errno);
	      char *msg = alloca (strlen (err) + 128);
	      sprintf (msg, "writing `%s' register: %s",
		        REGISTER_NAME (regno), err);
	      perror_with_name (msg);
	    }
	  return;
	}

      /* Another crock.  HPUX complains if you write a nonzero value to
	 the high part of IPSW.  What will it take for HP to catch a
	 clue about building sensible interfaces?  */
     if (regno == HPPA_IPSW_REGNUM && len == 8)
	*(int *)&deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)] = 0;
#endif

      for (i = 0; i < len; i += sizeof (int))
	{
	  errno = 0;
	  call_ptrace (PT_WUREGS, PIDGET (inferior_ptid),
	               (PTRACE_ARG3_TYPE) addr + i,
		       *(int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno) + i]);
	  if (errno != 0)
	    {
	      /* Warning, not error, in case we are attached; sometimes
		 the kernel doesn't let us at the registers. */
	      char *err = safe_strerror (errno);
	      char *msg = alloca (strlen (err) + 128);
	      sprintf (msg, "writing `%s' register: %s",
		        REGISTER_NAME (regno), err);
	      /* If we fail to write the PC, give a true error instead of
		 just a warning.  */
	      if (regno == HPPA_PCOQ_HEAD_REGNUM || regno == HPPA_PCOQ_TAIL_REGNUM)
		perror_with_name (msg);
	      else
		warning (msg);
	      return;
	    }
	}
    }
  else
    for (regno = 0; regno < NUM_REGS; regno++)
      store_inferior_registers (regno);
}
/* Fetch a register's value from the process's U area.  */
static void
fetch_register (int regno)
{
  char buf[MAX_REGISTER_SIZE];
  unsigned int addr, len, offset;
  int i;

  offset = 0;
  len = DEPRECATED_REGISTER_RAW_SIZE (regno);

  /* Requests for register zero actually want the save_state's
     ss_flags member.  As RM says: "Oh, what a hack!"  */
  if (regno == 0)
    {
      save_state_t ss;
      addr = HPPAH_OFFSETOF (save_state_t, ss_flags);
      len = sizeof (ss.ss_flags);

      /* Note that ss_flags is always an int, no matter what
	 DEPRECATED_REGISTER_RAW_SIZE(0) says.  Assuming all HP-UX PA
	 machines are big-endian, put it at the least significant end
	 of the value, and zap the rest of the buffer.  */
      offset = DEPRECATED_REGISTER_RAW_SIZE (0) - len;
      memset (buf, 0, sizeof (buf));
    }

  /* Floating-point registers come from the ss_fpblock area.  */
  else if (regno >= HPPA_FP0_REGNUM)
    addr = (HPPAH_OFFSETOF (save_state_t, ss_fpblock) 
	    + (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (HPPA_FP0_REGNUM)));

  /* Wide registers come from the ss_wide area.
     I think it's more PC to test (ss_flags & SS_WIDEREGS) to select
     between ss_wide and ss_narrow than to use the raw register size.
     But checking ss_flags would require an extra ptrace call for
     every register reference.  Bleah.  */
  else if (len == 8)
    addr = (HPPAH_OFFSETOF (save_state_t, ss_wide) 
	    + DEPRECATED_REGISTER_BYTE (regno));

  /* Narrow registers come from the ss_narrow area.  Note that
     ss_narrow starts with gr1, not gr0.  */
  else if (len == 4)
    addr = (HPPAH_OFFSETOF (save_state_t, ss_narrow)
	    + (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (1)));

  else
    internal_error (__FILE__, __LINE__,
		    "hppa-nat.c (fetch_register): unexpected register size");

  for (i = 0; i < len; i += sizeof (int))
    {
      errno = 0;
      /* Copy an int from the U area to buf.  Fill the least
         significant end if len != raw_size.  */
      * (int *) &buf[offset + i] =
	  call_ptrace (PT_RUREGS, PIDGET (inferior_ptid),
		       (PTRACE_ARG3_TYPE) addr + i, 0);
      if (errno != 0)
	{
	  /* Warning, not error, in case we are attached; sometimes
	     the kernel doesn't let us at the registers. */
	  char *err = safe_strerror (errno);
	  char *msg = alloca (strlen (err) + 128);
	  sprintf (msg, "reading `%s' register: %s",
		   REGISTER_NAME (regno), err);
	  warning (msg);
	  return;
	}
    }

  /* If we're reading an address from the instruction address queue,
     mask out the bottom two bits --- they contain the privilege
     level.  */
  if (regno == HPPA_PCOQ_HEAD_REGNUM || regno == HPPA_PCOQ_TAIL_REGNUM)
    buf[len - 1] &= ~0x3;

  supply_register (regno, buf);
}
Пример #11
0
/* Write given values into registers. The registers and values are
   given as pairs. The corresponding MI command is 
   -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]*/
enum mi_cmd_result
mi_cmd_data_write_register_values (char *command, char **argv, int argc)
{
  int regnum;
  int i;
  int numregs;
  LONGEST value;
  char format;

  /* Note that the test for a valid register must include checking the
     REGISTER_NAME because NUM_REGS may be allocated for the union of
     the register sets within a family of related processors.  In this
     case, some entries of REGISTER_NAME will change depending upon
     the particular processor being debugged.  */

  numregs = NUM_REGS + NUM_PSEUDO_REGS;

  if (argc == 0)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Usage: -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]");
      return MI_CMD_ERROR;
    }

  format = (int) argv[0][0];

  if (!target_has_registers)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No registers.");
      return MI_CMD_ERROR;
    }

  if (!(argc - 1))
    {
      mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No regs and values specified.");
      return MI_CMD_ERROR;
    }

  if ((argc - 1) % 2)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: Regs and vals are not in pairs.");
      return MI_CMD_ERROR;
    }

  for (i = 1; i < argc; i = i + 2)
    {
      regnum = atoi (argv[i]);

      if (regnum >= 0
	  && regnum < numregs
	  && REGISTER_NAME (regnum) != NULL
	  && *REGISTER_NAME (regnum) != '\000')
	{
	  void *buffer;
	  struct cleanup *old_chain;

	  /* Get the value as a number */
	  value = parse_and_eval_address (argv[i + 1]);
	  /* Get the value into an array */
	  buffer = xmalloc (DEPRECATED_REGISTER_SIZE);
	  old_chain = make_cleanup (xfree, buffer);
	  store_signed_integer (buffer, DEPRECATED_REGISTER_SIZE, value);
	  /* Write it down */
	  deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (regnum), buffer, register_size (current_gdbarch, regnum));
	  /* Free the buffer.  */
	  do_cleanups (old_chain);
	}
      else
	{
	  mi_error_message = xstrprintf ("bad register number");
	  return MI_CMD_ERROR;
	}
    }
  return MI_CMD_DONE;
}