Ejemplo n.º 1
0
/* Store the whole floating-point state into THREAD using information
   from the corresponding (pseudo) registers.  */
static void
store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
{
  mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
  struct i386_float_state state;
  error_t err;

  err = thread_get_state (thread->port, i386_FLOAT_STATE,
			  (thread_state_t) &state, &count);
  if (err)
    {
      warning (_("Couldn't fetch floating-point state from %s"),
	       proc_string (thread));
      return;
    }

  /* FIXME: kettenis/2001-07-15: Is this right?  Should we somehow
     take into account DEPRECATED_REGISTER_VALID like the old code did?  */
  i387_collect_fsave (regcache, regno, state.hw_state);

  err = thread_set_state (thread->port, i386_FLOAT_STATE,
			  (thread_state_t) &state, i386_FLOAT_STATE_COUNT);
  if (err)
    {
      warning (_("Couldn't store floating-point state into %s"),
	       proc_string (thread));
      return;
    }
}
Ejemplo n.º 2
0
static void
fetch_fpregs (struct regcache *regcache, struct proc *thread)
{
  mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
  struct i386_float_state state;
  error_t err;

  err = thread_get_state (thread->port, i386_FLOAT_STATE,
			  (thread_state_t) &state, &count);
  if (err)
    {
      warning (_("Couldn't fetch floating-point state from %s"),
	       proc_string (thread));
      return;
    }

  if (!state.initialized)
    {
      /* The floating-point state isn't initialized.  */
      i387_supply_fsave (regcache, -1, NULL);
    }
  else
    {
      /* Supply the floating-point registers.  */
      i387_supply_fsave (regcache, -1, state.hw_state);
    }
}
Ejemplo n.º 3
0
/* Get the whole floating-point state of THREAD and record the
   values of the corresponding (pseudo) registers.  */
static void
fetch_fpregs (struct proc *thread)
{
  mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
  struct i386_float_state state;
  error_t err;

  err = thread_get_state (thread->port, i386_FLOAT_STATE,
			  (thread_state_t) &state, &count);
  if (err)
    {
      warning ("Couldn't fetch floating-point state from %s",
	       proc_string (thread));
      return;
    }

  if (!state.initialized)
    /* The floating-point state isn't initialized.  */
    {
      int i;

      for (i = FP0_REGNUM; i <= FOP_REGNUM; i++)
	supply_register (i, NULL);

      return;
    }

  /* Supply the floating-point registers.  */
  i387_supply_fsave (current_regcache, -1, state.hw_state);
}
Ejemplo n.º 4
0
/*
 * Fetch inferiors registers for gdb.
 * REG specifies which (as gdb views it) register, -1 for all.
 */
void
gnu_fetch_registers (int reg)
{
  struct proc *thread;
  thread_state_t state;
  
  inf_update_procs (current_inferior); /* Make sure we know about new threads.  */

  thread = inf_tid_to_thread (current_inferior, inferior_pid);
  if (! thread)
    error ("fetch inferior registers: %d: Invalid thread", inferior_pid);

  state = proc_get_state (thread, 0);

  if (! state)
    warning ("Couldn't fetch register %s from %s (invalid thread).",
	     reg_names[reg], proc_string (thread));
  else if (reg >= 0)
    {
      proc_debug (thread, "fetching register: %s", reg_names[reg]);
      supply_register (reg, REG_ADDR(state, reg));
      thread->fetched_regs |= (1 << reg);
    }
  else
    {
      proc_debug (thread, "fetching all registers");
      for (reg = 0; reg < NUM_REGS; reg++) 
	supply_register (reg, REG_ADDR(state, reg));
      thread->fetched_regs = ~0;
    }
}
Ejemplo n.º 5
0
/* Fetch register REGNO, or all regs if REGNO is -1.  */
static void
gnu_fetch_registers (struct target_ops *ops,
		     struct regcache *regcache, int regno)
{
  struct proc *thread;

  /* 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 (_("Can't fetch registers from thread %s: No such thread"),
	   target_pid_to_str (inferior_ptid));

  if (regno < I386_NUM_GREGS || regno == -1)
    {
      thread_state_t state;

      /* This does the dirty work for us.  */
      state = proc_get_state (thread, 0);
      if (!state)
	{
	  warning (_("Couldn't fetch registers from %s"),
		   proc_string (thread));
	  return;
	}

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

	  proc_debug (thread, "fetching all register");

