/* Native-dependent code for GNU/Linux AArch64.

   Copyright (C) 2011-2023 Free Software Foundation, Inc.
   Contributed by ARM 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 "defs.h"

#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
#include "linux-nat.h"
#include "target-descriptions.h"
#include "auxv.h"
#include "gdbcmd.h"
#include "aarch64-nat.h"
#include "aarch64-tdep.h"
#include "aarch64-linux-tdep.h"
#include "aarch32-linux-nat.h"
#include "aarch32-tdep.h"
#include "arch/arm.h"
#include "nat/aarch64-linux.h"
#include "nat/aarch64-linux-hw-point.h"
#include "nat/aarch64-sve-linux-ptrace.h"

#include "elf/external.h"
#include "elf/common.h"

#include "nat/gdb_ptrace.h"
#include <sys/utsname.h>
#include <asm/ptrace.h>

#include "gregset.h"
#include "linux-tdep.h"
#include "arm-tdep.h"

/* Defines ps_err_e, struct ps_prochandle.  */
#include "gdb_proc_service.h"
#include "arch-utils.h"

#include "arch/aarch64-mte-linux.h"

#include "nat/aarch64-mte-linux-ptrace.h"

#include <string.h>

#ifndef TRAP_HWBKPT
#define TRAP_HWBKPT 0x0004
#endif

class aarch64_linux_nat_target final
  : public aarch64_nat_target<linux_nat_target>
{
public:
  /* Add our register access methods.  */
  void fetch_registers (struct regcache *, int) override;
  void store_registers (struct regcache *, int) override;

  const struct target_desc *read_description () override;

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

  int can_do_single_step () 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
  { aarch64_linux_new_thread (lp); }
  void low_delete_thread (struct arch_lwp_info *lp) override
  { aarch64_linux_delete_thread (lp); }
  void low_prepare_to_resume (struct lwp_info *lp) override
  { aarch64_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;

  /* Add our siginfo layout converter.  */
  bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
    override;

  struct gdbarch *thread_architecture (ptid_t) override;

  bool supports_memory_tagging () override;

  /* Read memory allocation tags from memory via PTRACE.  */
  bool fetch_memtags (CORE_ADDR address, size_t len,
		      gdb::byte_vector &tags, int type) override;

  /* Write allocation tags to memory via PTRACE.  */
  bool store_memtags (CORE_ADDR address, size_t len,
		      const gdb::byte_vector &tags, int type) override;
};

static aarch64_linux_nat_target the_aarch64_linux_nat_target;

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

void
aarch64_linux_nat_target::low_forget_process (pid_t pid)
{
  aarch64_remove_debug_reg_state (pid);
}

/* Fill GDB's register array with the general-purpose register values
   from the current thread.  */

static void
fetch_gregs_from_thread (struct regcache *regcache)
{
  int ret, tid;
  struct gdbarch *gdbarch = regcache->arch ();
  elf_gregset_t regs;
  struct iovec iovec;

  /* Make sure REGS can hold all registers contents on both aarch64
     and arm.  */
  gdb_static_assert (sizeof (regs) >= 18 * 4);

  tid = regcache->ptid ().lwp ();

  iovec.iov_base = &regs;
  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
    iovec.iov_len = 18 * 4;
  else
    iovec.iov_len = sizeof (regs);

  ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec);
  if (ret < 0)
    perror_with_name (_("Unable to fetch general registers"));

  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
    aarch32_gp_regcache_supply (regcache, (uint32_t *) regs, 1);
  else
    {
      int regno;

      for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
	regcache->raw_supply (regno, &regs[regno - AARCH64_X0_REGNUM]);
    }
}

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

static void
store_gregs_to_thread (const struct regcache *regcache)
{
  int ret, tid;
  elf_gregset_t regs;
  struct iovec iovec;
  struct gdbarch *gdbarch = regcache->arch ();

  /* Make sure REGS can hold all registers contents on both aarch64
     and arm.  */
  gdb_static_assert (sizeof (regs) >= 18 * 4);
  tid = regcache->ptid ().lwp ();

  iovec.iov_base = &regs;
  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
    iovec.iov_len = 18 * 4;
  else
    iovec.iov_len = sizeof (regs);

  ret = ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec);
  if (ret < 0)
    perror_with_name (_("Unable to fetch general registers"));

  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
    aarch32_gp_regcache_collect (regcache, (uint32_t *) regs, 1);
  else
    {
      int regno;

      for (regno = AARCH64_X0_REGNUM; regno <= AARCH64_CPSR_REGNUM; regno++)
	if (REG_VALID == regcache->get_register_status (regno))
	  regcache->raw_collect (regno, &regs[regno - AARCH64_X0_REGNUM]);
    }

  ret = ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, &iovec);
  if (ret < 0)
    perror_with_name (_("Unable to store general registers"));
}

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

