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

   Copyright (C) 2011-2025 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 "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
#include "linux-nat.h"
#include "target-descriptions.h"
#include "auxv.h"
#include "cli/cli-cmds.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-scalable-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 "arch/aarch64-scalable-linux.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;

  /* 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_init_process (pid_t 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;
  /* Check if an address is tagged.  */
  bool is_address_tagged (gdbarch *gdbarch, CORE_ADDR address) 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.  */
  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.  */
  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.  */
  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.  */
  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 REGCACHE with the valid SVE register values from the thread
   associated with REGCACHE.

   This function handles reading data from SVE or SSVE states, depending
   on which state is active at the moment.  */

static void
fetch_sveregs_from_thread (struct regcache *regcache)
{
  /* Fetch SVE state from the thread and copy it into the register cache.  */
  aarch64_sve_regs_copy_to_reg_buf (regcache->ptid ().lwp (), regcache);
}

/* Store the valid SVE register values from GDB's REGCACHE to the thread
   associated with REGCACHE.

   This function handles writing data to SVE or SSVE states, depending
   on which state is active at the moment.  */

static void
store_sveregs_to_thread (struct regcache *regcache)
{
  /* Fetch SVE state from the register cache and update the thread TID with
     it.  */
  aarch64_sve_regs_copy_from_reg_buf (regcache->ptid ().lwp (), regcache);
}

/* Fill GDB's REGCACHE with the ZA register set contents from the
   thread associated with REGCACHE.  If there is no active ZA register state,
   make the ZA register contents zero.  */

static void
fetch_za_from_thread (struct regcache *regcache)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());

  /* Read ZA state from the thread to the register cache.  */
  aarch64_za_regs_copy_to_reg_buf (regcache->ptid ().lwp (),
				   regcache,
				   tdep->sme_za_regnum,
				   tdep->sme_svg_regnum,
				   tdep->sme_svcr_regnum);
}

/* Store the NT_ARM_ZA register set contents from GDB's REGCACHE to the thread
   associated with REGCACHE.  */

static void
store_za_to_thread (struct regcache *regcache)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());

  /* Write ZA state from the register cache to the thread.  */
  aarch64_za_regs_copy_from_reg_buf (regcache->ptid ().lwp (),
				     regcache,
				     tdep->sme_za_regnum,
				     tdep->sme_svg_regnum,
				     tdep->sme_svcr_regnum);
}

/* Fill GDB's REGCACHE with the ZT register set contents from the
   thread associated with REGCACHE.  If there is no active ZA register state,
   make the ZT register contents zero.  */

static void
fetch_zt_from_thread (struct regcache *regcache)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());

  /* Read ZT state from the thread to the register cache.  */
  aarch64_zt_regs_copy_to_reg_buf (regcache->ptid ().lwp (),
				   regcache,
				   tdep->sme2_zt0_regnum);
}

/* Store the NT_ARM_ZT register set contents from GDB's REGCACHE to the
   thread associated with REGCACHE.  */

static void
store_zt_to_thread (struct regcache *regcache)
{
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (regcache->arch ());

  /* Write ZT state from the register cache to the thread.  */
  aarch64_zt_regs_copy_from_reg_buf (regcache->ptid ().lwp (),
				     regcache,
				     tdep->sme2_zt0_regnum);
}

