/* Cache and manage the values of registers for GDB, the GNU debugger.

   Copyright (C) 1986-2023 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 "defs.h"
#include "inferior.h"
#include "gdbthread.h"
#include "target.h"
#include "test-target.h"
#include "scoped-mock-context.h"
#include "gdbarch.h"
#include "gdbcmd.h"
#include "regcache.h"
#include "reggroups.h"
#include "observable.h"
#include "regset.h"
#include <unordered_map>
#include "cli/cli-cmds.h"

/*
 * DATA STRUCTURE
 *
 * Here is the actual register cache.
 */

/* Per-architecture object describing the layout of a register cache.
   Computed once when the architecture is created.  */

struct regcache_descr
{
  /* The architecture this descriptor belongs to.  */
  struct gdbarch *gdbarch = nullptr;

  /* The raw register cache.  Each raw (or hard) register is supplied
     by the target interface.  The raw cache should not contain
     redundant information - if the PC is constructed from two
     registers then those registers and not the PC lives in the raw
     cache.  */
  long sizeof_raw_registers = 0;

  /* The cooked register space.  Each cooked register in the range
     [0..NR_RAW_REGISTERS) is direct-mapped onto the corresponding raw
     register.  The remaining [NR_RAW_REGISTERS
     .. NR_COOKED_REGISTERS) (a.k.a. pseudo registers) are mapped onto
     both raw registers and memory by the architecture methods
     gdbarch_pseudo_register_read and gdbarch_pseudo_register_write.  */
  int nr_cooked_registers = 0;
  long sizeof_cooked_registers = 0;

  /* Offset and size (in 8 bit bytes), of each register in the
     register cache.  All registers (including those in the range
     [NR_RAW_REGISTERS .. NR_COOKED_REGISTERS) are given an
     offset.  */
  long *register_offset = nullptr;
  long *sizeof_register = nullptr;

  /* Cached table containing the type of each register.  */
  struct type **register_type = nullptr;
};

static const registry<gdbarch>::key<struct regcache_descr>
     regcache_descr_handle;

static struct regcache_descr *
init_regcache_descr (struct gdbarch *gdbarch)
{
  int i;
  struct regcache_descr *descr;
  gdb_assert (gdbarch != NULL);

  /* Create an initial, zero filled, table.  */
  descr = new struct regcache_descr;
  descr->gdbarch = gdbarch;

  /* Total size of the register space.  The raw registers are mapped
     directly onto the raw register cache while the pseudo's are
     either mapped onto raw-registers or memory.  */
  descr->nr_cooked_registers = gdbarch_num_cooked_regs (gdbarch);

  /* Fill in a table of register types.  */
  descr->register_type
    = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers,
			      struct type *);
  for (i = 0; i < descr->nr_cooked_registers; i++)
    descr->register_type[i] = gdbarch_register_type (gdbarch, i);

  /* Construct a strictly RAW register cache.  Don't allow pseudo's
     into the register cache.  */

  /* Lay out the register cache.

     NOTE: cagney/2002-05-22: Only register_type () is used when
     constructing the register cache.  It is assumed that the
     register's raw size, virtual size and type length are all the
     same.  */

  {
    long offset = 0;

    descr->sizeof_register
      = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
    descr->register_offset
      = GDBARCH_OBSTACK_CALLOC (gdbarch, descr->nr_cooked_registers, long);
    for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
      {
	descr->sizeof_register[i] = descr->register_type[i]->length ();
	descr->register_offset[i] = offset;
	offset += descr->sizeof_register[i];
      }
    /* Set the real size of the raw register cache buffer.  */
    descr->sizeof_raw_registers = offset;

    for (; i < descr->nr_cooked_registers; i++)
      {
	descr->sizeof_register[i] = descr->register_type[i]->length ();
	descr->register_offset[i] = offset;
	offset += descr->sizeof_register[i];
      }
    /* Set the real size of the readonly register cache buffer.  */
    descr->sizeof_cooked_registers = offset;
  }

  return descr;
}

static struct regcache_descr *
regcache_descr (struct gdbarch *gdbarch)
{
  struct regcache_descr *result = regcache_descr_handle.get (gdbarch);
  if (result == nullptr)
    {
      result = init_regcache_descr (gdbarch);
      regcache_descr_handle.set (gdbarch, result);
    }

  return result;
}

/* Utility functions returning useful register attributes stored in
   the regcache descr.  */

struct type *
register_type (struct gdbarch *gdbarch, int regnum)
{
  struct regcache_descr *descr = regcache_descr (gdbarch);

  gdb_assert (regnum >= 0 && regnum < descr->nr_cooked_registers);
  return descr->register_type[regnum];
}

/* Utility functions returning useful register attributes stored in
   the regcache descr.  */

int
register_size (struct gdbarch *gdbarch, int regnum)
{
  struct regcache_descr *descr = regcache_descr (gdbarch);
  int size;

  gdb_assert (regnum >= 0 && regnum < gdbarch_num_cooked_regs (gdbarch));
  size = descr->sizeof_register[regnum];
  return size;
}

/* See gdbsupport/common-regcache.h.  */

int
regcache_register_size (const struct regcache *regcache, int n)
{
  return register_size (regcache->arch (), n);
}

reg_buffer::reg_buffer (gdbarch *gdbarch, bool has_pseudo)
  : m_has_pseudo (has_pseudo)
{
  gdb_assert (gdbarch != NULL);
  m_descr = regcache_descr (gdbarch);

  /* We don't zero-initialize the M_REGISTERS array, as the bytes it contains
     aren't meaningful as long as the corresponding register status is not
     REG_VALID.  */
  if (has_pseudo)
    {
      m_registers.reset (new gdb_byte[m_descr->sizeof_cooked_registers]);
      m_register_status.reset
	(new register_status[m_descr->nr_cooked_registers] ());
    }
  else
    {
      m_registers.reset (new gdb_byte[m_descr->sizeof_raw_registers]);
      m_register_status.reset
	(new register_status[gdbarch_num_regs (gdbarch)] ());
    }
}

regcache::regcache (inferior *inf_for_target_calls, gdbarch *gdbarch,
		    const address_space *aspace_)
/* The register buffers.  A read/write register cache can only hold
   [0 .. gdbarch_num_regs).  */
  : detached_regcache (gdbarch, false), m_aspace (aspace_),
    m_inf_for_target_calls (inf_for_target_calls)
{
  m_ptid = minus_one_ptid;
}

readonly_detached_regcache::readonly_detached_regcache (regcache &src)
  : readonly_detached_regcache (src.arch (),
				[&src] (int regnum, gdb_byte *buf)
				  {
				    return src.cooked_read (regnum, buf);
				  })
{
}

gdbarch *
reg_buffer::arch () const
{
  return m_descr->gdbarch;
}

/* Return  a pointer to register REGNUM's buffer cache.  */

gdb_byte *
reg_buffer::register_buffer (int regnum) const
{
  return m_registers.get () + m_descr->register_offset[regnum];
}

void
reg_buffer::save (register_read_ftype cooked_read)
{
  struct gdbarch *gdbarch = m_descr->gdbarch;
  int regnum;

  /* It should have pseudo registers.  */
  gdb_assert (m_has_pseudo);
  /* Clear the dest.  */
  memset (m_registers.get (), 0, m_descr->sizeof_cooked_registers);
  memset (m_register_status.get (), REG_UNKNOWN, m_descr->nr_cooked_registers);
  /* Copy over any registers (identified by their membership in the
     save_reggroup) and mark them as valid.  The full [0 .. gdbarch_num_regs +
     gdbarch_num_pseudo_regs) range is checked since some architectures need
     to save/restore `cooked' registers that live in memory.  */
  for (regnum = 0; regnum < m_descr->nr_cooked_registers; regnum++)
    {
      if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
	{
	  gdb_byte *dst_buf = register_buffer (regnum);
	  enum register_status status = cooked_read (regnum, dst_buf);

	  gdb_assert (status != REG_UNKNOWN);

	  if (status != REG_VALID)
	    memset (dst_buf, 0, register_size (gdbarch, regnum));

	  m_register_status[regnum] = status;
	}
    }
}

