/* Native-dependent code for GNU/Linux on LoongArch processors.

   Copyright (C) 2022-2024 Free Software Foundation, Inc.
   Contributed by Loongson Ltd.

   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 "cli/cli-cmds.h"
#include "elf/common.h"
#include "gregset.h"
#include "inferior.h"
#include "linux-nat-trad.h"
#include "loongarch-tdep.h"
#include "nat/gdb_ptrace.h"
#include "nat/loongarch-hw-point.h"
#include "nat/loongarch-linux.h"
#include "nat/loongarch-linux-hw-point.h"
#include "target-descriptions.h"

#include <asm/ptrace.h>

/* LoongArch Linux native additions to the default Linux support.  */

class loongarch_linux_nat_target final : public linux_nat_trad_target
{
public:
  /* Add our register access methods.  */
  void fetch_registers (struct regcache *, int) override;
  void store_registers (struct regcache *, int) override;

  int can_use_hw_breakpoint (enum bptype type, int cnt, int othertype) override;
  int region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) override;

  int insert_watchpoint (CORE_ADDR addr, int len, enum target_hw_bp_type type,
			 struct expression *cond) override;
  int remove_watchpoint (CORE_ADDR addr, int len, enum target_hw_bp_type type,
			 struct expression *cond) override;
  bool watchpoint_addr_within_range (CORE_ADDR addr, CORE_ADDR start,
				     int length) override;

  /* Add our hardware breakpoint and watchpoint implementation.  */
  bool stopped_by_watchpoint () override;
  bool stopped_data_address (CORE_ADDR *) override;

  int insert_hw_breakpoint (struct gdbarch *gdbarch,
			    struct bp_target_info *bp_tgt) override;
  int remove_hw_breakpoint (struct gdbarch *gdbarch,
			    struct bp_target_info *bp_tgt) override;

  /* Override the GNU/Linux inferior startup hook.  */
  void post_startup_inferior (ptid_t) override;

  /* Override the GNU/Linux post attach hook.  */
  void post_attach (int pid) override;

  /* These three defer to common nat/ code.  */
  void low_new_thread (struct lwp_info *lp) override
  { loongarch_linux_new_thread (lp); }
  void low_delete_thread (struct arch_lwp_info *lp) override
  { loongarch_linux_delete_thread (lp); }
  void low_prepare_to_resume (struct lwp_info *lp) override
  { loongarch_linux_prepare_to_resume (lp); }

  void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
  void low_forget_process (pid_t pid) override;

protected:
  /* Override linux_nat_trad_target methods.  */
  CORE_ADDR register_u_offset (struct gdbarch *gdbarch, int regnum,
			       int store_p) override;
};

/* Fill GDB's register array with the general-purpose, orig_a0, pc and badv
   register values from the current thread.  */

static void
fetch_gregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_gregset_t regset;

  if (regnum == -1 || (regnum >= 0 && regnum < 32)
      || regnum == LOONGARCH_ORIG_A0_REGNUM
      || regnum == LOONGARCH_PC_REGNUM
      || regnum == LOONGARCH_BADV_REGNUM)
  {
    struct iovec iov;

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

    if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
      perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
    else
      loongarch_gregset.supply_regset (nullptr, regcache, -1,
				       &regset, sizeof (regset));
  }
}

/* Store to the current thread the valid general-purpose, orig_a0, pc and badv
   register values in the GDB's register array.  */

static void
store_gregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_gregset_t regset;

  if (regnum == -1 || (regnum >= 0 && regnum < 32)
      || regnum == LOONGARCH_ORIG_A0_REGNUM
      || regnum == LOONGARCH_PC_REGNUM
      || regnum == LOONGARCH_BADV_REGNUM)
  {
    struct iovec iov;

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

    if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
      perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
    else
      {
	loongarch_gregset.collect_regset (nullptr, regcache, regnum,
					  &regset, sizeof (regset));
	if (ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
	  perror_with_name (_("Couldn't set NT_PRSTATUS registers"));
      }
  }
}

/* Fill GDB's register array with the fp, fcc and fcsr
   register values from the current thread.  */

static void
fetch_fpregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_fpregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
	perror_with_name (_("Couldn't get NT_FPREGSET registers"));
      else
	loongarch_fpregset.supply_regset (nullptr, regcache, -1,
					  &regset, sizeof (regset));
    }
}

