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

   Copyright (C) 2011-2022 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"

/* 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"

#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
    = (aarch64_gdbarch_tdep *) 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
    = (aarch64_gdbarch_tdep *) 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
    = (aarch64_gdbarch_tdep *) 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
    = (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());
  int regno = tdep->tls_regnum;

  gdb_assert (regno != -1);

  uint64_t tpidr = 0;
  struct iovec iovec;

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

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

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

/* 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
    = (aarch64_gdbarch_tdep *) gdbarch_tdep (regcache->arch ());
  int regno = tdep->tls_regnum;

  gdb_assert (regno != -1);

  uint64_t tpidr = 0;

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

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

  struct iovec iovec;

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

  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."));
}

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

void
aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
					   int regno)
{
  aarch64_gdbarch_tdep *tdep
    = (aarch64_gdbarch_tdep *) 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)
    fetch_tlsregs_from_thread (regcache);
}

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

void
aarch64_linux_nat_target::store_registers (struct regcache *regcache,
					   int regno)
{
  aarch64_gdbarch_tdep *tdep
    = (aarch64_gdbarch_tdep *) 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)
    store_tlsregs_to_thread (regcache);
}

/* 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 (this);
  CORE_ADDR hwcap2 = linux_get_hwcap2 (this);

  bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
  bool mte_p = hwcap2 & HWCAP2_MTE;

  return aarch64_read_description (aarch64_sve_get_vq (tid), pauth_p, mte_p,
				   true);
}

/* 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
    = address_significant (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.  */

struct gdbarch *
aarch64_linux_nat_target::thread_architecture (ptid_t ptid)
{
  /* Return the gdbarch for the current thread.  If the vector length has
     changed since the last time this was called, then do a further lookup.  */

  uint64_t vq = aarch64_sve_get_vq (ptid.lwp ());

  /* Find the current gdbarch the same way as process_stratum_target.  Only
     return it if the current vector length matches the one in the tdep.  */
  inferior *inf = find_inferior_ptid (this, ptid);
  gdb_assert (inf != NULL);
  aarch64_gdbarch_tdep *tdep
    = (aarch64_gdbarch_tdep *) gdbarch_tdep (inf->gdbarch);
  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), stashing the vector length inside id.  Use -1 for when SVE
     unavailable, to distinguish from an unset value of 0.  */
  struct gdbarch_info info;
  info.bfd_arch_info = bfd_lookup_arch (bfd_arch_aarch64, bfd_mach_aarch64);
  info.id = (int *) (vq == 0 ? -1 : vq);
  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 (this) & 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);
}
