/* Low-level debug register code for GNU/Linux x86 (i386 and x86-64).

   Copyright (C) 1999-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "gdbsupport/common-defs.h"
#include "nat/gdb_ptrace.h"
#include <sys/user.h>
#include "target/waitstatus.h"
#include "nat/x86-linux.h"
#include "nat/x86-dregs.h"
#include "nat/x86-linux-dregs.h"

/* Return the offset of REGNUM in the u_debugreg field of struct
   user.  */

static int
u_debugreg_offset (int regnum)
{
  return (offsetof (struct user, u_debugreg)
	  + sizeof (((struct user *) 0)->u_debugreg[0]) * regnum);
}

/* Get debug register REGNUM value from the LWP specified by PTID.  */

static unsigned long
x86_linux_dr_get (ptid_t ptid, int regnum)
{
  int tid;
  unsigned long value;

  gdb_assert (ptid.lwp_p ());
  tid = ptid.lwp ();

  errno = 0;
  value = ptrace (PTRACE_PEEKUSER, tid, u_debugreg_offset (regnum), 0);
  if (errno != 0)
    perror_with_name (_("Couldn't read debug register"));

  return value;
}

/* Set debug register REGNUM to VALUE in the LWP specified by PTID.  */

static void
x86_linux_dr_set (ptid_t ptid, int regnum, unsigned long value)
{
  int tid;

  gdb_assert (ptid.lwp_p ());
  tid = ptid.lwp ();

  errno = 0;
  ptrace (PTRACE_POKEUSER, tid, u_debugreg_offset (regnum), value);
  if (errno != 0)
    perror_with_name (_("Couldn't write debug register"));
}

/* Callback for iterate_over_lwps.  Mark that our local mirror of
   LWP's debug registers has been changed, and cause LWP to stop if
   it isn't already.  Values are written from our local mirror to
   the actual debug registers immediately prior to LWP resuming.  */

static int
update_debug_registers_callback (struct lwp_info *lwp)
{
  lwp_set_debug_registers_changed (lwp, 1);

  if (!lwp_is_stopped (lwp))
    linux_stop_lwp (lwp);

  /* Continue the iteration.  */
  return 0;
}

/* See nat/x86-linux-dregs.h.  */

CORE_ADDR
x86_linux_dr_get_addr (int regnum)
{
  gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);

  return x86_linux_dr_get (current_lwp_ptid (), regnum);
}

/* See nat/x86-linux-dregs.h.  */

void
x86_linux_dr_set_addr (int regnum, CORE_ADDR addr)
{
  ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());

  gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);

  iterate_over_lwps (pid_ptid, update_debug_registers_callback);
}

/* See nat/x86-linux-dregs.h.  */

unsigned long
x86_linux_dr_get_control (void)
{
  return x86_linux_dr_get (current_lwp_ptid (), DR_CONTROL);
}

/* See nat/x86-linux-dregs.h.  */

void
x86_linux_dr_set_control (unsigned long control)
{
  ptid_t pid_ptid = ptid_t (current_lwp_ptid ().pid ());

  iterate_over_lwps (pid_ptid, update_debug_registers_callback);
}

/* See nat/x86-linux-dregs.h.  */

unsigned long
x86_linux_dr_get_status (void)
{
  return x86_linux_dr_get (current_lwp_ptid (), DR_STATUS);
}

/* See nat/x86-linux-dregs.h.  */

void
x86_linux_update_debug_registers (struct lwp_info *lwp)
{
  ptid_t ptid = ptid_of_lwp (lwp);
  int clear_status = 0;

  gdb_assert (lwp_is_stopped (lwp));

  if (lwp_debug_registers_changed (lwp))
    {
      struct x86_debug_reg_state *state
	= x86_debug_reg_state (ptid.pid ());
      int i;

      /* Prior to Linux kernel 2.6.33 commit
	 72f674d203cd230426437cdcf7dd6f681dad8b0d, setting DR0-3 to
	 a value that did not match what was enabled in DR_CONTROL
	 resulted in EINVAL.  To avoid this we zero DR_CONTROL before
	 writing address registers, only writing DR_CONTROL's actual
	 value once all the addresses are in place.  */
      x86_linux_dr_set (ptid, DR_CONTROL, 0);

      ALL_DEBUG_ADDRESS_REGISTERS (i)
	if (state->dr_ref_count[i] > 0)
	  {
	    x86_linux_dr_set (ptid, i, state->dr_mirror[i]);

	    /* If we're setting a watchpoint, any change the inferior
	       has made to its debug registers needs to be discarded
	       to avoid x86_stopped_data_address getting confused.  */
	    clear_status = 1;
	  }

      /* If DR_CONTROL is supposed to be zero then it's already set.  */
      if (state->dr_control_mirror != 0)
	x86_linux_dr_set (ptid, DR_CONTROL, state->dr_control_mirror);

      lwp_set_debug_registers_changed (lwp, 0);
    }

  if (clear_status
      || lwp_stop_reason (lwp) == TARGET_STOPPED_BY_WATCHPOINT)
    x86_linux_dr_set (ptid, DR_STATUS, 0);
}