void
regcache::restore (readonly_detached_regcache *src)
{
  struct gdbarch *gdbarch = m_descr->gdbarch;
  int regnum;

  gdb_assert (src != NULL);
  gdb_assert (src->m_has_pseudo);

  gdb_assert (gdbarch == src->arch ());

  /* Copy over any registers, being careful to only restore those that
     were both saved and need to be restored.  The full [0 .. gdbarch_num_regs
     + gdbarch_num_pseudo_regs) range is checked since some architectures need
     to save/restore `cooked' registers that live in memory.  */
  for (regnum = 0; regnum < m_descr->nr_cooked_registers; regnum++)
    {
      if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup))
	{
	  if (src->m_register_status[regnum] == REG_VALID)
	    cooked_write (regnum, src->register_buffer (regnum));
	}
    }
}

/* See gdbsupport/common-regcache.h.  */

enum register_status
reg_buffer::get_register_status (int regnum) const
{
  assert_regnum (regnum);

  return m_register_status[regnum];
}

void
reg_buffer::invalidate (int regnum)
{
  assert_regnum (regnum);
  m_register_status[regnum] = REG_UNKNOWN;
}

void
reg_buffer::assert_regnum (int regnum) const
{
  gdb_assert (regnum >= 0);
  if (m_has_pseudo)
    gdb_assert (regnum < m_descr->nr_cooked_registers);
  else
    gdb_assert (regnum < gdbarch_num_regs (arch ()));
}

/* Type to map a ptid to a list of regcaches (one thread may have multiple
   regcaches, associated to different gdbarches).  */

using ptid_regcache_map
  = std::unordered_multimap<ptid_t, regcache_up>;

/* Type holding regcaches for a given pid.  */

using pid_ptid_regcache_map = std::unordered_map<int, ptid_regcache_map>;

/* Type holding regcaches for a given target.  */

using target_pid_ptid_regcache_map
  = std::unordered_map<process_stratum_target *, pid_ptid_regcache_map>;

/* Global structure containing the existing regcaches.  */

/* NOTE: this is a write-through cache.  There is no "dirty" bit for
   recording if the register values have been changed (eg. by the
   user).  Therefore all registers must be written back to the
   target when appropriate.  */
static target_pid_ptid_regcache_map regcaches;

struct regcache *
get_thread_arch_aspace_regcache (inferior *inf_for_target_calls,
				 ptid_t ptid, gdbarch *arch,
				 struct address_space *aspace)
{
  gdb_assert (inf_for_target_calls != nullptr);

  process_stratum_target *proc_target = inf_for_target_calls->process_target ();
  gdb_assert (proc_target != nullptr);

  /* Find the map for this target.  */
  pid_ptid_regcache_map &pid_ptid_regc_map = regcaches[proc_target];

  /* Find the map for this pid.  */
  ptid_regcache_map &ptid_regc_map = pid_ptid_regc_map[ptid.pid ()];

  /* Check first if a regcache for this arch already exists.  */
  auto range = ptid_regc_map.equal_range (ptid);
  for (auto it = range.first; it != range.second; ++it)
    {
      if (it->second->arch () == arch)
	return it->second.get ();
    }

  /* It does not exist, create it.  */
  regcache *new_regcache = new regcache (inf_for_target_calls, arch, aspace);
  new_regcache->set_ptid (ptid);
  /* Work around a problem with g++ 4.8 (PR96537): Call the regcache_up
     constructor explicitly instead of implicitly.  */
  ptid_regc_map.insert (std::make_pair (ptid, regcache_up (new_regcache)));

  return new_regcache;
}

struct regcache *
get_thread_arch_regcache (process_stratum_target *target, ptid_t ptid,
			  struct gdbarch *gdbarch)
{
  scoped_restore_current_inferior restore_current_inferior;
  inferior *inf = find_inferior_ptid (target, ptid);
  set_current_inferior (inf);
  address_space *aspace = target_thread_address_space (ptid);

  return get_thread_arch_aspace_regcache (inf, ptid, gdbarch, aspace);
}

static process_stratum_target *current_thread_target;
static ptid_t current_thread_ptid;
static struct gdbarch *current_thread_arch;

struct regcache *
get_thread_regcache (process_stratum_target *target, ptid_t ptid)
{
  if (!current_thread_arch
      || target != current_thread_target
      || current_thread_ptid != ptid)
    {
      gdb_assert (ptid != null_ptid);

      current_thread_ptid = ptid;
      current_thread_target = target;

      scoped_restore_current_inferior restore_current_inferior;
      set_current_inferior (find_inferior_ptid (target, ptid));
      current_thread_arch = target_thread_architecture (ptid);
    }

  return get_thread_arch_regcache (target, ptid, current_thread_arch);
}

/* See regcache.h.  */

struct regcache *
get_thread_regcache (thread_info *thread)
{
  return get_thread_regcache (thread->inf->process_target (),
			      thread->ptid);
}

struct regcache *
get_current_regcache (void)
{
  return get_thread_regcache (inferior_thread ());
}

/* See gdbsupport/common-regcache.h.  */

struct regcache *
get_thread_regcache_for_ptid (ptid_t ptid)
{
  /* This function doesn't take a process_stratum_target parameter
     because it's a gdbsupport/ routine implemented by both gdb and
     gdbserver.  It always refers to a ptid of the current target.  */
  process_stratum_target *proc_target = current_inferior ()->process_target ();
  return get_thread_regcache (proc_target, ptid);
}

/* Observer for the target_changed event.  */

static void
regcache_observer_target_changed (struct target_ops *target)
{
  registers_changed ();
}

/* Update regcaches related to OLD_PTID to now use NEW_PTID.  */
static void
regcache_thread_ptid_changed (process_stratum_target *target,
			      ptid_t old_ptid, ptid_t new_ptid)
{
  /* Look up map for target.  */
  auto pid_ptid_regc_map_it = regcaches.find (target);
  if (pid_ptid_regc_map_it == regcaches.end ())
    return;

 /* Look up map for pid.  */
  pid_ptid_regcache_map &pid_ptid_regc_map = pid_ptid_regc_map_it->second;
  auto ptid_regc_map_it = pid_ptid_regc_map.find (old_ptid.pid ());
  if (ptid_regc_map_it == pid_ptid_regc_map.end ())
    return;

  /* Update all regcaches belonging to old_ptid.  */
  ptid_regcache_map &ptid_regc_map = ptid_regc_map_it->second;
  auto range = ptid_regc_map.equal_range (old_ptid);
  for (auto it = range.first; it != range.second;)
    {
      regcache_up rc = std::move (it->second);
      rc->set_ptid (new_ptid);

      /* Remove old before inserting new, to avoid rehashing,
	 which would invalidate iterators.  */
      it = ptid_regc_map.erase (it);
      ptid_regc_map.insert (std::make_pair (new_ptid, std::move (rc)));
    }
}

/* Low level examining and depositing of registers.

   The caller is responsible for making sure that the inferior is
   stopped before calling the fetching routines, or it will get
   garbage.  (a change from GDB version 3, in which the caller got the
   value from the last stop).  */

/* REGISTERS_CHANGED ()

   Indicate that registers may have changed, so invalidate the cache.  */

void
registers_changed_ptid (process_stratum_target *target, ptid_t ptid)
{
  if (target == nullptr)
    {
      /* Since there can be ptid clashes between targets, it's not valid to
	 pass a ptid without saying to which target it belongs.  */
      gdb_assert (ptid == minus_one_ptid);

      /* Delete all the regcaches of all targets.  */
      regcaches.clear ();
    }
  else if (ptid.is_pid ())
    {
      /* Non-NULL target and pid ptid, delete all regcaches belonging
	 to this (TARGET, PID).  */

      /* Look up map for target.  */
      auto pid_ptid_regc_map_it = regcaches.find (target);
      if (pid_ptid_regc_map_it != regcaches.end ())
	{
	  pid_ptid_regcache_map &pid_ptid_regc_map
	    = pid_ptid_regc_map_it->second;

	  pid_ptid_regc_map.erase (ptid.pid ());
	}
    }
  else if (ptid != minus_one_ptid)
    {
      /* Non-NULL target and non-minus_one_ptid, delete all regcaches belonging
	 to this (TARGET, PTID).  */

      /* Look up map for target.  */
      auto pid_ptid_regc_map_it = regcaches.find (target);
      if (pid_ptid_regc_map_it != regcaches.end ())
	{
	  pid_ptid_regcache_map &pid_ptid_regc_map
	    = pid_ptid_regc_map_it->second;

	  /* Look up map for pid.  */
	  auto ptid_regc_map_it
	    = pid_ptid_regc_map.find (ptid.pid ());
	  if (ptid_regc_map_it != pid_ptid_regc_map.end ())
	    {
	      ptid_regcache_map &ptid_regc_map
		= ptid_regc_map_it->second;

	      ptid_regc_map.erase (ptid);
	    }
	}
    }
  else
    {
       /* Non-NULL target and minus_one_ptid, delete all regcaches
	  associated to this target.  */
      regcaches.erase (target);
    }

  if ((target == nullptr || current_thread_target == target)
      && current_thread_ptid.matches (ptid))
    {
      current_thread_target = NULL;
      current_thread_ptid = null_ptid;
      current_thread_arch = NULL;
    }

  if ((target == nullptr || current_inferior ()->process_target () == target)
      && inferior_ptid.matches (ptid))
    {
      /* We just deleted the regcache of the current thread.  Need to
	 forget about any frames we have cached, too.  */
      reinit_frame_cache ();
    }
}