static void
fetch_fpregs_from_thread (struct regcache *regcache)
{
  int ret, tid;
  elf_fpregset_t regs;
  struct iovec iovec;
  struct gdbarch *gdbarch = regcache->arch ();

  /* Make sure REGS can hold all VFP registers contents on both aarch64
     and arm.  */
  gdb_static_assert (sizeof regs >= ARM_VFP3_REGS_SIZE);

  tid = regcache->ptid ().lwp ();

  iovec.iov_base = &regs;

  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
    {
      iovec.iov_len = ARM_VFP3_REGS_SIZE;

      ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iovec);
      if (ret < 0)
	perror_with_name (_("Unable to fetch VFP registers"));

      aarch32_vfp_regcache_supply (regcache, (gdb_byte *) &regs, 32);
    }
  else
    {
      int regno;

      iovec.iov_len = sizeof (regs);

      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec);
      if (ret < 0)
	perror_with_name (_("Unable to fetch vFP/SIMD registers"));

      for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
	regcache->raw_supply (regno, &regs.vregs[regno - AARCH64_V0_REGNUM]);

      regcache->raw_supply (AARCH64_FPSR_REGNUM, &regs.fpsr);
      regcache->raw_supply (AARCH64_FPCR_REGNUM, &regs.fpcr);
    }
}

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

static void
store_fpregs_to_thread (const struct regcache *regcache)
{
  int ret, tid;
  elf_fpregset_t regs;
  struct iovec iovec;
  struct gdbarch *gdbarch = regcache->arch ();

  /* Make sure REGS can hold all VFP registers contents on both aarch64
     and arm.  */
  gdb_static_assert (sizeof regs >= ARM_VFP3_REGS_SIZE);
  tid = regcache->ptid ().lwp ();

  iovec.iov_base = &regs;

  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
    {
      iovec.iov_len = ARM_VFP3_REGS_SIZE;

      ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iovec);
      if (ret < 0)
	perror_with_name (_("Unable to fetch VFP registers"));

      aarch32_vfp_regcache_collect (regcache, (gdb_byte *) &regs, 32);
    }
  else
    {
      int regno;

      iovec.iov_len = sizeof (regs);

      ret = ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec);
      if (ret < 0)
	perror_with_name (_("Unable to fetch FP/SIMD registers"));

      for (regno = AARCH64_V0_REGNUM; regno <= AARCH64_V31_REGNUM; regno++)
	if (REG_VALID == regcache->get_register_status (regno))
	  regcache->raw_collect
	    (regno, (char *) &regs.vregs[regno - AARCH64_V0_REGNUM]);

      if (REG_VALID == regcache->get_register_status (AARCH64_FPSR_REGNUM))
	regcache->raw_collect (AARCH64_FPSR_REGNUM, (char *) &regs.fpsr);
      if (REG_VALID == regcache->get_register_status (AARCH64_FPCR_REGNUM))
	regcache->raw_collect (AARCH64_FPCR_REGNUM, (char *) &regs.fpcr);
    }

  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
    {
      ret = ptrace (PTRACE_SETREGSET, tid, NT_ARM_VFP, &iovec);
      if (ret < 0)
	perror_with_name (_("Unable to store VFP registers"));
    }
  else
    {
      ret = ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, &iovec);
      if (ret < 0)
	perror_with_name (_("Unable to store FP/SIMD registers"));
    }
}

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

static void
fetch_sveregs_from_thread (struct regcache *regcache)
{
  std::unique_ptr<gdb_byte[]> base
    = aarch64_sve_get_sveregs (regcache->ptid ().lwp ());
  aarch64_sve_regs_copy_to_reg_buf (regcache, base.get ());
}

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