/* 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);

  std::vector<uint64_t> tpidrs (tdep->tls_register_count);

  struct iovec iovec;
  iovec.iov_base = tpidrs.data ();
  iovec.iov_len = tpidrs.size () * sizeof (tpidrs[0]);

  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);

  std::vector<uint64_t> tpidrs (tdep->tls_register_count);

  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.data ();
  iovec.iov_len = tpidrs.size () * sizeof (tpidrs[0]);

  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 ());

  /* Do we need to fetch all registers?  */
  if (regno == -1)
    {
      fetch_gregs_from_thread (regcache);

      /* We attempt to fetch SVE registers if there is support for either
	 SVE or SME (due to the SSVE state of SME).  */
      if (tdep->has_sve () || tdep->has_sme ())
	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);

      if (tdep->has_sme ())
	fetch_za_from_thread (regcache);

      if (tdep->has_sme2 ())
	fetch_zt_from_thread (regcache);
    }
  /* General purpose register?  */
  else if (regno < AARCH64_V0_REGNUM)
    fetch_gregs_from_thread (regcache);
  /* SVE register?  */
  else if ((tdep->has_sve () || tdep->has_sme ())
	   && regno <= AARCH64_SVE_VG_REGNUM)
    fetch_sveregs_from_thread (regcache);
  /* FPSIMD register?  */
  else if (regno <= AARCH64_FPCR_REGNUM)
    fetch_fpregs_from_thread (regcache);
  /* PAuth register?  */
  else if (tdep->has_pauth ()
	   && (regno == AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base)
	       || regno == AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base)))
    fetch_pauth_masks_from_thread (regcache);
  /* SME register?  */
  else if (tdep->has_sme () && regno >= tdep->sme_reg_base
	   && regno < tdep->sme_reg_base + 3)
    fetch_za_from_thread (regcache);
  /* SME2 register?  */
  else if (tdep->has_sme2 () && regno == tdep->sme2_zt0_regnum)
    fetch_zt_from_thread (regcache);
  /* MTE register?  */
  else if (tdep->has_mte ()
	   && (regno == tdep->mte_reg_base))
    fetch_mteregs_from_thread (regcache);
  /* TLS register?  */
  else 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 ());

  /* Do we need to store all registers?  */
  if (regno == -1)
    {
      store_gregs_to_thread (regcache);

      /* We attempt to store SVE registers if there is support for either
	 SVE or SME (due to the SSVE state of SME).  */
      if (tdep->has_sve () || tdep->has_sme ())
	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);

      if (tdep->has_sme ())
	store_za_to_thread (regcache);

      if (tdep->has_sme2 ())
	store_zt_to_thread (regcache);
    }
  /* General purpose register?  */
  else if (regno < AARCH64_V0_REGNUM)
    store_gregs_to_thread (regcache);
  /* SVE register?  */
  else if ((tdep->has_sve () || tdep->has_sme ())
	   && regno <= AARCH64_SVE_VG_REGNUM)
    store_sveregs_to_thread (regcache);
  /* FPSIMD register?  */
  else if (regno <= AARCH64_FPCR_REGNUM)
    store_fpregs_to_thread (regcache);
  /* SME register?  */
  else if (tdep->has_sme () && regno >= tdep->sme_reg_base
	   && regno < tdep->sme_reg_base + 3)
    store_za_to_thread (regcache);
  else if (tdep->has_sme2 () && regno == tdep->sme2_zt0_regnum)
    store_zt_to_thread (regcache);
  /* MTE register?  */
  else if (tdep->has_mte ()
	   && (regno == tdep->mte_reg_base))
    store_mteregs_to_thread (regcache);
  /* TLS register?  */
  else if (tdep->has_tls ()
	   && regno >= tdep->tls_regnum_base
	   && regno < tdep->tls_regnum_base + tdep->tls_register_count)
    store_tlsregs_to_thread (regcache);

  /* PAuth registers are read-only.  */
}

/* 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)
{
  gdbarch *arch = current_inferior ()->arch ();
  int is_64bit_p = (gdbarch_bfd_arch_info (arch)->bits_per_word == 64);

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

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

void
aarch64_linux_nat_target::low_init_process (pid_t pid)
{
  low_forget_process (pid);
  /* Set the hardware debug register capacity.  This requires the process to be
     ptrace-stopped, otherwise detection will fail and software watchpoints will
     be used instead of hardware.  If we allow this to be done lazily, we
     cannot guarantee that it's called when the process is ptrace-stopped, so
     do it now.  */
  aarch64_linux_get_debug_reg_capacity (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;

  if (inferior_ptid == null_ptid)
    return this->beneath ()->read_description ();

  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 (false);

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

  aarch64_features features;
  /* SVE/SSVE check.  Reading VQ may return either the regular vector length
     or the streaming vector length, depending on whether streaming mode is
     active or not.  */
  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);
  /* SME feature check.  */
  features.svq = aarch64_za_get_svq (tid);

  /* Check for SME2 support.  */
  if ((hwcap2 & HWCAP2_SME2) || (hwcap2 & HWCAP2_SME2P1))
    features.sme2 = supports_zt_registers (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
    = aarch64_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 ()
{
  return stopped_data_address (nullptr);
}

/* 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->arch ())->bits_per_word == 32)
    return inf->arch ();

  /* Only return the inferior's gdbarch if both vq and svq match the ones in
     the tdep.  */
  aarch64_gdbarch_tdep *tdep
    = gdbarch_tdep<aarch64_gdbarch_tdep> (inf->arch ());
  uint64_t vq = aarch64_sve_get_vq (ptid.lwp ());
  uint64_t svq = aarch64_za_get_svq (ptid.lwp ());
  if (vq == tdep->vq && svq == tdep->sme_svq)
    return inf->arch ();

  /* We reach here if any 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/svq
     value and the current architecture features.  */

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

  /* Check for the SME2 feature.  */
  features.sme2 = supports_zt_registers (ptid.lwp ());

  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;
}

bool
aarch64_linux_nat_target::is_address_tagged (gdbarch *gdbarch, CORE_ADDR address)
{
  /* Here we take a detour going to linux-tdep layer to read the smaps file,
     because currently there isn't a better way to get that information to
     check if a given address is tagged or not.

     In the future, if this check is made, for instance, available via PTRACE,
     it will be possible to drop the smaps path in favor of a PTRACE one for
     this check.  */
  return gdbarch_tagged_address_p (gdbarch, address);
}

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