/* See regcache.h.  */

void
registers_changed_thread (thread_info *thread)
{
  registers_changed_ptid (thread->inf->process_target (), thread->ptid);
}

void
registers_changed (void)
{
  registers_changed_ptid (nullptr, minus_one_ptid);
}

void
regcache::raw_update (int regnum)
{
  assert_regnum (regnum);

  /* Make certain that the register cache is up-to-date with respect
     to the current thread.  This switching shouldn't be necessary
     only there is still only one target side register cache.  Sigh!
     On the bright side, at least there is a regcache object.  */

  if (get_register_status (regnum) == REG_UNKNOWN)
    {
      gdb::optional<scoped_restore_current_thread> maybe_restore_thread
	= maybe_switch_inferior (m_inf_for_target_calls);

      target_fetch_registers (this, regnum);

      /* A number of targets can't access the whole set of raw
	 registers (because the debug API provides no means to get at
	 them).  */
      if (m_register_status[regnum] == REG_UNKNOWN)
	m_register_status[regnum] = REG_UNAVAILABLE;
    }
}

enum register_status
readable_regcache::raw_read (int regnum, gdb_byte *buf)
{
  gdb_assert (buf != NULL);
  raw_update (regnum);

  if (m_register_status[regnum] != REG_VALID)
    memset (buf, 0, m_descr->sizeof_register[regnum]);
  else
    memcpy (buf, register_buffer (regnum),
	    m_descr->sizeof_register[regnum]);

  return m_register_status[regnum];
}

enum register_status
regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
{
  gdb_assert (regcache != NULL);
  return regcache->raw_read (regnum, val);
}

template<typename T, typename>
enum register_status
readable_regcache::raw_read (int regnum, T *val)
{
  assert_regnum (regnum);
  size_t len = m_descr->sizeof_register[regnum];
  gdb_byte *buf = (gdb_byte *) alloca (len);
  register_status status = raw_read (regnum, buf);
  if (status == REG_VALID)
    *val = extract_integer<T> ({buf, len},
			       gdbarch_byte_order (m_descr->gdbarch));
  else
    *val = 0;
  return status;
}

enum register_status
regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
			    ULONGEST *val)
{
  gdb_assert (regcache != NULL);
  return regcache->raw_read (regnum, val);
}

void
regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val)
{
  gdb_assert (regcache != NULL);
  regcache->raw_write (regnum, val);
}

template<typename T, typename>
void
regcache::raw_write (int regnum, T val)
{
  gdb_byte *buf;

  assert_regnum (regnum);
  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
  store_integer (buf, m_descr->sizeof_register[regnum],
		 gdbarch_byte_order (m_descr->gdbarch), val);
  raw_write (regnum, buf);
}

void
regcache_raw_write_unsigned (struct regcache *regcache, int regnum,
			     ULONGEST val)
{
  gdb_assert (regcache != NULL);
  regcache->raw_write (regnum, val);
}

LONGEST
regcache_raw_get_signed (struct regcache *regcache, int regnum)
{
  LONGEST value;
  enum register_status status;

  status = regcache_raw_read_signed (regcache, regnum, &value);
  if (status == REG_UNAVAILABLE)
    throw_error (NOT_AVAILABLE_ERROR,
		 _("Register %d is not available"), regnum);
  return value;
}

enum register_status
readable_regcache::cooked_read (int regnum, gdb_byte *buf)
{
  gdb_assert (regnum >= 0);
  gdb_assert (regnum < m_descr->nr_cooked_registers);
  if (regnum < num_raw_registers ())
    return raw_read (regnum, buf);
  else if (m_has_pseudo
	   && m_register_status[regnum] != REG_UNKNOWN)
    {
      if (m_register_status[regnum] == REG_VALID)
	memcpy (buf, register_buffer (regnum),
		m_descr->sizeof_register[regnum]);
      else
	memset (buf, 0, m_descr->sizeof_register[regnum]);

      return m_register_status[regnum];
    }
  else if (gdbarch_pseudo_register_read_value_p (m_descr->gdbarch))
    {
      struct value *computed;
      enum register_status result = REG_VALID;

      scoped_value_mark mark;

      computed = gdbarch_pseudo_register_read_value (m_descr->gdbarch,
						     this, regnum);
      if (computed->entirely_available ())
	memcpy (buf, computed->contents_raw ().data (),
		m_descr->sizeof_register[regnum]);
      else
	{
	  memset (buf, 0, m_descr->sizeof_register[regnum]);
	  result = REG_UNAVAILABLE;
	}

      return result;
    }
  else
    return gdbarch_pseudo_register_read (m_descr->gdbarch, this,
					 regnum, buf);
}

struct value *
readable_regcache::cooked_read_value (int regnum)
{
  gdb_assert (regnum >= 0);
  gdb_assert (regnum < m_descr->nr_cooked_registers);

  if (regnum < num_raw_registers ()
      || (m_has_pseudo && m_register_status[regnum] != REG_UNKNOWN)
      || !gdbarch_pseudo_register_read_value_p (m_descr->gdbarch))
    {
      struct value *result;

      result = value::allocate (register_type (m_descr->gdbarch, regnum));
      result->set_lval (lval_register);
      VALUE_REGNUM (result) = regnum;

      /* It is more efficient in general to do this delegation in this
	 direction than in the other one, even though the value-based
	 API is preferred.  */
      if (cooked_read (regnum,
		       result->contents_raw ().data ()) == REG_UNAVAILABLE)
	result->mark_bytes_unavailable (0,
					result->type ()->length ());

      return result;
    }
  else
    return gdbarch_pseudo_register_read_value (m_descr->gdbarch,
					       this, regnum);
}

enum register_status
regcache_cooked_read_signed (struct regcache *regcache, int regnum,
			     LONGEST *val)
{
  gdb_assert (regcache != NULL);
  return regcache->cooked_read (regnum, val);
}

template<typename T, typename>
enum register_status
readable_regcache::cooked_read (int regnum, T *val)
{
  gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers);
  size_t len = m_descr->sizeof_register[regnum];
  gdb_byte *buf = (gdb_byte *) alloca (len);
  register_status status = cooked_read (regnum, buf);
  if (status == REG_VALID)
    *val = extract_integer<T> ({buf, len},
			       gdbarch_byte_order (m_descr->gdbarch));
  else
    *val = 0;
  return status;
}

enum register_status
regcache_cooked_read_unsigned (struct regcache *regcache, int regnum,
			       ULONGEST *val)
{
  gdb_assert (regcache != NULL);
  return regcache->cooked_read (regnum, val);
}

void
regcache_cooked_write_signed (struct regcache *regcache, int regnum,
			      LONGEST val)
{
  gdb_assert (regcache != NULL);
  regcache->cooked_write (regnum, val);
}

template<typename T, typename>
void
regcache::cooked_write (int regnum, T val)
{
  gdb_byte *buf;

  gdb_assert (regnum >=0 && regnum < m_descr->nr_cooked_registers);
  buf = (gdb_byte *) alloca (m_descr->sizeof_register[regnum]);
  store_integer (buf, m_descr->sizeof_register[regnum],
		 gdbarch_byte_order (m_descr->gdbarch), val);
  cooked_write (regnum, buf);
}

void
regcache_cooked_write_unsigned (struct regcache *regcache, int regnum,
				ULONGEST val)
{
  gdb_assert (regcache != NULL);
  regcache->cooked_write (regnum, val);
}