static void
store_sveregs_to_thread (struct regcache *regcache)
{
  int ret;
  struct iovec iovec;
  int tid = regcache->ptid ().lwp ();

  /* First store vector length to the thread.  This is done first to ensure the
     ptrace buffers read from the kernel are the correct size.  */
  if (!aarch64_sve_set_vq (tid, regcache))
    perror_with_name (_("Unable to set VG register"));

  /* Obtain a dump of SVE registers from ptrace.  */
  std::unique_ptr<gdb_byte[]> base = aarch64_sve_get_sveregs (tid);

  /* Overwrite with regcache state.  */
  aarch64_sve_regs_copy_from_reg_buf (regcache, base.get ());

  /* Write back to the kernel.  */
  iovec.iov_base = base.get ();
  iovec.iov_len = ((struct user_sve_header *) base.get ())->size;
  ret = ptrace (PTRACE_SETREGSET, tid, NT_ARM_SVE, &iovec);

  if (ret < 0)
    perror_with_name (_("Unable to store sve registers"));
}

/* Fill GDB's register array with the pointer authentication mask values from
   the current thread.  */

static void
fetch_pauth_masks_from_thread (struct regcache *regcache)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
  int ret;
  struct iovec iovec;
  uint64_t pauth_regset[2] = {0, 0};
  int tid = regcache->ptid ().lwp ();

  iovec.iov_base = &pauth_regset;
  iovec.iov_len = sizeof (pauth_regset);

  ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_PAC_MASK, &iovec);
  if (ret != 0)
    perror_with_name (_("unable to fetch pauth registers"));

  regcache->raw_supply (AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base),
			&pauth_regset[0]);
  regcache->raw_supply (AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base),
			&pauth_regset[1]);
}

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

static void
fetch_mteregs_from_thread (struct regcache *regcache)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
  int regno = tdep->mte_reg_base;

  gdb_assert (regno != -1);

  uint64_t tag_ctl = 0;
  struct iovec iovec;

  iovec.iov_base = &tag_ctl;
  iovec.iov_len = sizeof (tag_ctl);

  int tid = get_ptrace_pid (regcache->ptid ());
  if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_TAGGED_ADDR_CTRL, &iovec) != 0)
      perror_with_name (_("unable to fetch MTE registers"));

  regcache->raw_supply (regno, &tag_ctl);
}

/* Store to the current thread the valid MTE register set in the GDB's
   register array.  */

static void
store_mteregs_to_thread (struct regcache *regcache)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
  int regno = tdep->mte_reg_base;

  gdb_assert (regno != -1);

  uint64_t tag_ctl = 0;

  if (REG_VALID != regcache->get_register_status (regno))
    return;

  regcache->raw_collect (regno, (char *) &tag_ctl);

  struct iovec iovec;

  iovec.iov_base = &tag_ctl;
  iovec.iov_len = sizeof (tag_ctl);

  int tid = get_ptrace_pid (regcache->ptid ());
  if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_TAGGED_ADDR_CTRL, &iovec) != 0)
    perror_with_name (_("unable to store MTE registers"));
}

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

static void
fetch_tlsregs_from_thread (struct regcache *regcache)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
  int regno = tdep->tls_regnum_base;

  gdb_assert (regno != -1);
  gdb_assert (tdep->tls_register_count > 0);

  uint64_t tpidrs[tdep->tls_register_count];
  memset(tpidrs, 0, sizeof(tpidrs));

  struct iovec iovec;
  iovec.iov_base = tpidrs;
  iovec.iov_len = sizeof (tpidrs);

  int tid = get_ptrace_pid (regcache->ptid ());
  if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_TLS, &iovec) != 0)
      perror_with_name (_("unable to fetch TLS registers"));

  for (int i = 0; i < tdep->tls_register_count; i++)
    regcache->raw_supply (regno + i, &tpidrs[i]);
}

/* Store to the current thread the valid TLS register set in GDB's
   register array.  */

static void
store_tlsregs_to_thread (struct regcache *regcache)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());
  int regno = tdep->tls_regnum_base;

  gdb_assert (regno != -1);
  gdb_assert (tdep->tls_register_count > 0);

  uint64_t tpidrs[tdep->tls_register_count];
  memset(tpidrs, 0, sizeof(tpidrs));

  for (int i = 0; i < tdep->tls_register_count; i++)
    {
      if (REG_VALID != regcache->get_register_status (regno + i))
	continue;

      regcache->raw_collect (regno + i, (char *) &tpidrs[i]);
    }

  struct iovec iovec;
  iovec.iov_base = &tpidrs;
  iovec.iov_len = sizeof (tpidrs);

  int tid = get_ptrace_pid (regcache->ptid ());
  if (ptrace (PTRACE_SETREGSET, tid, NT_ARM_TLS, &iovec) != 0)
    perror_with_name (_("unable to store TLS register"));
}