/* Store to the current thread the valid fp, fcc and fcsr
   register values in the GDB's register array.  */

static void
store_fpregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_fpregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
	perror_with_name (_("Couldn't get NT_FPREGSET registers"));
      else
	{
	  loongarch_fpregset.collect_regset (nullptr, regcache, regnum,
					     &regset, sizeof (regset));
	  if (ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
	    perror_with_name (_("Couldn't set NT_FPREGSET registers"));
	}
    }
}

/* Fill GDB's register array with the Loongson SIMD Extension
   register values from the current thread.  */

static void
fetch_lsxregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_lsxregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0)
	{
	  /* If kernel dose not support lsx, just return. */
	  if (errno == EINVAL)
	    return;

	  perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
	}
      else
	loongarch_lsxregset.supply_regset (nullptr, regcache, -1,
					   &regset, sizeof (regset));
    }
}

/* Store to the current thread the valid Loongson SIMD Extension
   register values in the GDB's register array.  */

static void
store_lsxregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_lsxregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0)
	{
	  /* If kernel dose not support lsx, just return. */
	  if (errno == EINVAL)
	    return;

	  perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
	}
      else
	{
	  loongarch_lsxregset.collect_regset (nullptr, regcache, regnum,
					     &regset, sizeof (regset));
	  if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0)
	    perror_with_name (_("Couldn't set NT_LARCH_LSX registers"));
	}
    }
}

/* Fill GDB's register array with the Loongson Advanced SIMD Extension
   register values from the current thread.  */

static void
fetch_lasxregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_lasxregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_LASX_REGNUM
	  && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0)
	{
	  /* If kernel dose not support lasx, just return. */
	  if (errno == EINVAL)
	    return;

	  perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
	}
      else
	loongarch_lasxregset.supply_regset (nullptr, regcache, -1,
					    &regset, sizeof (regset));
    }
}

/* Store to the current thread the valid Loongson Advanced SIMD Extension
   register values in the GDB's register array.  */

static void
store_lasxregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_lasxregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_LASX_REGNUM
	  && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0)
	{
	  /* If kernel dose not support lasx, just return. */
	  if (errno == EINVAL)
	    return;

	  perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
	}
      else
	{
	  loongarch_lasxregset.collect_regset (nullptr, regcache, regnum,
					      &regset, sizeof (regset));
	  if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0)
	    perror_with_name (_("Couldn't set NT_LARCH_LASX registers"));
	}
    }
}


/* Fill GDB's register array with the lbt register values
   from the current thread.  */

static void
fetch_lbt_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  gdb_byte regset[LOONGARCH_LBT_REGS_SIZE];

  if (regnum == -1
      || (regnum >= LOONGARCH_FIRST_SCR_REGNUM
	  && regnum <= LOONGARCH_FTOP_REGNUM))
    {
      struct iovec iov;

      iov.iov_base = regset;
      iov.iov_len = LOONGARCH_LBT_REGS_SIZE;

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
	{
	  /* If kernel dose not support lbt, just return. */
	  if (errno == EINVAL)
	    return;
	  perror_with_name (_("Couldn't get NT_LARCH_LBT registers"));
	}
      else
	loongarch_lbtregset.supply_regset (nullptr, regcache, -1,
					   regset, LOONGARCH_LBT_REGS_SIZE);
    }
}

/* Store to the current thread the valid lbt register values
   in the GDB's register array.  */

static void
store_lbt_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  gdb_byte regset[LOONGARCH_LBT_REGS_SIZE];

  if (regnum == -1
      || (regnum >= LOONGARCH_FIRST_SCR_REGNUM
	  && regnum <= LOONGARCH_FTOP_REGNUM))
    {
      struct iovec iov;

      iov.iov_base = regset;
      iov.iov_len = LOONGARCH_LBT_REGS_SIZE;

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
	{
	  /* If kernel dose not support lbt, just return. */
	  if (errno == EINVAL)
	    return;
	  perror_with_name (_("Couldn't get NT_LARCH_LBT registers"));
	}
      else
	{
	  loongarch_lbtregset.collect_regset (nullptr, regcache, regnum,
					    regset, LOONGARCH_LBT_REGS_SIZE);
	  if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
	    perror_with_name (_("Couldn't set NT_LARCH_LBT registers"));
	}
    }
}