void
regcache::raw_write (int regnum, const gdb_byte *buf)
{

  gdb_assert (buf != NULL);
  assert_regnum (regnum);

  /* On the sparc, writing %g0 is a no-op, so we don't even want to
     change the registers array if something writes to this register.  */
  if (gdbarch_cannot_store_register (arch (), regnum))
    return;

  /* If we have a valid copy of the register, and new value == old
     value, then don't bother doing the actual store.  */
  if (get_register_status (regnum) == REG_VALID
      && (memcmp (register_buffer (regnum), buf,
		  m_descr->sizeof_register[regnum]) == 0))
    return;

  gdb::optional<scoped_restore_current_thread> maybe_restore_thread
    = maybe_switch_inferior (m_inf_for_target_calls);

  target_prepare_to_store (this);
  raw_supply (regnum, buf);

  /* Invalidate the register after it is written, in case of a
     failure.  */
  auto invalidator
    = make_scope_exit ([&] { this->invalidate (regnum); });

  target_store_registers (this, regnum);

  /* The target did not throw an error so we can discard invalidating
     the register.  */
  invalidator.release ();
}

void
regcache::cooked_write (int regnum, const gdb_byte *buf)
{
  gdb_assert (regnum >= 0);
  gdb_assert (regnum < m_descr->nr_cooked_registers);
  if (regnum < num_raw_registers ())
    raw_write (regnum, buf);
  else
    gdbarch_pseudo_register_write (m_descr->gdbarch, this,
				   regnum, buf);
}

/* See regcache.h.  */

enum register_status
readable_regcache::read_part (int regnum, int offset, int len,
			      gdb_byte *out, bool is_raw)
{
  int reg_size = register_size (arch (), regnum);

  gdb_assert (out != NULL);
  gdb_assert (offset >= 0 && offset <= reg_size);
  gdb_assert (len >= 0 && offset + len <= reg_size);

  if (offset == 0 && len == 0)
    {
      /* Nothing to do.  */
      return REG_VALID;
    }

  if (offset == 0 && len == reg_size)
    {
      /* Read the full register.  */
      return (is_raw) ? raw_read (regnum, out) : cooked_read (regnum, out);
    }

  enum register_status status;
  gdb_byte *reg = (gdb_byte *) alloca (reg_size);

  /* Read full register to buffer.  */
  status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg);
  if (status != REG_VALID)
    return status;

  /* Copy out.  */
  memcpy (out, reg + offset, len);
  return REG_VALID;
}

/* See regcache.h.  */

void
reg_buffer::raw_collect_part (int regnum, int offset, int len,
			      gdb_byte *out) const
{
  int reg_size = register_size (arch (), regnum);

  gdb_assert (out != nullptr);
  gdb_assert (offset >= 0 && offset <= reg_size);
  gdb_assert (len >= 0 && offset + len <= reg_size);

  if (offset == 0 && len == 0)
    {
      /* Nothing to do.  */
      return;
    }

  if (offset == 0 && len == reg_size)
    {
      /* Collect the full register.  */
      return raw_collect (regnum, out);
    }

  /* Read to buffer, then write out.  */
  gdb_byte *reg = (gdb_byte *) alloca (reg_size);
  raw_collect (regnum, reg);
  memcpy (out, reg + offset, len);
}

/* See regcache.h.  */

enum register_status
regcache::write_part (int regnum, int offset, int len,
		      const gdb_byte *in, bool is_raw)
{
  int reg_size = register_size (arch (), regnum);

  gdb_assert (in != NULL);
  gdb_assert (offset >= 0 && offset <= reg_size);
  gdb_assert (len >= 0 && offset + len <= reg_size);

  if (offset == 0 && len == 0)
    {
      /* Nothing to do.  */
      return REG_VALID;
    }

  if (offset == 0 && len == reg_size)
    {
      /* Write the full register.  */
      (is_raw) ? raw_write (regnum, in) : cooked_write (regnum, in);
      return REG_VALID;
    }

  enum register_status status;
  gdb_byte *reg = (gdb_byte *) alloca (reg_size);

  /* Read existing register to buffer.  */
  status = (is_raw) ? raw_read (regnum, reg) : cooked_read (regnum, reg);
  if (status != REG_VALID)
    return status;

  /* Update buffer, then write back to regcache.  */
  memcpy (reg + offset, in, len);
  is_raw ? raw_write (regnum, reg) : cooked_write (regnum, reg);
  return REG_VALID;
}

/* See regcache.h.  */

void
reg_buffer::raw_supply_part (int regnum, int offset, int len,
			     const gdb_byte *in)
{
  int reg_size = register_size (arch (), regnum);

  gdb_assert (in != nullptr);
  gdb_assert (offset >= 0 && offset <= reg_size);
  gdb_assert (len >= 0 && offset + len <= reg_size);

  if (offset == 0 && len == 0)
    {
      /* Nothing to do.  */
      return;
    }

  if (offset == 0 && len == reg_size)
    {
      /* Supply the full register.  */
      return raw_supply (regnum, in);
    }

  gdb_byte *reg = (gdb_byte *) alloca (reg_size);

  /* Read existing value to buffer.  */
  raw_collect (regnum, reg);

  /* Write to buffer, then write out.  */
  memcpy (reg + offset, in, len);
  raw_supply (regnum, reg);
}

enum register_status
readable_regcache::raw_read_part (int regnum, int offset, int len,
				  gdb_byte *buf)
{
  assert_regnum (regnum);
  return read_part (regnum, offset, len, buf, true);
}

/* See regcache.h.  */

void
regcache::raw_write_part (int regnum, int offset, int len,
			  const gdb_byte *buf)
{
  assert_regnum (regnum);
  write_part (regnum, offset, len, buf, true);
}

/* See regcache.h.  */

enum register_status
readable_regcache::cooked_read_part (int regnum, int offset, int len,
				     gdb_byte *buf)
{
  gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers);
  return read_part (regnum, offset, len, buf, false);
}

/* See regcache.h.  */

void
regcache::cooked_write_part (int regnum, int offset, int len,
			     const gdb_byte *buf)
{
  gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers);
  write_part (regnum, offset, len, buf, false);
}

/* See gdbsupport/common-regcache.h.  */

void
reg_buffer::raw_supply (int regnum, const void *buf)
{
  void *regbuf;
  size_t size;

  assert_regnum (regnum);

  regbuf = register_buffer (regnum);
  size = m_descr->sizeof_register[regnum];

  if (buf)
    {
      memcpy (regbuf, buf, size);
      m_register_status[regnum] = REG_VALID;
    }
  else
    {
      /* This memset not strictly necessary, but better than garbage
	 in case the register value manages to escape somewhere (due
	 to a bug, no less).  */
      memset (regbuf, 0, size);
      m_register_status[regnum] = REG_UNAVAILABLE;
    }
}

/* See regcache.h.  */

void
reg_buffer::raw_supply_integer (int regnum, const gdb_byte *addr,
				int addr_len, bool is_signed)
{
  enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch);
  gdb_byte *regbuf;
  size_t regsize;

  assert_regnum (regnum);

  regbuf = register_buffer (regnum);
  regsize = m_descr->sizeof_register[regnum];

  copy_integer_to_size (regbuf, regsize, addr, addr_len, is_signed,
			byte_order);
  m_register_status[regnum] = REG_VALID;
}

/* See regcache.h.  */

void
reg_buffer::raw_supply_zeroed (int regnum)
{
  void *regbuf;
  size_t size;

  assert_regnum (regnum);

  regbuf = register_buffer (regnum);
  size = m_descr->sizeof_register[regnum];

  memset (regbuf, 0, size);
  m_register_status[regnum] = REG_VALID;
}

/* See gdbsupport/common-regcache.h.  */

void
reg_buffer::raw_collect (int regnum, void *buf) const
{
  const void *regbuf;
  size_t size;

  gdb_assert (buf != NULL);
  assert_regnum (regnum);

  regbuf = register_buffer (regnum);
  size = m_descr->sizeof_register[regnum];
  memcpy (buf, regbuf, size);
}

/* See regcache.h.  */

void
reg_buffer::raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
				 bool is_signed) const
{
  enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch);
  const gdb_byte *regbuf;
  size_t regsize;

  assert_regnum (regnum);

  regbuf = register_buffer (regnum);
  regsize = m_descr->sizeof_register[regnum];

  copy_integer_to_size (addr, addr_len, regbuf, regsize, is_signed,
			byte_order);
}

/* See regcache.h.  */

