예제 #1
0
static void
store_regs (const struct regcache *regcache)
{
  int ret, regno, tid;
  elf_gregset_t regs;

  /* Get the thread id for the ptrace call.  */
  tid = GET_THREAD_ID (inferior_ptid);
  
  /* Fetch the general registers.  */
  ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);
  if (ret < 0)
    {
      warning (_("Unable to fetch general registers."));
      return;
    }

  for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++)
    {
      if (REG_VALID == regcache_register_status (regcache, regno))
	regcache_raw_collect (regcache, regno, (char *) &regs[regno]);
    }

  if (arm_apcs_32 && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM))
    regcache_raw_collect (regcache, ARM_PS_REGNUM,
			 (char *) &regs[ARM_CPSR_GREGNUM]);

  ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);

  if (ret < 0)
    {
      warning (_("Unable to store general registers."));
      return;
    }
}
예제 #2
0
static void
store_fpregs (const struct regcache *regcache)
{
  int ret, regno, tid;
  gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];

  /* Get the thread id for the ptrace call.  */
  tid = GET_THREAD_ID (inferior_ptid);
  
  /* Read the floating point state.  */
  ret = ptrace (PT_GETFPREGS, tid, 0, fp);
  if (ret < 0)
    {
      warning (_("Unable to fetch the floating point registers."));
      return;
    }

  /* Store fpsr.  */
  if (REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM))
    regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET);

  /* Store the floating point registers.  */
  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
    if (REG_VALID == regcache_register_status (regcache, regno))
      collect_nwfpe_register (regcache, regno, fp);

  ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);
  if (ret < 0)
    {
      warning (_("Unable to store floating point registers."));
      return;
    }
}
예제 #3
0
static void
store_fpregs (const struct regcache *regcache)
{
  int ret, regno, tid;
  gdb_byte fp[ARM_LINUX_SIZEOF_NWFPE];

  /* Get the thread id for the ptrace call.  */
  tid = ptid_get_lwp (inferior_ptid);

  /* Read the floating point state.  */
  if (have_ptrace_getregset == TRIBOOL_TRUE)
    {
      elf_fpregset_t fpregs;
      struct iovec iov;

      iov.iov_base = &fpregs;
      iov.iov_len = sizeof (fpregs);

      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iov);
    }
  else
    ret = ptrace (PT_GETFPREGS, tid, 0, fp);

  if (ret < 0)
    {
      warning (_("Unable to fetch the floating point registers."));
      return;
    }

  /* Store fpsr.  */
  if (REG_VALID == regcache_register_status (regcache, ARM_FPS_REGNUM))
    regcache_raw_collect (regcache, ARM_FPS_REGNUM, fp + NWFPE_FPSR_OFFSET);

  /* Store the floating point registers.  */
  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
    if (REG_VALID == regcache_register_status (regcache, regno))
      collect_nwfpe_register (regcache, regno, fp);

  if (have_ptrace_getregset == TRIBOOL_TRUE)
    {
      struct iovec iov;

      iov.iov_base = &fp;
      iov.iov_len = ARM_LINUX_SIZEOF_NWFPE;

      ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iov);
    }
  else
    ret = ptrace (PTRACE_SETFPREGS, tid, 0, fp);

  if (ret < 0)
    {
      warning (_("Unable to store floating point registers."));
      return;
    }
}
예제 #4
0
static void
store_regs (const struct regcache *regcache)
{
  int ret, regno, tid;
  elf_gregset_t regs;

  /* Get the thread id for the ptrace call.  */
  tid = GET_THREAD_ID (inferior_ptid);

  /* Fetch the general registers.  */
  if (have_ptrace_getregset == TRIBOOL_TRUE)
    {
      struct iovec iov;

      iov.iov_base = &regs;
      iov.iov_len = sizeof (regs);

      ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iov);
    }
  else
    ret = ptrace (PTRACE_GETREGS, tid, 0, &regs);

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

  for (regno = ARM_A1_REGNUM; regno <= ARM_PC_REGNUM; regno++)
    {
      if (REG_VALID == regcache_register_status (regcache, regno))
	regcache_raw_collect (regcache, regno, (char *) &regs[regno]);
    }

  if (arm_apcs_32 && REG_VALID == regcache_register_status (regcache, ARM_PS_REGNUM))
    regcache_raw_collect (regcache, ARM_PS_REGNUM,
			 (char *) &regs[ARM_CPSR_GREGNUM]);

  if (have_ptrace_getregset == TRIBOOL_TRUE)
    {
      struct iovec iov;

      iov.iov_base = &regs;
      iov.iov_len = sizeof (regs);

      ret = ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, &iov);
    }
  else
    ret = ptrace (PTRACE_SETREGS, tid, 0, &regs);

  if (ret < 0)
    {
      warning (_("Unable to store general registers."));
      return;
    }
}
예제 #5
0
static void
store_wmmx_regs (const struct regcache *regcache)
{
  char regbuf[IWMMXT_REGS_SIZE];
  int ret, regno, tid;

  /* Get the thread id for the ptrace call.  */
  tid = ptid_get_lwp (inferior_ptid);

  ret = ptrace (PTRACE_GETWMMXREGS, tid, 0, regbuf);
  if (ret < 0)
    {
      warning (_("Unable to fetch WMMX registers."));
      return;
    }

  for (regno = 0; regno < 16; regno++)
    if (REG_VALID == regcache_register_status (regcache,
					       regno + ARM_WR0_REGNUM))
      regcache_raw_collect (regcache, regno + ARM_WR0_REGNUM,
			    &regbuf[regno * 8]);

  for (regno = 0; regno < 2; regno++)
    if (REG_VALID == regcache_register_status (regcache,
					       regno + ARM_WCSSF_REGNUM))
      regcache_raw_collect (regcache, regno + ARM_WCSSF_REGNUM,
			    &regbuf[16 * 8 + regno * 4]);

  for (regno = 0; regno < 4; regno++)
    if (REG_VALID == regcache_register_status (regcache,
					       regno + ARM_WCGR0_REGNUM))
      regcache_raw_collect (regcache, regno + ARM_WCGR0_REGNUM,
			    &regbuf[16 * 8 + 2 * 4 + regno * 4]);

  ret = ptrace (PTRACE_SETWMMXREGS, tid, 0, regbuf);

  if (ret < 0)
    {
      warning (_("Unable to store WMMX registers."));
      return;
    }
}
예제 #6
0
static void
get_core_registers (struct target_ops *ops,
		    struct regcache *regcache, int regno)
{
  struct core_regset_section *sect_list;
  int i;