	  for (i = 0; i < I386_NUM_GREGS; i++)
	    regcache_raw_supply (regcache, i, REG_ADDR (state, i));
	  thread->fetched_regs = ~0;
	}
      else
	{
	  proc_debug (thread, "fetching register %s",
		      gdbarch_register_name (get_regcache_arch (regcache),
					     regno));

	  regcache_raw_supply (regcache, regno,
			       REG_ADDR (state, regno));
	  thread->fetched_regs |= (1 << regno);
	}
    }

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

      fetch_fpregs (regcache, thread);
    }
}
Ejemplo n.º 6
0
static void
i386_gnu_dr_set (const struct i386_debug_state *regs, struct proc *thread)
{
  error_t err;

  err = thread_set_state (thread->port, i386_DEBUG_STATE,
			  (thread_state_t) regs, i386_DEBUG_STATE_COUNT);
  if (err != 0)
    warning (_("Couldn't store debug state into %s"),
	     proc_string (thread));
}
Ejemplo n.º 7
0
static void
i386_gnu_dr_get (struct i386_debug_state *regs, struct proc *thread)
{
  mach_msg_type_number_t count = i386_DEBUG_STATE_COUNT;
  error_t err;

  err = thread_get_state (thread->port, i386_DEBUG_STATE,
			  (thread_state_t) regs, &count);
  if (err != 0 || count != i386_DEBUG_STATE_COUNT)
    warning (_("Couldn't fetch debug state from %s"),
	     proc_string (thread));
}
Ejemplo n.º 8
0
/* Fetch register REGNO, or all regs if REGNO is -1.  */
void
gnu_fetch_registers (int regno)
{
  struct proc *thread;

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

  thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
  if (!thread)
    error ("Can't fetch registers from thread %d: No such thread",
	   PIDGET (inferior_ptid));

  if (regno < I386_NUM_GREGS || regno == -1)
    {
      thread_state_t state;

      /* This does the dirty work for us.  */
      state = proc_get_state (thread, 0);
      if (!state)
	{
	  warning ("Couldn't fetch registers from %s",
		   proc_string (thread));
	  return;
	}

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

	  proc_debug (thread, "fetching all register");

	  for (i = 0; i < I386_NUM_GREGS; i++)
	    supply_register (i, REG_ADDR (state, i));
	  thread->fetched_regs = ~0;
	}
      else
	{
	  proc_debug (thread, "fetching register %s", REGISTER_NAME (regno));

	  supply_register (regno, REG_ADDR (state, regno));
	  thread->fetched_regs |= (1 << regno);
	}
    }

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

      fetch_fpregs (thread);
    }
}
Ejemplo n.º 9
0
static void
state_wait (pid_t process, const char *wanted)
{
  char *filename;
  int i;
  struct timespec start, now;
  const char *state;

  i = asprintf (&filename, "/proc/%lu/status", (unsigned long) process);
  assert (i > 0);

  i = clock_gettime (CLOCK_MONOTONIC, &start);
  assert (i == 0);

  do
    {
      state = proc_string (filename, "State:\t");

      /* torvalds/linux-2.6.git 464763cf1c6df632dccc8f2f4c7e50163154a2c0
	 has changed "T (tracing stop)" to "t (tracing stop)".  Make the GDB
	 testcase backward compatible with older Linux kernels.  */
      if (strcmp (state, "T (tracing stop)") == 0)
	state = "t (tracing stop)";

      if (strcmp (state, wanted) == 0)
	{
	  free (filename);
	  return;
	}

      if (sched_yield ())
	{
	  perror ("sched_yield()");
	  exit (EXIT_FAILURE);
	}

      i = clock_gettime (CLOCK_MONOTONIC, &now);
      assert (i == 0);
      assert (now.tv_sec >= start.tv_sec);
    }
  while (now.tv_sec - start.tv_sec < TIMEOUT);

  fprintf (stderr, "Timed out waiting for PID %lu \"%s\" (now it is \"%s\")!\n",
	   (unsigned long) process, wanted, state);
  exit (EXIT_FAILURE);
}
Ejemplo n.º 10
0
static unsigned long
proc_ulong (const char *filename, const char *line)
{
  const char *s = proc_string (filename, line);
  long retval;
  char *end;

  errno = 0;
  retval = strtol (s, &end, 10);
  if (retval < 0 || retval >= LONG_MAX || (end && *end))
    {
      fprintf (stderr, "\"%s\":\"%s\": %ld, %s\n", filename, line, retval,
	       strerror (errno));
      exit (EXIT_FAILURE);
    }
  return retval;
}
static void
state_wait (pid_t process, const char *wanted)
{
  char *filename;
  int i;
  struct timespec start, now;
  const char *state;

  i = asprintf (&filename, "/proc/%lu/status", (unsigned long) process);
  assert (i > 0);

  i = clock_gettime (CLOCK_MONOTONIC, &start);
  assert (i == 0);

  do
    {
      state = proc_string (filename, "State:\t");
      if (strcmp (state, wanted) == 0)
	{
	  free (filename);
	  return;
	}

      if (sched_yield ())
	{
	  perror ("sched_yield()");
	  exit (EXIT_FAILURE);
	}

      i = clock_gettime (CLOCK_MONOTONIC, &now);
      assert (i == 0);
      assert (now.tv_sec >= start.tv_sec);
    }
  while (now.tv_sec - start.tv_sec < TIMEOUT);

  fprintf (stderr, "Timed out waiting for PID %lu \"%s\" (now it is \"%s\")!\n",
	   (unsigned long) process, wanted, state);
  exit (EXIT_FAILURE);
}
Ejemplo n.º 12
0
/* 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);
    }
}
Ejemplo n.º 13
0
/* Store at least register REGNO, or all regs if REGNO == -1.  */
void
gnu_store_registers (int regno)
{
  struct proc *thread;

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

  thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
  if (!thread)
    error ("Couldn't store registers into thread %d: No such thread",
	   PIDGET (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),
			   DEPRECATED_REGISTER_RAW_SIZE (check_regno)))
	      /* Register CHECK_REGNO has changed!  Ack!  */
	      {
		warning ("Register %s changed after the thread was aborted",
			 REGISTER_NAME (check_regno));
		if (regno >= 0 && regno != check_regno)
		  /* Update GDB's copy of the register.  */
		  supply_register (check_regno, REG_ADDR (state, check_regno));
		else
		  warning ("... also writing this register!  Suspicious...");
	      }
	}

#define fill(state, regno)                                               \
  memcpy (REG_ADDR(state, regno), &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)],     \
          DEPRECATED_REGISTER_RAW_SIZE (regno))

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

	  proc_debug (thread, "storing all registers");

	  for (i = 0; i < I386_NUM_GREGS; i++)
	    if (deprecated_register_valid[i])
	      fill (state, i);
	}
      else
	{
	  proc_debug (thread, "storing register %s", REGISTER_NAME (regno));

	  gdb_assert (deprecated_register_valid[regno]);
	  fill (state, regno);
	}

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

#undef fill

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

      store_fpregs (thread, regno);
    }
}