/* The AArch64 version of the "fetch_registers" target_ops method.  Fetch
   REGNO from the target and place the result into REGCACHE.  */

static void
aarch64_fetch_registers (struct regcache *regcache, int regno)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());

  if (regno == -1)
    {
      fetch_gregs_from_thread (regcache);
      if (tdep->has_sve ())
	fetch_sveregs_from_thread (regcache);
      else
	fetch_fpregs_from_thread (regcache);

      if (tdep->has_pauth ())
	fetch_pauth_masks_from_thread (regcache);

      if (tdep->has_mte ())
	fetch_mteregs_from_thread (regcache);

      if (tdep->has_tls ())
	fetch_tlsregs_from_thread (regcache);
    }
  else if (regno < AARCH64_V0_REGNUM)
    fetch_gregs_from_thread (regcache);
  else if (tdep->has_sve ())
    fetch_sveregs_from_thread (regcache);
  else
    fetch_fpregs_from_thread (regcache);

  if (tdep->has_pauth ())
    {
      if (regno == AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base)
	  || regno == AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base))
	fetch_pauth_masks_from_thread (regcache);
    }

  /* Fetch individual MTE registers.  */
  if (tdep->has_mte ()
      && (regno == tdep->mte_reg_base))
    fetch_mteregs_from_thread (regcache);

  if (tdep->has_tls ()
      && regno >= tdep->tls_regnum_base
      && regno < tdep->tls_regnum_base + tdep->tls_register_count)
    fetch_tlsregs_from_thread (regcache);
}

/* A version of the "fetch_registers" target_ops method used when running
   32-bit ARM code on an AArch64 target.  Fetch REGNO from the target and
   place the result into REGCACHE.  */

static void
aarch32_fetch_registers (struct regcache *regcache, int regno)
{
  arm_gdbarch_tdep *tdep
    = gdbarch_tdep<arm_gdbarch_tdep> (regcache->arch ());

  if (regno == -1)
    {
      fetch_gregs_from_thread (regcache);
      if (tdep->vfp_register_count > 0)
	fetch_fpregs_from_thread (regcache);
    }
  else if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
    fetch_gregs_from_thread (regcache);
  else if (tdep->vfp_register_count > 0
	   && regno >= ARM_D0_REGNUM
	   && (regno < ARM_D0_REGNUM + tdep->vfp_register_count
	       || regno == ARM_FPSCR_REGNUM))
    fetch_fpregs_from_thread (regcache);
}

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

void
aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
					   int regno)
{
  if (gdbarch_bfd_arch_info (regcache->arch ())->bits_per_word == 32)
    aarch32_fetch_registers (regcache, regno);
  else
    aarch64_fetch_registers (regcache, regno);
}

/* The AArch64 version of the "store_registers" target_ops method.  Copy
   the value of register REGNO from REGCACHE into the the target.  */

static void
aarch64_store_registers (struct regcache *regcache, int regno)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());

  if (regno == -1)
    {
      store_gregs_to_thread (regcache);
      if (tdep->has_sve ())
	store_sveregs_to_thread (regcache);
      else
	store_fpregs_to_thread (regcache);

      if (tdep->has_mte ())
	store_mteregs_to_thread (regcache);

      if (tdep->has_tls ())
	store_tlsregs_to_thread (regcache);
    }
  else if (regno < AARCH64_V0_REGNUM)
    store_gregs_to_thread (regcache);
  else if (tdep->has_sve ())
    store_sveregs_to_thread (regcache);
  else
    store_fpregs_to_thread (regcache);

  /* Store MTE registers.  */
  if (tdep->has_mte ()
      && (regno == tdep->mte_reg_base))
    store_mteregs_to_thread (regcache);

  if (tdep->has_tls ()
      && regno >= tdep->tls_regnum_base
      && regno < tdep->tls_regnum_base + tdep->tls_register_count)
    store_tlsregs_to_thread (regcache);
}

/* A version of the "store_registers" target_ops method used when running
   32-bit ARM code on an AArch64 target.  Copy the value of register REGNO
   from REGCACHE into the the target.  */

