/* Common Linux native ptrace code for AArch64 MTE.

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

   This file is part of GDB.

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

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

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

#include "gdbsupport/byte-vector.h"

#include "linux-ptrace.h"

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

#include <sys/uio.h>

/* Helper function to display various possible errors when reading
   MTE tags.  */

[[noreturn]] static void
aarch64_mte_linux_peek_error (int error)
{
  switch (error)
    {
    case EIO:
      perror_with_name (_("PEEKMTETAGS not supported"));
      break;
    case EFAULT:
      perror_with_name (_("Couldn't fetch allocation tags"));
      break;
    case EOPNOTSUPP:
      perror_with_name (_("PROT_MTE not enabled for requested address"));
    default:
      perror_with_name (_("Unknown MTE error"));
      break;
    }
}

/* Helper function to display various possible errors when writing
   MTE tags.  */

[[noreturn]] static void
aarch64_mte_linux_poke_error (int error)
{
  switch (error)
    {
    case EIO:
      perror_with_name (_("POKEMTETAGS not supported"));
      break;
    case EFAULT:
      perror_with_name (_("Couldn't store allocation tags"));
      break;
    case EOPNOTSUPP:
      perror_with_name (_("PROT_MTE not enabled for requested address"));
    default:
      perror_with_name (_("Unknown MTE error"));
      break;
    }
}

/* Helper to prepare a vector of tags to be passed on to the kernel.  The
   main purpose of this function is to optimize the number of calls to
   ptrace if we're writing too many tags at once, like a pattern fill
   request.

   Return a vector of tags of up to MAX_SIZE size, containing the tags that
   must be passed on to the kernel, extracted from TAGS, starting at POS.
   GRANULES is the number of tag granules to be modified.  */

static gdb::byte_vector
prepare_tag_vector (size_t granules, const gdb::byte_vector &tags, size_t pos,
		    size_t max_size)
{
  gdb::byte_vector t;

  if (granules == 0)
    return t;

  gdb_assert (tags.size () > 0 && max_size > 0);

  if (granules > AARCH64_MTE_TAGS_MAX_SIZE)
    t.resize (AARCH64_MTE_TAGS_MAX_SIZE);
  else
    t.resize (granules);

  size_t tag_count = tags.size ();

  for (size_t i = 0; i < t.size (); i++)
    t[i] = tags[(pos + i) % tag_count];

  return t;
}

/* See nat/aarch64-mte-linux-ptrace.h */

bool
aarch64_mte_fetch_memtags (int tid, CORE_ADDR address, size_t len,
			   gdb::byte_vector &tags)
{
  size_t ntags = aarch64_mte_get_tag_granules (address, len,
					       AARCH64_MTE_GRANULE_SIZE);

  /* If the memory range contains no tags, nothing left to do.  */
  if (ntags == 0)
    return true;

  gdb::byte_vector tagbuf (ntags);

  struct iovec iovec;
  iovec.iov_base = tagbuf.data ();
  iovec.iov_len = ntags;

  tags.clear ();
  bool done_reading = false;

  /* The kernel may return less tags than we requested.  Loop until we've read
     all the requested tags or until we get an error.  */
  while (!done_reading)
    {
      /* Attempt to read ntags allocation tags from the kernel.  */
      if (ptrace (PTRACE_PEEKMTETAGS, tid, address, &iovec) < 0)
	aarch64_mte_linux_peek_error (errno);

      /* Make sure the kernel returned at least one tag.  */
      if (iovec.iov_len <= 0)
	{
	  tags.clear ();
	  return false;
	}

      /* Copy the tags the kernel returned.  */
      for (size_t i = 0; i < iovec.iov_len; i++)
	tags.push_back (tagbuf[i]);

      /* Are we done reading tags?  */
      if (tags.size () == ntags)
	done_reading = true;
      else
	{
	  address += iovec.iov_len * AARCH64_MTE_GRANULE_SIZE;
	  iovec.iov_len = ntags - iovec.iov_len;
	}
    }
  return true;
}

/* See nat/aarch64-mte-linux-ptrace.h */

bool
aarch64_mte_store_memtags (int tid, CORE_ADDR address, size_t len,
			   const gdb::byte_vector &tags)
{
  if (tags.size () == 0)
    return true;

  /* Get the number of tags we need to write.  */
  size_t ntags = aarch64_mte_get_tag_granules (address, len,
					       AARCH64_MTE_GRANULE_SIZE);

  /* If the memory range contains no tags, nothing left to do.  */
  if (ntags == 0)
    return true;

  bool done_writing = false;
  size_t tags_written = 0;

  /* Write all the tags, AARCH64_MTE_TAGS_MAX_SIZE blocks at a time.  */
  while (!done_writing)
    {
      gdb::byte_vector t = prepare_tag_vector (ntags - tags_written, tags,
					       tags_written,
					       AARCH64_MTE_TAGS_MAX_SIZE);

      struct iovec iovec;
      iovec.iov_base = t.data ();
      iovec.iov_len = t.size ();

      /* Request the kernel to update the allocation tags.  */
      if (ptrace (PTRACE_POKEMTETAGS, tid, address, &iovec) < 0)
	aarch64_mte_linux_poke_error (errno);

      /* Make sure the kernel wrote at least one tag.  */
      if (iovec.iov_len <= 0)
	return false;

      tags_written += iovec.iov_len;

      /* Are we done writing tags?  */
      if (tags_written == ntags)
	done_writing = true;
      else
	address += iovec.iov_len * AARCH64_MTE_GRANULE_SIZE;
    }

  return true;
}