void
regcache::transfer_regset_register (struct regcache *out_regcache, int regnum,
				    const gdb_byte *in_buf, gdb_byte *out_buf,
				    int slot_size, int offs) const
{
  struct gdbarch *gdbarch = arch ();
  int reg_size = std::min (register_size (gdbarch, regnum), slot_size);

  /* Use part versions and reg_size to prevent possible buffer overflows when
     accessing the regcache.  */

  if (out_buf != nullptr)
    {
      raw_collect_part (regnum, 0, reg_size, out_buf + offs);

      /* Ensure any additional space is cleared.  */
      if (slot_size > reg_size)
	memset (out_buf + offs + reg_size, 0, slot_size - reg_size);
    }
  else if (in_buf != nullptr)
    {
      /* Zero-extend the register value if the slot is smaller than the register.  */
      if (slot_size < register_size (gdbarch, regnum))
	out_regcache->raw_supply_zeroed (regnum);
      out_regcache->raw_supply_part (regnum, 0, reg_size, in_buf + offs);
    }
  else
    {
      /* Invalidate the register.  */
      out_regcache->raw_supply (regnum, nullptr);
    }
}

/* See regcache.h.  */

void
regcache::transfer_regset (const struct regset *regset, int regbase,
			   struct regcache *out_regcache,
			   int regnum, const gdb_byte *in_buf,
			   gdb_byte *out_buf, size_t size) const
{
  const struct regcache_map_entry *map;
  int offs = 0, count;

  for (map = (const struct regcache_map_entry *) regset->regmap;
       (count = map->count) != 0;
       map++)
    {
      int regno = map->regno;
      int slot_size = map->size;

      if (regno != REGCACHE_MAP_SKIP)
	regno += regbase;

      if (slot_size == 0 && regno != REGCACHE_MAP_SKIP)
	slot_size = m_descr->sizeof_register[regno];

      if (regno == REGCACHE_MAP_SKIP
	  || (regnum != -1
	      && (regnum < regno || regnum >= regno + count)))
	  offs += count * slot_size;

      else if (regnum == -1)
	for (; count--; regno++, offs += slot_size)
	  {
	    if (offs + slot_size > size)
	      break;

	    transfer_regset_register (out_regcache, regno, in_buf, out_buf,
				      slot_size, offs);
	  }
      else
	{
	  /* Transfer a single register and return.  */
	  offs += (regnum - regno) * slot_size;
	  if (offs + slot_size > size)
	    return;

	  transfer_regset_register (out_regcache, regnum, in_buf, out_buf,
				    slot_size, offs);
	  return;
	}
    }
}

/* Supply register REGNUM from BUF to REGCACHE, using the register map
   in REGSET.  If REGNUM is -1, do this for all registers in REGSET.
   If BUF is NULL, set the register(s) to "unavailable" status. */

void
regcache_supply_regset (const struct regset *regset,
			struct regcache *regcache,
			int regnum, const void *buf, size_t size)
{
  regcache->supply_regset (regset, regnum, (const gdb_byte *) buf, size);
}

/* See regcache.h.  */

void
regcache::supply_regset (const struct regset *regset, int regbase,
			 int regnum, const void *buf, size_t size)
{
  transfer_regset (regset, regbase, this, regnum, (const gdb_byte *) buf,
		   nullptr, size);
}

/* Collect register REGNUM from REGCACHE to BUF, using the register
   map in REGSET.  If REGNUM is -1, do this for all registers in
   REGSET.  */

void
regcache_collect_regset (const struct regset *regset,
			 const struct regcache *regcache,
			 int regnum, void *buf, size_t size)
{
  regcache->collect_regset (regset, regnum, (gdb_byte *) buf, size);
}

/* See regcache.h  */

void
regcache::collect_regset (const struct regset *regset, int regbase,
			 int regnum, void *buf, size_t size) const
{
  transfer_regset (regset, regbase, nullptr, regnum, nullptr, (gdb_byte *) buf,
		   size);
}

bool
regcache_map_supplies (const struct regcache_map_entry *map, int regnum,
		       struct gdbarch *gdbarch, size_t size)
{
  int offs = 0, count;

  for (; (count = map->count) != 0; map++)
    {
      int regno = map->regno;
      int slot_size = map->size;

      if (slot_size == 0 && regno != REGCACHE_MAP_SKIP)
	slot_size = register_size (gdbarch, regno);

      if (regno != REGCACHE_MAP_SKIP && regnum >= regno
	  && regnum < regno + count)
	return offs + (regnum - regno + 1) * slot_size <= size;

      offs += count * slot_size;
      if (offs >= size)
	return false;
    }
  return false;
}

/* See gdbsupport/common-regcache.h.  */

bool
reg_buffer::raw_compare (int regnum, const void *buf, int offset) const
{
  gdb_assert (buf != NULL);
  assert_regnum (regnum);

  const char *regbuf = (const char *) register_buffer (regnum);
  size_t size = m_descr->sizeof_register[regnum];
  gdb_assert (size >= offset);

  return (memcmp (buf, regbuf + offset, size - offset) == 0);
}

/* Special handling for register PC.  */

CORE_ADDR
regcache_read_pc (struct regcache *regcache)
{
  struct gdbarch *gdbarch = regcache->arch ();

  CORE_ADDR pc_val;

  if (gdbarch_read_pc_p (gdbarch))
    pc_val = gdbarch_read_pc (gdbarch, regcache);
  /* Else use per-frame method on get_current_frame.  */
  else if (gdbarch_pc_regnum (gdbarch) >= 0)
    {
      ULONGEST raw_val;

      if (regcache_cooked_read_unsigned (regcache,
					 gdbarch_pc_regnum (gdbarch),
					 &raw_val) == REG_UNAVAILABLE)
	throw_error (NOT_AVAILABLE_ERROR, _("PC register is not available"));

      pc_val = gdbarch_addr_bits_remove (gdbarch, raw_val);
    }
  else
    internal_error (_("regcache_read_pc: Unable to find PC"));
  return pc_val;
}

/* See gdbsupport/common-regcache.h.  */

CORE_ADDR
regcache_read_pc_protected (regcache *regcache)
{
  CORE_ADDR pc;
  try
    {
      pc = regcache_read_pc (regcache);
    }
  catch (const gdb_exception_error &ex)
    {
      pc = 0;
    }

  return pc;
}

void
regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = regcache->arch ();

  if (gdbarch_write_pc_p (gdbarch))
    gdbarch_write_pc (gdbarch, regcache, pc);
  else if (gdbarch_pc_regnum (gdbarch) >= 0)
    regcache_cooked_write_unsigned (regcache,
				    gdbarch_pc_regnum (gdbarch), pc);
  else
    internal_error (_("regcache_write_pc: Unable to update PC"));

  /* Writing the PC (for instance, from "load") invalidates the
     current frame.  */
  reinit_frame_cache ();
}

int
reg_buffer::num_raw_registers () const
{
  return gdbarch_num_regs (arch ());
}

void
regcache::debug_print_register (const char *func,  int regno)
{
  struct gdbarch *gdbarch = arch ();

  gdb_printf (gdb_stdlog, "%s ", func);
  if (regno >= 0 && regno < gdbarch_num_regs (gdbarch)
      && gdbarch_register_name (gdbarch, regno)[0] != '\0')
    gdb_printf (gdb_stdlog, "(%s)",
		gdbarch_register_name (gdbarch, regno));
  else
    gdb_printf (gdb_stdlog, "(%d)", regno);
  if (regno >= 0 && regno < gdbarch_num_regs (gdbarch))
    {
      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
      int size = register_size (gdbarch, regno);
      gdb_byte *buf = register_buffer (regno);

      gdb_printf (gdb_stdlog, " = ");
      for (int i = 0; i < size; i++)
	{
	  gdb_printf (gdb_stdlog, "%02x", buf[i]);
	}
      if (size <= sizeof (LONGEST))
	{
	  ULONGEST val = extract_unsigned_integer (buf, size, byte_order);

	  gdb_printf (gdb_stdlog, " %s %s",
		      core_addr_to_string_nz (val), plongest (val));
	}
    }
  gdb_printf (gdb_stdlog, "\n");
}

/* Implement 'maint flush register-cache' command.  */

static void
reg_flush_command (const char *command, int from_tty)
{
  /* Force-flush the register cache.  */
  registers_changed ();
  if (from_tty)
    gdb_printf (_("Register cache flushed.\n"));
}