/* Implement the "fetch_registers" target_ops method.  */

void
loongarch_linux_nat_target::fetch_registers (struct regcache *regcache,
					     int regnum)
{
  pid_t tid = get_ptrace_pid (regcache->ptid ());

  fetch_gregs_from_thread(regcache, regnum, tid);
  fetch_fpregs_from_thread(regcache, regnum, tid);
  fetch_lsxregs_from_thread(regcache, regnum, tid);
  fetch_lasxregs_from_thread(regcache, regnum, tid);
  fetch_lbt_from_thread (regcache, regnum, tid);
}

/* Implement the "store_registers" target_ops method.  */

void
loongarch_linux_nat_target::store_registers (struct regcache *regcache,
					     int regnum)
{
  pid_t tid = get_ptrace_pid (regcache->ptid ());

  store_gregs_to_thread (regcache, regnum, tid);
  store_fpregs_to_thread(regcache, regnum, tid);
  store_lsxregs_to_thread(regcache, regnum, tid);
  store_lasxregs_to_thread(regcache, regnum, tid);
  store_lbt_to_thread (regcache, regnum, tid);
}

/* Return the address in the core dump or inferior of register REGNO.  */

CORE_ADDR
loongarch_linux_nat_target::register_u_offset (struct gdbarch *gdbarch,
					       int regnum, int store_p)
{
  if (regnum >= 0 && regnum < 32)
    return regnum;
  else if (regnum == LOONGARCH_PC_REGNUM)
    return LOONGARCH_PC_REGNUM;
  else
    return -1;
}

static loongarch_linux_nat_target the_loongarch_linux_nat_target;

/* Wrapper functions.  These are only used by libthread_db.  */

void
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregset)
{
  loongarch_gregset.supply_regset (nullptr, regcache, -1, gregset,
				   sizeof (gdb_gregset_t));
}

void
fill_gregset (const struct regcache *regcache, gdb_gregset_t *gregset,
	      int regnum)
{
  loongarch_gregset.collect_regset (nullptr, regcache, regnum, gregset,
				    sizeof (gdb_gregset_t));
}

void
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregset)
{
  loongarch_fpregset.supply_regset (nullptr, regcache, -1, fpregset,
				    sizeof (gdb_fpregset_t));
}

void
fill_fpregset (const struct regcache *regcache, gdb_fpregset_t *fpregset,
	       int regnum)
{
  loongarch_fpregset.collect_regset (nullptr, regcache, regnum, fpregset,
				     sizeof (gdb_fpregset_t));
}

/* Helper for the "stopped_data_address" target method.  Returns TRUE
   if a hardware watchpoint trap at ADDR_TRAP matches a set watchpoint.
   The address of the matched watchpoint is returned in *ADDR_P.  */

static bool
loongarch_stopped_data_address (const struct loongarch_debug_reg_state *state,
			      CORE_ADDR addr_trap, CORE_ADDR *addr_p)
{

  int i;

  for (i = loongarch_num_wp_regs - 1; i >= 0; --i)
    {
      const CORE_ADDR addr_watch = state->dr_addr_wp[i];

      if (state->dr_ref_count_wp[i]
	  && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])
	  && addr_trap == addr_watch)
	{
	  *addr_p = addr_watch;
	  return true;
	}
    }
  return false;
}


/* Returns the number of hardware watchpoints of type TYPE that we can
   set.  Value is positive if we can set CNT watchpoints, zero if
   setting watchpoints of type TYPE is not supported, and negative if
   CNT is more than the maximum number of watchpoints of type TYPE
   that we can support.  TYPE is one of bp_hardware_watchpoint,
   bp_read_watchpoint, bp_write_watchpoint, or bp_hardware_breakpoint.
   CNT is the number of such watchpoints used so far (including this
   one).  OTHERTYPE is non-zero if other types of watchpoints are
   currently enabled.  */