  if (!(core_gdbarch && gdbarch_regset_from_core_section_p (core_gdbarch))
      && (core_vec == NULL || core_vec->core_read_registers == NULL))
    {
      fprintf_filtered (gdb_stderr,
		     "Can't fetch registers from this type of core file\n");
      return;
    }

  sect_list = gdbarch_core_regset_sections (get_regcache_arch (regcache));
  if (sect_list)
    while (sect_list->sect_name != NULL)
      {
        if (strcmp (sect_list->sect_name, ".reg") == 0)
	  get_core_register_section (regcache, sect_list->sect_name,
				     0, sect_list->human_name, 1);
        else if (strcmp (sect_list->sect_name, ".reg2") == 0)
	  get_core_register_section (regcache, sect_list->sect_name,
				     2, sect_list->human_name, 0);
	else
	  get_core_register_section (regcache, sect_list->sect_name,
				     3, sect_list->human_name, 0);

	sect_list++;
      }

  else
    {
      get_core_register_section (regcache,
				 ".reg", 0, "general-purpose", 1);
      get_core_register_section (regcache,
				 ".reg2", 2, "floating-point", 0);
    }

  /* Mark all registers not found in the core as unavailable.  */
  for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
    if (regcache_register_status (regcache, i) == REG_UNKNOWN)
      regcache_raw_supply (regcache, i, NULL);
}
예제 #7
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_lwp (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 (REG_VALID == regcache_register_status (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 (REG_VALID == regcache_register_status (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);
    }
}
예제 #8
0
파일: ctf.c 프로젝트: phausler/binutils
static void
ctf_fetch_registers (struct target_ops *ops,
		     struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct bt_ctf_event *event = NULL;
  struct bt_iter_pos *pos;

  /* An uninitialized reg size says we're not going to be
     successful at getting register blocks.  */
  if (trace_regblock_size == 0)
    return;

  gdb_assert (ctf_iter != NULL);
  /* Save the current position.  */
  pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter));
  gdb_assert (pos->type == BT_SEEK_RESTORE);

  while (1)
    {
      const char *name;
      struct bt_ctf_event *event1;

      event1 = bt_ctf_iter_read_event (ctf_iter);

      name = bt_ctf_event_name (event1);

      if (name == NULL || strcmp (name, "frame") == 0)
	break;
      else if (strcmp (name, "register") == 0)
	{
	  event = event1;
	  break;
	}

      if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0)
	break;
    }

  /* Restore the position.  */
  bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);

  if (event != NULL)
    {
      int offset, regsize, regn;
      const struct bt_definition *scope
	= bt_ctf_get_top_level_scope (event,
				      BT_EVENT_FIELDS);
      const struct bt_definition *array
	= bt_ctf_get_field (event, scope, "contents");
      gdb_byte *regs = (gdb_byte *) bt_ctf_get_char_array (array);

      /* Assume the block is laid out in GDB register number order,
	 each register with the size that it has in GDB.  */
      offset = 0;
      for (regn = 0; regn < gdbarch_num_regs (gdbarch); regn++)
	{
	  regsize = register_size (gdbarch, regn);
	  /* Make sure we stay within block bounds.  */
	  if (offset + regsize >= trace_regblock_size)
	    break;
	  if (regcache_register_status (regcache, regn) == REG_UNKNOWN)
	    {
	      if (regno == regn)
		{
		  regcache_raw_supply (regcache, regno, regs + offset);
		  break;
		}
	      else if (regno == -1)
		{
		  regcache_raw_supply (regcache, regn, regs + offset);
		}
	    }
	  offset += regsize;
	}
    }
  else
    tracefile_fetch_registers (regcache, regno);
}