void
register_dump::dump (ui_file *file)
{
  auto descr = regcache_descr (m_gdbarch);
  int regnum;
  int footnote_nr = 0;
  int footnote_register_offset = 0;
  int footnote_register_type_name_null = 0;
  long register_offset = 0;

  gdb_assert (descr->nr_cooked_registers
	      == gdbarch_num_cooked_regs (m_gdbarch));

  for (regnum = -1; regnum < descr->nr_cooked_registers; regnum++)
    {
      /* Name.  */
      if (regnum < 0)
	gdb_printf (file, " %-10s", "Name");
      else
	{
	  const char *p = gdbarch_register_name (m_gdbarch, regnum);

	  if (p[0] == '\0')
	    p = "''";
	  gdb_printf (file, " %-10s", p);
	}

      /* Number.  */
      if (regnum < 0)
	gdb_printf (file, " %4s", "Nr");
      else
	gdb_printf (file, " %4d", regnum);

      /* Relative number.  */
      if (regnum < 0)
	gdb_printf (file, " %4s", "Rel");
      else if (regnum < gdbarch_num_regs (m_gdbarch))
	gdb_printf (file, " %4d", regnum);
      else
	gdb_printf (file, " %4d",
		    (regnum - gdbarch_num_regs (m_gdbarch)));

      /* Offset.  */
      if (regnum < 0)
	gdb_printf (file, " %6s  ", "Offset");
      else
	{
	  gdb_printf (file, " %6ld",
		      descr->register_offset[regnum]);
	  if (register_offset != descr->register_offset[regnum]
	      || (regnum > 0
		  && (descr->register_offset[regnum]
		      != (descr->register_offset[regnum - 1]
			  + descr->sizeof_register[regnum - 1])))
	      )
	    {
	      if (!footnote_register_offset)
		footnote_register_offset = ++footnote_nr;
	      gdb_printf (file, "*%d", footnote_register_offset);
	    }
	  else
	    gdb_printf (file, "  ");
	  register_offset = (descr->register_offset[regnum]
			     + descr->sizeof_register[regnum]);
	}

      /* Size.  */
      if (regnum < 0)
	gdb_printf (file, " %5s ", "Size");
      else
	gdb_printf (file, " %5ld", descr->sizeof_register[regnum]);

      /* Type.  */
      {
	const char *t;
	std::string name_holder;

	if (regnum < 0)
	  t = "Type";
	else
	  {
	    static const char blt[] = "builtin_type";

	    t = register_type (m_gdbarch, regnum)->name ();
	    if (t == NULL)
	      {
		if (!footnote_register_type_name_null)
		  footnote_register_type_name_null = ++footnote_nr;
		name_holder = string_printf ("*%d",
					     footnote_register_type_name_null);
		t = name_holder.c_str ();
	      }
	    /* Chop a leading builtin_type.  */
	    if (startswith (t, blt))
	      t += strlen (blt);
	  }
	gdb_printf (file, " %-15s", t);
      }

      /* Leading space always present.  */
      gdb_printf (file, " ");

      dump_reg (file, regnum);

      gdb_printf (file, "\n");
    }

  if (footnote_register_offset)
    gdb_printf (file, "*%d: Inconsistent register offsets.\n",
		footnote_register_offset);
  if (footnote_register_type_name_null)
    gdb_printf (file,
		"*%d: Register type's name NULL.\n",
		footnote_register_type_name_null);
}

#if GDB_SELF_TEST
#include "gdbsupport/selftest.h"
#include "selftest-arch.h"
#include "target-float.h"

namespace selftests {

static size_t
regcaches_size ()
{
  size_t size = 0;

  for (auto pid_ptid_regc_map_it = regcaches.cbegin ();
       pid_ptid_regc_map_it != regcaches.cend ();
       ++pid_ptid_regc_map_it)
    {
      const pid_ptid_regcache_map &pid_ptid_regc_map
	= pid_ptid_regc_map_it->second;

      for (auto ptid_regc_map_it = pid_ptid_regc_map.cbegin ();
	   ptid_regc_map_it != pid_ptid_regc_map.cend ();
	   ++ptid_regc_map_it)
	{
	  const ptid_regcache_map &ptid_regc_map
	    = ptid_regc_map_it->second;

	  size += ptid_regc_map.size ();
	}
    }

  return size;
}

/* Return the count of regcaches for (TARGET, PTID) in REGCACHES.  */

static int
regcache_count (process_stratum_target *target, ptid_t ptid)
{
  /* Look up map for target.  */
  auto pid_ptid_regc_map_it = regcaches.find (target);
  if (pid_ptid_regc_map_it != regcaches.end ())
    {
      pid_ptid_regcache_map &pid_ptid_regc_map = pid_ptid_regc_map_it->second;

      /* Look map for pid.  */
      auto ptid_regc_map_it = pid_ptid_regc_map.find (ptid.pid ());
      if (ptid_regc_map_it != pid_ptid_regc_map.end ())
	{
	  ptid_regcache_map &ptid_regc_map = ptid_regc_map_it->second;
	  auto range = ptid_regc_map.equal_range (ptid);

	  return std::distance (range.first, range.second);
	}
    }

  return 0;
};

/* Wrapper around get_thread_arch_aspace_regcache that does some self checks.  */

static void
get_thread_arch_aspace_regcache_and_check (inferior *inf_for_target_calls,
					   ptid_t ptid)
{
  /* We currently only test with a single gdbarch.  Any gdbarch will do, so use
     the current inferior's gdbarch.  Also use the current inferior's address
     space.  */
  gdbarch *arch = inf_for_target_calls->arch ();
  address_space *aspace = inf_for_target_calls->aspace;
  regcache *regcache = get_thread_arch_aspace_regcache (inf_for_target_calls,
							ptid, arch, aspace);

  SELF_CHECK (regcache != NULL);
  SELF_CHECK (regcache->ptid () == ptid);
  SELF_CHECK (regcache->arch () == arch);
  SELF_CHECK (regcache->aspace () == aspace);
}

/* The data that the regcaches selftests must hold onto for the duration of the
   test.  */

struct regcache_test_data
{
  regcache_test_data ()
      /* The specific arch doesn't matter.  */
    : test_ctx_1 (current_inferior ()->arch ()),
      test_ctx_2 (current_inferior ()->arch ())
  {
    /* Ensure the regcaches container is empty at the start.  */
    registers_changed ();
  }

  ~regcache_test_data ()
  {
    /* Make sure to leave the global regcaches container empty.  */
    registers_changed ();
  }

  scoped_mock_context<test_target_ops> test_ctx_1;
  scoped_mock_context<test_target_ops> test_ctx_2;
};

using regcache_test_data_up = std::unique_ptr<regcache_test_data>;

/* Set up a few regcaches from two different targets, for use in
   regcache-management tests.

   Return a pointer, because the `regcache_test_data` type is not moveable.  */

static regcache_test_data_up
populate_regcaches_for_test ()
{
  regcache_test_data_up data (new regcache_test_data);
  size_t expected_regcache_size = 0;

  SELF_CHECK (regcaches_size () == 0);

  /* Populate the regcache container with a few regcaches for the two test
     targets. */
  for (int pid : { 1, 2 })
    {
      for (long lwp : { 1, 2, 3 })
	{
	  get_thread_arch_aspace_regcache_and_check
	    (&data->test_ctx_1.mock_inferior, ptid_t (pid, lwp));
	  expected_regcache_size++;
	  SELF_CHECK (regcaches_size () == expected_regcache_size);

	  get_thread_arch_aspace_regcache_and_check
	    (&data->test_ctx_2.mock_inferior, ptid_t (pid, lwp));
	  expected_regcache_size++;
	  SELF_CHECK (regcaches_size () == expected_regcache_size);
	}
    }

  return data;
}

static void
get_thread_arch_aspace_regcache_test ()
{
  /* populate_regcaches_for_test already tests most of the
     get_thread_arch_aspace_regcache functionality.  */
  regcache_test_data_up data = populate_regcaches_for_test ();
  size_t regcaches_size_before = regcaches_size ();

  /* Test that getting an existing regcache doesn't create a new one.  */
  get_thread_arch_aspace_regcache_and_check (&data->test_ctx_1.mock_inferior,
					     ptid_t (2, 2));
  SELF_CHECK (regcaches_size () == regcaches_size_before);
}