int
loongarch_linux_nat_target::can_use_hw_breakpoint (enum bptype type, int cnt,
						   int othertype)
{
  if (type == bp_hardware_watchpoint || type == bp_read_watchpoint
      || type == bp_access_watchpoint || type == bp_watchpoint)
    {
      if (loongarch_num_wp_regs == 0)
	return 0;
    }
  else if (type == bp_hardware_breakpoint)
    {
      if (loongarch_num_bp_regs == 0)
	return 0;
    }
  else
    gdb_assert_not_reached ("unexpected breakpoint type");

  /* We always return 1 here because we don't have enough information
     about possible overlap of addresses that they want to watch.  As an
     extreme example, consider the case where all the watchpoints watch
     the same address and the same region length: then we can handle a
     virtually unlimited number of watchpoints, due to debug register
     sharing implemented via reference counts.  */
  return 1;

}

int
loongarch_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr,
							int len)
{
  return loongarch_region_ok_for_watchpoint (addr, len);
}

/* Insert a watchpoint to watch a memory region which starts at
   address ADDR and whose length is LEN bytes.  Watch memory accesses
   of the type TYPE.  Return 0 on success, -1 on failure.  */

int
loongarch_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
					      enum target_hw_bp_type type,
					      struct expression *cond)
{
  int ret;
  struct loongarch_debug_reg_state *state
	= loongarch_get_debug_reg_state (inferior_ptid.pid ());

  if (show_debug_regs)
    gdb_printf (gdb_stdlog,
		"insert_watchpoint on entry (addr=0x%08lx, len=%d)\n",
		(unsigned long) addr, len);

  gdb_assert (type != hw_execute);

  ret = loongarch_handle_watchpoint (type, addr, len, 1 /* is_insert */,
				     inferior_ptid, state);

  if (show_debug_regs)
    {
      loongarch_show_debug_reg_state (state,
				      "insert_watchpoint", addr, len, type);
    }

  return ret;

}

/* Remove a watchpoint that watched the memory region which starts at
   address ADDR, whose length is LEN bytes, and for accesses of the
   type TYPE.  Return 0 on success, -1 on failure.  */

int
loongarch_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
					      enum target_hw_bp_type type,
					      struct expression *cond)
{
  int ret;
  struct loongarch_debug_reg_state *state
	= loongarch_get_debug_reg_state (inferior_ptid.pid ());

  if (show_debug_regs)
    gdb_printf (gdb_stdlog,
		"remove_watchpoint on entry (addr=0x%08lx, len=%d)\n",
		(unsigned long) addr, len);

  gdb_assert (type != hw_execute);

  ret = loongarch_handle_watchpoint (type, addr, len, 0 /* is_insert */,
				     inferior_ptid, state);

  if (show_debug_regs)
    {
      loongarch_show_debug_reg_state (state,
				      "remove_watchpoint", addr, len, type);
    }

  return ret;

}

bool
loongarch_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
							  CORE_ADDR start,
							  int length)
{
  return start <= addr && start + length - 1 >= addr;
}


/* Implement the "stopped_data_address" target_ops method.  */

bool
loongarch_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
{
  siginfo_t siginfo;
  struct loongarch_debug_reg_state *state;

  if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
    return false;

  /* This must be a hardware breakpoint.  */
  if (siginfo.si_signo != SIGTRAP || (siginfo.si_code & 0xffff) != TRAP_HWBKPT)
    return false;

  /* Make sure to ignore the top byte, otherwise we may not recognize a
     hardware watchpoint hit.  The stopped data addresses coming from the
     kernel can potentially be tagged addresses.  */
  struct gdbarch *gdbarch = thread_architecture (inferior_ptid);
  const CORE_ADDR addr_trap
    = gdbarch_remove_non_address_bits (gdbarch, (CORE_ADDR) siginfo.si_addr);

  /* Check if the address matches any watched address.  */
  state = loongarch_get_debug_reg_state (inferior_ptid.pid ());

  return loongarch_stopped_data_address (state, addr_trap, addr_p);
}

/* Implement the "stopped_by_watchpoint" target_ops method.  */

bool
loongarch_linux_nat_target::stopped_by_watchpoint ()
{
  CORE_ADDR addr;

  return stopped_data_address (&addr);
}

/* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address.
   Return 0 on success, -1 on failure.  */

int
loongarch_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
						  struct bp_target_info *bp_tgt)
{
  int ret;
  CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
  int len;
  const enum target_hw_bp_type type = hw_execute;
  struct loongarch_debug_reg_state *state
	= loongarch_get_debug_reg_state (inferior_ptid.pid ());

  gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);

  if (show_debug_regs)
    gdb_printf (gdb_stdlog,
		"insert_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n",
		(unsigned long) addr, len);

  ret = loongarch_handle_breakpoint (type, addr, len, 1 /* is_insert */,
				     inferior_ptid, state);

  if (show_debug_regs)
    {
      loongarch_show_debug_reg_state (state,
				      "insert_hw_breakpoint", addr, len, type);
    }

  return ret;
}

/* Remove a hardware-assisted breakpoint at BP_TGT->placed_address.
   Return 0 on success, -1 on failure.  */

int
loongarch_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
						  struct bp_target_info *bp_tgt)
{
  int ret;
  CORE_ADDR addr = bp_tgt->placed_address;
  int len = 4;
  const enum target_hw_bp_type type = hw_execute;
  struct loongarch_debug_reg_state *state
    = loongarch_get_debug_reg_state (inferior_ptid.pid ());

  gdbarch_breakpoint_from_pc (gdbarch, &addr, &len);

  if (show_debug_regs)
    gdb_printf (gdb_stdlog,
		"remove_hw_breakpoint on entry (addr=0x%08lx, len=%d))\n",
		(unsigned long) addr, len);

  ret = loongarch_handle_breakpoint (type, addr, len, 0 /* is_insert */,
				     inferior_ptid, state);

  if (show_debug_regs)
    {
      loongarch_show_debug_reg_state (state,
				      "remove_hw_watchpoint", addr, len, type);
    }

  return ret;
}

/* Implement the virtual inf_ptrace_target::post_startup_inferior method.  */

void
loongarch_linux_nat_target::post_startup_inferior (ptid_t ptid)
{
  low_forget_process (ptid.pid ());
  loongarch_linux_get_debug_reg_capacity (ptid.pid ());
  linux_nat_target::post_startup_inferior (ptid);
}

/* Implement the "post_attach" target_ops method.  */

void
loongarch_linux_nat_target::post_attach (int pid)
{
  low_forget_process (pid);
  /* Get the hardware debug register capacity. If
     loongarch_linux_get_debug_reg_capacity is not called
     (as it is in loongarch_linux_child_post_startup_inferior) then
     software watchpoints will be used instead of hardware
     watchpoints when attaching to a target.  */
  loongarch_linux_get_debug_reg_capacity (pid);
  linux_nat_target::post_attach (pid);
}

/* linux_nat_new_fork hook.   */

void
loongarch_linux_nat_target::low_new_fork (struct lwp_info *parent,
					  pid_t child_pid)
{
  pid_t parent_pid;
  struct loongarch_debug_reg_state *parent_state;
  struct loongarch_debug_reg_state *child_state;

  /* NULL means no watchpoint has ever been set in the parent.  In
     that case, there's nothing to do.  */
  if (parent->arch_private == NULL)
    return;

  /* GDB core assumes the child inherits the watchpoints/hw
     breakpoints of the parent, and will remove them all from the
     forked off process.  Copy the debug registers mirrors into the
     new process so that all breakpoints and watchpoints can be
     removed together.  */

  parent_pid = parent->ptid.pid ();
  parent_state = loongarch_get_debug_reg_state (parent_pid);
  child_state = loongarch_get_debug_reg_state (child_pid);
  *child_state = *parent_state;
}

/* Called whenever GDB is no longer debugging process PID.  It deletes
   data structures that keep track of debug register state.  */

void
loongarch_linux_nat_target::low_forget_process (pid_t pid)
{
  loongarch_remove_debug_reg_state (pid);
}

/* Initialize LoongArch Linux native support.  */

void _initialize_loongarch_linux_nat ();
void
_initialize_loongarch_linux_nat ()
{
  linux_target = &the_loongarch_linux_nat_target;
  add_inf_child_target (&the_loongarch_linux_nat_target);

  /* Add a maintenance command to enable printing the LoongArch internal
     debug registers mirror variables.  */
  add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
			   &show_debug_regs, _("\
Set whether to show the LoongArch debug registers state."), _("\
Show whether to show the LoongArch debug registers state."), _("\
Use \"on\" to enable, \"off\" to disable.\n\
If enabled, the debug registers values are shown when GDB inserts\n\
or removes a hardware breakpoint or watchpoint, and when the inferior\n\
triggers a breakpoint or watchpoint."),
			   NULL,
			   NULL,
			   &maintenance_set_cmdlist,
			   &maintenance_show_cmdlist);
}