static void
aarch32_store_registers (struct regcache *regcache, int regno)
{
  arm_gdbarch_tdep *tdep
    = gdbarch_tdep<arm_gdbarch_tdep> (regcache->arch ());

  if (regno == -1)
    {
      store_gregs_to_thread (regcache);
      if (tdep->vfp_register_count > 0)
	store_fpregs_to_thread (regcache);
    }
  else if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
    store_gregs_to_thread (regcache);
  else if (tdep->vfp_register_count > 0
	   && regno >= ARM_D0_REGNUM
	   && (regno < ARM_D0_REGNUM + tdep->vfp_register_count
	       || regno == ARM_FPSCR_REGNUM))
    store_fpregs_to_thread (regcache);
}

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

void
aarch64_linux_nat_target::store_registers (struct regcache *regcache,
					   int regno)
{
  if (gdbarch_bfd_arch_info (regcache->arch ())->bits_per_word == 32)
    aarch32_store_registers (regcache, regno);
  else
    aarch64_store_registers (regcache, regno);
}

/* Fill register REGNO (if it is a general-purpose register) in
   *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
   do this for all registers.  */

void
fill_gregset (const struct regcache *regcache,
	      gdb_gregset_t *gregsetp, int regno)
{
  regcache_collect_regset (&aarch64_linux_gregset, regcache,
			   regno, (gdb_byte *) gregsetp,
			   AARCH64_LINUX_SIZEOF_GREGSET);
}

/* Fill GDB's register array with the general-purpose register values
   in *GREGSETP.  */

void
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
{
  regcache_supply_regset (&aarch64_linux_gregset, regcache, -1,
			  (const gdb_byte *) gregsetp,
			  AARCH64_LINUX_SIZEOF_GREGSET);
}

/* Fill register REGNO (if it is a floating-point register) in
   *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
   do this for all registers.  */

void
fill_fpregset (const struct regcache *regcache,
	       gdb_fpregset_t *fpregsetp, int regno)
{
  regcache_collect_regset (&aarch64_linux_fpregset, regcache,
			   regno, (gdb_byte *) fpregsetp,
			   AARCH64_LINUX_SIZEOF_FPREGSET);
}

/* Fill GDB's register array with the floating-point register values
   in *FPREGSETP.  */

void
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
{
  regcache_supply_regset (&aarch64_linux_fpregset, regcache, -1,
			  (const gdb_byte *) fpregsetp,
			  AARCH64_LINUX_SIZEOF_FPREGSET);
}

/* linux_nat_new_fork hook.   */

void
aarch64_linux_nat_target::low_new_fork (struct lwp_info *parent,
					pid_t child_pid)
{
  pid_t parent_pid;
  struct aarch64_debug_reg_state *parent_state;
  struct aarch64_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 = aarch64_get_debug_reg_state (parent_pid);
  child_state = aarch64_get_debug_reg_state (child_pid);
  *child_state = *parent_state;
}


/* Called by libthread_db.  Returns a pointer to the thread local
   storage (or its descriptor).  */

ps_err_e
ps_get_thread_area (struct ps_prochandle *ph,
		    lwpid_t lwpid, int idx, void **base)
{
  int is_64bit_p
    = (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 64);

  return aarch64_ps_get_thread_area (ph, lwpid, idx, base, is_64bit_p);
}


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

void
aarch64_linux_nat_target::post_startup_inferior (ptid_t ptid)
{
  low_forget_process (ptid.pid ());
  aarch64_linux_get_debug_reg_capacity (ptid.pid ());
  linux_nat_target::post_startup_inferior (ptid);
}

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

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

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

const struct target_desc *
aarch64_linux_nat_target::read_description ()
{
  int ret, tid;
  gdb_byte regbuf[ARM_VFP3_REGS_SIZE];
  struct iovec iovec;

  tid = inferior_ptid.pid ();

  iovec.iov_base = regbuf;
  iovec.iov_len = ARM_VFP3_REGS_SIZE;

  ret = ptrace (PTRACE_GETREGSET, tid, NT_ARM_VFP, &iovec);
  if (ret == 0)
    return aarch32_read_description ();

  CORE_ADDR hwcap = linux_get_hwcap ();
  CORE_ADDR hwcap2 = linux_get_hwcap2 ();

  aarch64_features features;
  features.vq = aarch64_sve_get_vq (tid);
  features.pauth = hwcap & AARCH64_HWCAP_PACA;
  features.mte = hwcap2 & HWCAP2_MTE;
  features.tls = aarch64_tls_register_count (tid);

  return aarch64_read_description (features);
}