  /* Test marking all regcaches of all targets as changed.  */

static void
registers_changed_ptid_all_test ()
{
  regcache_test_data_up data = populate_regcaches_for_test ();

  registers_changed_ptid (nullptr, minus_one_ptid);
  SELF_CHECK (regcaches_size () == 0);
}

/* Test marking regcaches of a specific target as changed.  */

static void
registers_changed_ptid_target_test ()
{
  regcache_test_data_up data = populate_regcaches_for_test ();

  registers_changed_ptid (&data->test_ctx_1.mock_target, minus_one_ptid);
  SELF_CHECK (regcaches_size () == 6);

  /* Check that we deleted the regcache for the right target.  */
  SELF_CHECK (regcache_count (&data->test_ctx_1.mock_target,
			      ptid_t (2, 2)) == 0);
  SELF_CHECK (regcache_count (&data->test_ctx_2.mock_target,
			      ptid_t (2, 2)) == 1);
}

/* Test marking regcaches of a specific (target, pid) as changed.  */

static void
registers_changed_ptid_target_pid_test ()
{
  regcache_test_data_up data = populate_regcaches_for_test ();

  registers_changed_ptid (&data->test_ctx_1.mock_target, ptid_t (2));
  SELF_CHECK (regcaches_size () == 9);

  /* Regcaches from target1 should not exist, while regcaches from target2
     should exist.  */
  SELF_CHECK (regcache_count (&data->test_ctx_1.mock_target,
			      ptid_t (2, 2)) == 0);
  SELF_CHECK (regcache_count (&data->test_ctx_2.mock_target,
			      ptid_t (2, 2)) == 1);
}

/* Test marking regcaches of a specific (target, ptid) as changed.  */

static void
registers_changed_ptid_target_ptid_test ()
{
  regcache_test_data_up data = populate_regcaches_for_test ();

  registers_changed_ptid (&data->test_ctx_1.mock_target, ptid_t (2, 2));
  SELF_CHECK (regcaches_size () == 11);

  /* Check that we deleted the regcache for the right target.  */
  SELF_CHECK (regcache_count (&data->test_ctx_1.mock_target,
			      ptid_t (2, 2)) == 0);
  SELF_CHECK (regcache_count (&data->test_ctx_2.mock_target,
			      ptid_t (2, 2)) == 1);
}

class target_ops_no_register : public test_target_ops
{
public:
  target_ops_no_register ()
    : test_target_ops {}
  {}

  void reset ()
  {
    fetch_registers_called = 0;
    store_registers_called = 0;
    xfer_partial_called = 0;
  }

  void fetch_registers (regcache *regs, int regno) override;
  void store_registers (regcache *regs, int regno) override;

  enum target_xfer_status xfer_partial (enum target_object object,
					const char *annex, gdb_byte *readbuf,
					const gdb_byte *writebuf,
					ULONGEST offset, ULONGEST len,
					ULONGEST *xfered_len) override;

