void
amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
{
  gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);

  amd64_linux_dr_set (DR_FIRSTADDR + regnum, addr);
}
void
amd64_linux_dr_reset_addr (int regnum)
{
  gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);

  amd64_linux_dr_set (DR_FIRSTADDR + regnum, 0L);
}
示例#3
0
static void
amd64_linux_prepare_to_resume (struct lwp_info *lwp)
{
  int clear_status = 0;

  /* NULL means this is the main thread still going through the shell,
     or, no watchpoint has been set yet.  In that case, there's
     nothing to do.  */
  if (lwp->arch_private == NULL)
    return;

  if (lwp->arch_private->debug_registers_changed)
    {
      struct i386_debug_reg_state *state
	= i386_debug_reg_state (ptid_get_pid (lwp->ptid));
      int i;

      /* On Linux kernel before 2.6.33 commit
	 72f674d203cd230426437cdcf7dd6f681dad8b0d
	 if you enable a breakpoint by the DR_CONTROL bits you need to have
	 already written the corresponding DR_FIRSTADDR...DR_LASTADDR registers.

	 Ensure DR_CONTROL gets written as the very last register here.  */

      for (i = DR_FIRSTADDR; i <= DR_LASTADDR; i++)
	if (state->dr_ref_count[i] > 0)
	  {
	    amd64_linux_dr_set (lwp->ptid, i, state->dr_mirror[i]);

	    /* If we're setting a watchpoint, any change the inferior
	       had done itself to the debug registers needs to be
	       discarded, otherwise, i386_stopped_data_address can get
	       confused.  */
	    clear_status = 1;
	  }

      amd64_linux_dr_set (lwp->ptid, DR_CONTROL, state->dr_control_mirror);

      lwp->arch_private->debug_registers_changed = 0;
    }

  if (clear_status || lwp->stopped_by_watchpoint)
    amd64_linux_dr_set (lwp->ptid, DR_STATUS, 0);
}
void
amd64_linux_dr_set_control (unsigned long control)
{
  amd64_linux_dr_set (DR_CONTROL, control);
}