/* Convert a native/host siginfo object, into/from the siginfo in the
   layout of the inferiors' architecture.  Returns true if any
   conversion was done; false otherwise.  If DIRECTION is 1, then copy
   from INF to NATIVE.  If DIRECTION is 0, copy from NATIVE to
   INF.  */

bool
aarch64_linux_nat_target::low_siginfo_fixup (siginfo_t *native, gdb_byte *inf,
					     int direction)
{
  struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());

  /* Is the inferior 32-bit?  If so, then do fixup the siginfo
     object.  */
  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
    {
      if (direction == 0)
	aarch64_compat_siginfo_from_siginfo ((struct compat_siginfo *) inf,
					     native);
      else
	aarch64_siginfo_from_compat_siginfo (native,
					     (struct compat_siginfo *) inf);

      return true;
    }

  return false;
}

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

bool
aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
{
  siginfo_t siginfo;
  struct aarch64_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 = aarch64_get_debug_reg_state (inferior_ptid.pid ());
  return aarch64_stopped_data_address (state, addr_trap, addr_p);
}

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

bool
aarch64_linux_nat_target::stopped_by_watchpoint ()
{
  CORE_ADDR addr;

  return stopped_data_address (&addr);
}

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

int
aarch64_linux_nat_target::can_do_single_step ()
{
  return 1;
}

/* Implement the "thread_architecture" target_ops method.

   Returns the gdbarch for the thread identified by PTID.  If the thread in
   question is a 32-bit ARM thread, then the architecture returned will be
   that of the process itself.

   If the thread is an AArch64 thread then we need to check the current
   vector length; if the vector length has changed then we need to lookup a
   new gdbarch that matches the new vector length.  */

struct gdbarch *
aarch64_linux_nat_target::thread_architecture (ptid_t ptid)
{
  /* Find the current gdbarch the same way as process_stratum_target.  */
  inferior *inf = find_inferior_ptid (this, ptid);
  gdb_assert (inf != NULL);

  /* If this is a 32-bit architecture, then this is ARM, not AArch64.
     There's no SVE vectors here, so just return the inferior
     architecture.  */
  if (gdbarch_bfd_arch_info (inf->gdbarch)->bits_per_word == 32)
    return inf->gdbarch;

  /* Only return it if the current vector length matches the one in the tdep.  */
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (inf->gdbarch);
  uint64_t vq = aarch64_sve_get_vq (ptid.lwp ());
  if (vq == tdep->vq)
    return inf->gdbarch;

  /* We reach here if the vector length for the thread is different from its
     value at process start.  Lookup gdbarch via info (potentially creating a
     new one) by using a target description that corresponds to the new vq value
     and the current architecture features.  */

  const struct target_desc *tdesc = gdbarch_target_desc (inf->gdbarch);
  aarch64_features features = aarch64_features_from_target_desc (tdesc);
  features.vq = vq;

  struct gdbarch_info info;
  info.bfd_arch_info = bfd_lookup_arch (bfd_arch_aarch64, bfd_mach_aarch64);
  info.target_desc = aarch64_read_description (features);
  return gdbarch_find_by_info (info);
}

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

bool
aarch64_linux_nat_target::supports_memory_tagging ()
{
  return (linux_get_hwcap2 () & HWCAP2_MTE) != 0;
}

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

bool
aarch64_linux_nat_target::fetch_memtags (CORE_ADDR address, size_t len,
					 gdb::byte_vector &tags, int type)
{
  int tid = get_ptrace_pid (inferior_ptid);

  /* Allocation tags?  */
  if (type == static_cast<int> (aarch64_memtag_type::mte_allocation))
    return aarch64_mte_fetch_memtags (tid, address, len, tags);

  return false;
}

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

bool
aarch64_linux_nat_target::store_memtags (CORE_ADDR address, size_t len,
					 const gdb::byte_vector &tags, int type)
{
  int tid = get_ptrace_pid (inferior_ptid);

  /* Allocation tags?  */
  if (type == static_cast<int> (aarch64_memtag_type::mte_allocation))
    return aarch64_mte_store_memtags (tid, address, len, tags);

  return false;
}

void _initialize_aarch64_linux_nat ();
void
_initialize_aarch64_linux_nat ()
{
  aarch64_initialize_hw_point ();

  /* Register the target.  */
  linux_target = &the_aarch64_linux_nat_target;
  add_inf_child_target (&the_aarch64_linux_nat_target);
}