  unsigned int fetch_registers_called = 0;
  unsigned int store_registers_called = 0;
  unsigned int xfer_partial_called = 0;
};

void
target_ops_no_register::fetch_registers (regcache *regs, int regno)
{
  /* Mark register available.  */
  regs->raw_supply_zeroed (regno);
  this->fetch_registers_called++;
}

void
target_ops_no_register::store_registers (regcache *regs, int regno)
{
  this->store_registers_called++;
}

enum target_xfer_status
target_ops_no_register::xfer_partial (enum target_object object,
				      const char *annex, gdb_byte *readbuf,
				      const gdb_byte *writebuf,
				      ULONGEST offset, ULONGEST len,
				      ULONGEST *xfered_len)
{
  this->xfer_partial_called++;

  *xfered_len = len;
  return TARGET_XFER_OK;
}

class readwrite_regcache : public regcache
{
public:
  readwrite_regcache (inferior *inf_for_target_calls,
		      struct gdbarch *gdbarch)
    : regcache (inf_for_target_calls, gdbarch, nullptr)
  {}
};

/* Return true if regcache::cooked_{read,write}_test should be skipped for
   GDBARCH.  */

static bool
selftest_skiparch (struct gdbarch *gdbarch)
{
  const char *name = gdbarch_bfd_arch_info (gdbarch)->printable_name;

  /* Avoid warning:
       Running selftest regcache::cooked_{read,write}_test::m68hc11.
       warning: No frame soft register found in the symbol table.
       Stack backtrace will not work.
     We could instead capture the output and then filter out the warning, but
     that seems more trouble than it's worth.  */
  return (strcmp (name, "m68hc11") == 0
	  || strcmp (name, "m68hc12") == 0
	  || strcmp (name, "m68hc12:HCS12") == 0);
}

/* Test regcache::cooked_read gets registers from raw registers and
   memory instead of target to_{fetch,store}_registers.  */

static void
cooked_read_test (struct gdbarch *gdbarch)
{
  if (selftest_skiparch (gdbarch))
    return;

  scoped_mock_context<target_ops_no_register> mockctx (gdbarch);

  /* Test that read one raw register from regcache_no_target will go
     to the target layer.  */

  /* Find a raw register which size isn't zero.  */
  int nonzero_regnum;
  for (nonzero_regnum = 0;
       nonzero_regnum < gdbarch_num_regs (gdbarch);
       nonzero_regnum++)
    {
      if (register_size (gdbarch, nonzero_regnum) != 0)
	break;
    }

  readwrite_regcache readwrite (&mockctx.mock_inferior, gdbarch);
  readwrite.set_ptid (mockctx.mock_ptid);
  gdb::def_vector<gdb_byte> buf (register_size (gdbarch, nonzero_regnum));

  readwrite.raw_read (nonzero_regnum, buf.data ());

  /* raw_read calls target_fetch_registers.  */
  SELF_CHECK (mockctx.mock_target.fetch_registers_called > 0);
  mockctx.mock_target.reset ();

  /* Mark all raw registers valid, so the following raw registers
     accesses won't go to target.  */
  for (auto i = 0; i < gdbarch_num_regs (gdbarch); i++)
    readwrite.raw_update (i);

  mockctx.mock_target.reset ();
  /* Then, read all raw and pseudo registers, and don't expect calling
     to_{fetch,store}_registers.  */
  for (int regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
    {
      if (register_size (gdbarch, regnum) == 0)
	continue;

      gdb::def_vector<gdb_byte> inner_buf (register_size (gdbarch, regnum));

      SELF_CHECK (REG_VALID == readwrite.cooked_read (regnum,
						      inner_buf.data ()));

      SELF_CHECK (mockctx.mock_target.fetch_registers_called == 0);
      SELF_CHECK (mockctx.mock_target.store_registers_called == 0);
      SELF_CHECK (mockctx.mock_target.xfer_partial_called == 0);

      mockctx.mock_target.reset ();
    }

  readonly_detached_regcache readonly (readwrite);

  /* GDB may go to target layer to fetch all registers and memory for
     readonly regcache.  */
  mockctx.mock_target.reset ();

  for (int regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
    {
      if (register_size (gdbarch, regnum) == 0)
	continue;

      gdb::def_vector<gdb_byte> inner_buf (register_size (gdbarch, regnum));
      enum register_status status = readonly.cooked_read (regnum,
							  inner_buf.data ());

      if (regnum < gdbarch_num_regs (gdbarch))
	{
	  auto bfd_arch = gdbarch_bfd_arch_info (gdbarch)->arch;

	  if (bfd_arch == bfd_arch_amdgcn
	      || bfd_arch == bfd_arch_frv || bfd_arch == bfd_arch_h8300
	      || bfd_arch == bfd_arch_m32c || bfd_arch == bfd_arch_sh
	      || bfd_arch == bfd_arch_alpha || bfd_arch == bfd_arch_v850
	      || bfd_arch == bfd_arch_msp430 || bfd_arch == bfd_arch_mep
	      || bfd_arch == bfd_arch_mips || bfd_arch == bfd_arch_v850_rh850
	      || bfd_arch == bfd_arch_tic6x || bfd_arch == bfd_arch_mn10300
	      || bfd_arch == bfd_arch_rl78 || bfd_arch == bfd_arch_score
	      || bfd_arch == bfd_arch_riscv || bfd_arch == bfd_arch_csky)
	    {
	      /* Raw registers.  If raw registers are not in save_reggroup,
		 their status are unknown.  */
	      if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
		SELF_CHECK (status == REG_VALID);
	      else
		SELF_CHECK (status == REG_UNKNOWN);
	    }
	  else
	    SELF_CHECK (status == REG_VALID);
	}
      else
	{
	  if (gdbarch_register_reggroup_p (gdbarch, regnum, save_reggroup))
	    SELF_CHECK (status == REG_VALID);
	  else
	    {
	      /* If pseudo registers are not in save_reggroup, some of
		 them can be computed from saved raw registers, but some
		 of them are unknown.  */
	      auto bfd_arch = gdbarch_bfd_arch_info (gdbarch)->arch;

	      if (bfd_arch == bfd_arch_frv
		  || bfd_arch == bfd_arch_m32c
		  || bfd_arch == bfd_arch_mep
		  || bfd_arch == bfd_arch_sh)
		SELF_CHECK (status == REG_VALID || status == REG_UNKNOWN);
	      else if (bfd_arch == bfd_arch_mips
		       || bfd_arch == bfd_arch_h8300)
		SELF_CHECK (status == REG_UNKNOWN);
	      else
		SELF_CHECK (status == REG_VALID);
	    }
	}

      SELF_CHECK (mockctx.mock_target.fetch_registers_called == 0);
      SELF_CHECK (mockctx.mock_target.store_registers_called == 0);
      SELF_CHECK (mockctx.mock_target.xfer_partial_called == 0);

      mockctx.mock_target.reset ();
    }
}

/* Test regcache::cooked_write by writing some expected contents to
   registers, and checking that contents read from registers and the
   expected contents are the same.  */

static void
cooked_write_test (struct gdbarch *gdbarch)
{
  if (selftest_skiparch (gdbarch))
    return;

  /* Create a mock environment.  A process_stratum target pushed.  */
  scoped_mock_context<target_ops_no_register> ctx (gdbarch);
  readwrite_regcache readwrite (&ctx.mock_inferior, gdbarch);
  readwrite.set_ptid (ctx.mock_ptid);
  const int num_regs = gdbarch_num_cooked_regs (gdbarch);

  for (auto regnum = 0; regnum < num_regs; regnum++)
    {
      if (register_size (gdbarch, regnum) == 0
	  || gdbarch_cannot_store_register (gdbarch, regnum))
	continue;

      auto bfd_arch = gdbarch_bfd_arch_info (gdbarch)->arch;

      if (bfd_arch == bfd_arch_sparc
	  /* SPARC64_CWP_REGNUM, SPARC64_PSTATE_REGNUM,
	     SPARC64_ASI_REGNUM and SPARC64_CCR_REGNUM are hard to test.  */
	  && gdbarch_ptr_bit (gdbarch) == 64
	  && (regnum >= gdbarch_num_regs (gdbarch)
	      && regnum <= gdbarch_num_regs (gdbarch) + 4))
	continue;

      std::vector<gdb_byte> expected (register_size (gdbarch, regnum), 0);
      std::vector<gdb_byte> buf (register_size (gdbarch, regnum), 0);
      const auto type = register_type (gdbarch, regnum);

      if (type->code () == TYPE_CODE_FLT
	  || type->code () == TYPE_CODE_DECFLOAT)
	{
	  /* Generate valid float format.  */
	  target_float_from_string (expected.data (), type, "1.25");
	}
      else if (type->code () == TYPE_CODE_INT
	       || type->code () == TYPE_CODE_ARRAY
	       || type->code () == TYPE_CODE_PTR
	       || type->code () == TYPE_CODE_UNION
	       || type->code () == TYPE_CODE_STRUCT)
	{
	  if (bfd_arch == bfd_arch_ia64
	      || (regnum >= gdbarch_num_regs (gdbarch)
		  && (bfd_arch == bfd_arch_xtensa
		      || bfd_arch == bfd_arch_bfin
		      || bfd_arch == bfd_arch_m32c
		      /* m68hc11 pseudo registers are in memory.  */
		      || bfd_arch == bfd_arch_m68hc11
		      || bfd_arch == bfd_arch_m68hc12
		      || bfd_arch == bfd_arch_s390))
	      || (bfd_arch == bfd_arch_frv
		  /* FRV pseudo registers except iacc0.  */
		  && regnum > gdbarch_num_regs (gdbarch)))
	    {
	      /* Skip setting the expected values for some architecture
		 registers.  */
	    }
	  else if (bfd_arch == bfd_arch_rl78 && regnum == 40)
	    {
	      /* RL78_PC_REGNUM */
	      for (auto j = 0; j < register_size (gdbarch, regnum) - 1; j++)
		expected[j] = j;
	    }
	  else
	    {
	      for (auto j = 0; j < register_size (gdbarch, regnum); j++)
		expected[j] = j;
	    }
	}
      else if (type->code () == TYPE_CODE_FLAGS)
	{
	  /* No idea how to test flags.  */
	  continue;
	}
      else
	{
	  /* If we don't know how to create the expected value for the
	     this type, make it fail.  */
	  SELF_CHECK (0);
	}

      readwrite.cooked_write (regnum, expected.data ());

      SELF_CHECK (readwrite.cooked_read (regnum, buf.data ()) == REG_VALID);
      SELF_CHECK (expected == buf);
    }
}

/* Verify that when two threads with the same ptid exist (from two different
   targets) and one of them changes ptid, we only update the appropriate
   regcaches.  */

static void
regcache_thread_ptid_changed ()
{
  /* This test relies on the global regcache list to initially be empty.  */
  registers_changed ();

  /* Any arch will do.  */
  gdbarch *arch = current_inferior ()->arch ();

  /* Prepare two targets with one thread each, with the same ptid.  */
  scoped_mock_context<test_target_ops> target1 (arch);
  scoped_mock_context<test_target_ops> target2 (arch);

  ptid_t old_ptid (111, 222);
  ptid_t new_ptid (111, 333);

  target1.mock_inferior.pid = old_ptid.pid ();
  target1.mock_thread.ptid = old_ptid;
  target1.mock_inferior.ptid_thread_map.clear ();
  target1.mock_inferior.ptid_thread_map[old_ptid] = &target1.mock_thread;

  target2.mock_inferior.pid = old_ptid.pid ();
  target2.mock_thread.ptid = old_ptid;
  target2.mock_inferior.ptid_thread_map.clear ();
  target2.mock_inferior.ptid_thread_map[old_ptid] = &target2.mock_thread;

  gdb_assert (regcaches.empty ());

  /* Populate the regcaches container.  */
  get_thread_arch_aspace_regcache (&target1.mock_inferior, old_ptid, arch,
				   nullptr);
  get_thread_arch_aspace_regcache (&target2.mock_inferior, old_ptid, arch,
				   nullptr);

  gdb_assert (regcaches.size () == 2);
  gdb_assert (regcache_count (&target1.mock_target, old_ptid) == 1);
  gdb_assert (regcache_count (&target1.mock_target, new_ptid) == 0);
  gdb_assert (regcache_count (&target2.mock_target, old_ptid) == 1);
  gdb_assert (regcache_count (&target2.mock_target, new_ptid) == 0);

  thread_change_ptid (&target1.mock_target, old_ptid, new_ptid);

  gdb_assert (regcaches.size () == 2);
  gdb_assert (regcache_count (&target1.mock_target, old_ptid) == 0);
  gdb_assert (regcache_count (&target1.mock_target, new_ptid) == 1);
  gdb_assert (regcache_count (&target2.mock_target, old_ptid) == 1);
  gdb_assert (regcache_count (&target2.mock_target, new_ptid) == 0);

  /* Leave the regcache list empty.  */
  registers_changed ();
  gdb_assert (regcaches.empty ());
}

} // namespace selftests
#endif /* GDB_SELF_TEST */

void _initialize_regcache ();
void
_initialize_regcache ()
{
  struct cmd_list_element *c;

  gdb::observers::target_changed.attach (regcache_observer_target_changed,
					 "regcache");
  gdb::observers::thread_ptid_changed.attach (regcache_thread_ptid_changed,
					      "regcache");

  cmd_list_element *maintenance_flush_register_cache_cmd
    = add_cmd ("register-cache", class_maintenance, reg_flush_command,
	       _("Force gdb to flush its register and frame cache."),
	       &maintenanceflushlist);
  c = add_com_alias ("flushregs", maintenance_flush_register_cache_cmd,
		     class_maintenance, 0);
  deprecate_cmd (c, "maintenance flush register-cache");

#if GDB_SELF_TEST
  selftests::register_test ("get_thread_arch_aspace_regcache",
			    selftests::get_thread_arch_aspace_regcache_test);
  selftests::register_test ("registers_changed_ptid_all",
			    selftests::registers_changed_ptid_all_test);
  selftests::register_test ("registers_changed_ptid_target",
			    selftests::registers_changed_ptid_target_test);
  selftests::register_test ("registers_changed_ptid_target_pid",
			    selftests::registers_changed_ptid_target_pid_test);
  selftests::register_test ("registers_changed_ptid_target_ptid",
			    selftests::registers_changed_ptid_target_ptid_test);

  selftests::register_test_foreach_arch ("regcache::cooked_read_test",
					 selftests::cooked_read_test);
  selftests::register_test_foreach_arch ("regcache::cooked_write_test",
					 selftests::cooked_write_test);
  selftests::register_test ("regcache_thread_ptid_changed",
			    selftests::regcache_thread_ptid_changed);
#endif
}
