/* Ada Ravenscar thread support.

   Copyright (C) 2004-2024 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 "extract-store-integer.h"
#include "gdbcore.h"
#include "gdbthread.h"
#include "ada-lang.h"
#include "target.h"
#include "inferior.h"
#include "command.h"
#include "ravenscar-thread.h"
#include "observable.h"
#include "cli/cli-cmds.h"
#include "top.h"
#include "regcache.h"
#include "objfiles.h"
#include <unordered_map>

/* This module provides support for "Ravenscar" tasks (Ada) when
   debugging on bare-metal targets.

   The typical situation is when debugging a bare-metal target over
   the remote protocol. In that situation, the system does not know
   about high-level concepts such as threads, only about some code
   running on one or more CPUs. And since the remote protocol does not
   provide any handling for CPUs, the de facto standard for handling
   them is to have one thread per CPU, where the thread's ptid has
   its lwp field set to the CPU number (eg: 1 for the first CPU,
   2 for the second one, etc).  This module will make that assumption.

   This module then creates and maintains the list of threads based
   on the list of Ada tasks, with one thread per Ada task. The convention
   is that threads corresponding to the CPUs (see assumption above)
   have a ptid_t of the form (PID, LWP, 0), while threads corresponding
   to our Ada tasks have a ptid_t of the form (PID, 0, TID) where TID
   is the Ada task's ID as extracted from Ada runtime information.

   Switching to a given Ada task (or its underlying thread) is performed
   by fetching the registers of that task from the memory area where
   the registers were saved.  For any of the other operations, the
   operation is performed by first finding the CPU on which the task
   is running, switching to its corresponding ptid, and then performing
   the operation on that ptid using the target beneath us.  */

/* If true, ravenscar task support is enabled.  */
static bool ravenscar_task_support = true;

static const char running_thread_name[] = "__gnat_running_thread_table";

static const char known_tasks_name[] = "system__tasking__debug__known_tasks";
static const char first_task_name[] = "system__tasking__debug__first_task";

static const char ravenscar_runtime_initializer[]
  = "system__bb__threads__initialize";

static const target_info ravenscar_target_info = {
  "ravenscar",
  N_("Ravenscar tasks."),
  N_("Ravenscar tasks support.")
};

struct ravenscar_thread_target final : public target_ops
{
  ravenscar_thread_target ()
    : m_base_ptid (inferior_ptid)
  {
  }

  const target_info &info () const override
  { return ravenscar_target_info; }

  strata stratum () const override { return thread_stratum; }

  ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
  void resume (ptid_t, int, enum gdb_signal) override;

  void fetch_registers (struct regcache *, int) override;
  void store_registers (struct regcache *, int) override;

  void prepare_to_store (struct regcache *) override;

  bool stopped_by_sw_breakpoint () override;

  bool stopped_by_hw_breakpoint () override;

  bool stopped_by_watchpoint () override;

  bool stopped_data_address (CORE_ADDR *) 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;

  bool thread_alive (ptid_t ptid) override;

  int core_of_thread (ptid_t ptid) override;

  void update_thread_list () override;

  std::string pid_to_str (ptid_t) override;

  ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;

  struct btrace_target_info *enable_btrace (thread_info *tp,
					    const struct btrace_config *conf)
    override
  {
    process_stratum_target *proc_target
      = as_process_stratum_target (this->beneath ());
    ptid_t underlying = get_base_thread_from_ravenscar_task (tp->ptid);
    tp = proc_target->find_thread (underlying);

    return beneath ()->enable_btrace (tp, conf);
  }

  void mourn_inferior () override;

  void close () override
  {
    delete this;
  }

  thread_info *add_active_thread ();

private:

  /* PTID of the last thread that received an event.
     This can be useful to determine the associated task that received
     the event, to make it the current task.  */
  ptid_t m_base_ptid;

  ptid_t active_task (int cpu);
  bool task_is_currently_active (ptid_t ptid);
  bool runtime_initialized ();
  int get_thread_base_cpu (ptid_t ptid);
  ptid_t get_base_thread_from_ravenscar_task (ptid_t ptid);
  void add_thread (struct ada_task_info *task);

  /* Like switch_to_thread, but uses the base ptid for the thread.  */
  void set_base_thread_from_ravenscar_task (ptid_t ptid)
  {
    process_stratum_target *proc_target
      = as_process_stratum_target (this->beneath ());
    ptid_t underlying = get_base_thread_from_ravenscar_task (ptid);
    switch_to_thread (proc_target->find_thread (underlying));
  }

  /* Some targets use lazy FPU initialization.  On these, the FP
     registers for a given task might be uninitialized, or stored in
     the per-task context, or simply be the live registers on the CPU.
     This enum is used to encode this information.  */
  enum fpu_state
  {
    /* This target doesn't do anything special for FP registers -- if
       any exist, they are treated just identical to non-FP
       registers.  */
    NOTHING_SPECIAL,
    /* This target uses the lazy FP scheme, and the FP registers are
       taken from the CPU.  This can happen for any task, because if a
       task switch occurs, the registers aren't immediately written to
       the per-task context -- this is deferred until the current task
       causes an FPU trap.  */
    LIVE_FP_REGISTERS,
    /* This target uses the lazy FP scheme, and the FP registers are
       not available.  Maybe this task never initialized the FPU, or
       maybe GDB couldn't find the required symbol.  */
    NO_FP_REGISTERS
  };

  /* Return the FPU state.  */
  fpu_state get_fpu_state (struct regcache *regcache,
			   const ravenscar_arch_ops *arch_ops);

  /* This maps a TID to the CPU on which it was running.  This is
     needed because sometimes the runtime will report an active task
     that hasn't yet been put on the list of tasks that is read by
     ada-tasks.c.  */
  std::unordered_map<ULONGEST, int> m_cpu_map;
};

/* Return true iff PTID corresponds to a ravenscar task.  */

static bool
is_ravenscar_task (ptid_t ptid)
{
  /* By construction, ravenscar tasks have their LWP set to zero.
     Also make sure that the TID is nonzero, as some remotes, when
     asked for the list of threads, will return the first thread
     as having its TID set to zero.  For instance, TSIM version
     2.0.48 for LEON3 sends 'm0' as a reply to the 'qfThreadInfo'
     query, which the remote protocol layer then treats as a thread
     whose TID is 0.  This is obviously not a ravenscar task.  */
  return ptid.lwp () == 0 && ptid.tid () != 0;
}

/* Given PTID, which can be either a ravenscar task or a CPU thread,
   return which CPU that ptid is running on.

   This assume that PTID is a valid ptid_t.  Otherwise, a gdb_assert
   will be triggered.  */

int
ravenscar_thread_target::get_thread_base_cpu (ptid_t ptid)
{
  int base_cpu;

  if (is_ravenscar_task (ptid))
    {
      /* Prefer to not read inferior memory if possible, to avoid
	 reentrancy problems with xfer_partial.  */
      auto iter = m_cpu_map.find (ptid.tid ());

      if (iter != m_cpu_map.end ())
	base_cpu = iter->second;
      else
	{
	  struct ada_task_info *task_info = ada_get_task_info_from_ptid (ptid);

	  gdb_assert (task_info != NULL);
	  base_cpu = task_info->base_cpu;
	}
    }
  else
    {
      /* We assume that the LWP of the PTID is equal to the CPU number.  */
      base_cpu = ptid.lwp ();
    }

  return base_cpu;
}

/* Given a ravenscar task (identified by its ptid_t PTID), return true
   if this task is the currently active task on the cpu that task is
   running on.

   In other words, this function determine which CPU this task is
   currently running on, and then return nonzero if the CPU in question
   is executing the code for that task.  If that's the case, then
   that task's registers are in the CPU bank.  Otherwise, the task
   is currently suspended, and its registers have been saved in memory.  */

bool
ravenscar_thread_target::task_is_currently_active (ptid_t ptid)
{
  ptid_t active_task_ptid = active_task (get_thread_base_cpu (ptid));

  return ptid == active_task_ptid;
}

/* Return the CPU thread (as a ptid_t) on which the given ravenscar
   task is running.

   This is the thread that corresponds to the CPU on which the task
   is running.  */

ptid_t
ravenscar_thread_target::get_base_thread_from_ravenscar_task (ptid_t ptid)
{
  int base_cpu;

  if (!is_ravenscar_task (ptid))
    return ptid;

  base_cpu = get_thread_base_cpu (ptid);
  return ptid_t (ptid.pid (), base_cpu);
}

/* Fetch the ravenscar running thread from target memory, make sure
   there's a corresponding thread in the thread list, and return it.
   If the runtime is not initialized, return NULL.  */

thread_info *
ravenscar_thread_target::add_active_thread ()
{
  process_stratum_target *proc_target
    = as_process_stratum_target (this->beneath ());

  int base_cpu;

  gdb_assert (!is_ravenscar_task (m_base_ptid));
  base_cpu = get_thread_base_cpu (m_base_ptid);

  if (!runtime_initialized ())
    return nullptr;

  /* It's possible for runtime_initialized to return true but for it
     not to be fully initialized.  For example, this can happen for a
     breakpoint placed at the task's beginning.  */
  ptid_t active_ptid = active_task (base_cpu);
  if (active_ptid == null_ptid)
    return nullptr;

  /* The running thread may not have been added to
     system.tasking.debug's list yet; so ravenscar_update_thread_list
     may not always add it to the thread list.  Add it here.  */
  thread_info *active_thr = proc_target->find_thread (active_ptid);
  if (active_thr == nullptr)
    {
      active_thr = ::add_thread (proc_target, active_ptid);
      m_cpu_map[active_ptid.tid ()] = base_cpu;
    }
  return active_thr;
}

/* The Ravenscar Runtime exports a symbol which contains the ID of
   the thread that is currently running.  Try to locate that symbol
   and return its associated minimal symbol.
   Return NULL if not found.  */

static bound_minimal_symbol
get_running_thread_msymbol ()
{
  bound_minimal_symbol msym
    = lookup_minimal_symbol (current_program_space, running_thread_name);
  if (!msym.minsym)
    /* Older versions of the GNAT runtime were using a different
       (less ideal) name for the symbol where the active thread ID
       is stored.  If we couldn't find the symbol using the latest
       name, then try the old one.  */
    msym = lookup_minimal_symbol (current_program_space, "running_thread");

  return msym;
}

/* Return True if the Ada Ravenscar run-time can be found in the
   application.  */

static bool
has_ravenscar_runtime ()
{
  bound_minimal_symbol msym_ravenscar_runtime_initializer
    = lookup_minimal_symbol (current_program_space,
			     ravenscar_runtime_initializer);
  bound_minimal_symbol msym_known_tasks
    = lookup_minimal_symbol (current_program_space, known_tasks_name);
  bound_minimal_symbol msym_first_task
    = lookup_minimal_symbol (current_program_space, first_task_name);
  bound_minimal_symbol msym_running_thread = get_running_thread_msymbol ();

  return (msym_ravenscar_runtime_initializer.minsym
	  && (msym_known_tasks.minsym || msym_first_task.minsym)
	  && msym_running_thread.minsym);
}

/* Return True if the Ada Ravenscar run-time can be found in the
   application, and if it has been initialized on target.  */

bool
ravenscar_thread_target::runtime_initialized ()
{
  return active_task (1) != null_ptid;
}

/* Return the ID of the thread that is currently running.
   Return 0 if the ID could not be determined.  */

static CORE_ADDR
get_running_thread_id (int cpu)
{
  bound_minimal_symbol object_msym = get_running_thread_msymbol ();
  int object_size;
  int buf_size;
  gdb_byte *buf;
  CORE_ADDR object_addr;
  struct type *builtin_type_void_data_ptr
    = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;

  if (!object_msym.minsym)
    return 0;

  object_size = builtin_type_void_data_ptr->length ();
  object_addr = (object_msym.value_address ()
		 + (cpu - 1) * object_size);
  buf_size = object_size;
  buf = (gdb_byte *) alloca (buf_size);
  read_memory (object_addr, buf, buf_size);
  return extract_typed_address (buf, builtin_type_void_data_ptr);
}

void
ravenscar_thread_target::resume (ptid_t ptid, int step,
				 enum gdb_signal siggnal)
{
  /* If we see a wildcard resume, we simply pass that on.  Otherwise,
     arrange to resume the base ptid.  */
  inferior_ptid = m_base_ptid;
  if (ptid.is_pid ())
    {
      /* We only have one process, so resume all threads of it.  */
      ptid = minus_one_ptid;
    }
  else if (ptid != minus_one_ptid)
    ptid = m_base_ptid;
  beneath ()->resume (ptid, step, siggnal);
}

ptid_t
ravenscar_thread_target::wait (ptid_t ptid,
			       struct target_waitstatus *status,
			       target_wait_flags options)
{
  process_stratum_target *beneath
    = as_process_stratum_target (this->beneath ());
  ptid_t event_ptid;

  if (ptid != minus_one_ptid)
    ptid = m_base_ptid;
  event_ptid = beneath->wait (ptid, status, 0);
  /* Find any new threads that might have been created, and return the
     active thread.

     Only do it if the program is still alive, though.  Otherwise,
     this causes problems when debugging through the remote protocol,
     because we might try switching threads (and thus sending packets)
     after the remote has disconnected.  */
  if (status->kind () != TARGET_WAITKIND_EXITED
      && status->kind () != TARGET_WAITKIND_SIGNALLED
      && runtime_initialized ())
    {
      m_base_ptid = event_ptid;
      this->update_thread_list ();
      thread_info *thr = this->add_active_thread ();
      if (thr != nullptr)
	return thr->ptid;
    }
  return event_ptid;
}

/* Add the thread associated to the given TASK to the thread list
   (if the thread has already been added, this is a no-op).  */

void
ravenscar_thread_target::add_thread (struct ada_task_info *task)
{
  if (current_inferior ()->find_thread (task->ptid) == NULL)
    {
      ::add_thread (current_inferior ()->process_target (), task->ptid);
      m_cpu_map[task->ptid.tid ()] = task->base_cpu;
    }
}

void
ravenscar_thread_target::update_thread_list ()
{
  /* iterate_over_live_ada_tasks requires that inferior_ptid be set,
     but this isn't always the case in target methods.  So, we ensure
     it here.  */
  scoped_restore save_ptid = make_scoped_restore (&inferior_ptid,
						  m_base_ptid);

  /* Do not clear the thread list before adding the Ada task, to keep
     the thread that the process stratum has included into it
     (m_base_ptid) and the running thread, that may not have been included
     to system.tasking.debug's list yet.  */

  iterate_over_live_ada_tasks ([this] (struct ada_task_info *task)
			       {
				 this->add_thread (task);
			       });
}

ptid_t
ravenscar_thread_target::active_task (int cpu)
{
  CORE_ADDR tid = get_running_thread_id (cpu);

  if (tid == 0)
    return null_ptid;
  else
    return ptid_t (m_base_ptid.pid (), 0, tid);
}

bool
ravenscar_thread_target::thread_alive (ptid_t ptid)
{
  /* Ravenscar tasks are non-terminating.  */
  return true;
}

std::string
ravenscar_thread_target::pid_to_str (ptid_t ptid)
{
  if (!is_ravenscar_task (ptid))
    return beneath ()->pid_to_str (ptid);

  return string_printf ("Ravenscar Thread 0x%s",
			phex_nz (ptid.tid (), sizeof (ULONGEST)));
}

CORE_ADDR
ravenscar_arch_ops::get_stack_base (struct regcache *regcache) const
{
  struct gdbarch *gdbarch = regcache->arch ();
  const int sp_regnum = gdbarch_sp_regnum (gdbarch);
  ULONGEST stack_address;
  regcache_cooked_read_unsigned (regcache, sp_regnum, &stack_address);
  return (CORE_ADDR) stack_address;
}

void
ravenscar_arch_ops::supply_one_register (struct regcache *regcache,
					 int regnum,
					 CORE_ADDR descriptor,
					 CORE_ADDR stack_base) const
{
  CORE_ADDR addr;
  if (regnum >= first_stack_register && regnum <= last_stack_register)
    addr = stack_base;
  else
    addr = descriptor;
  addr += offsets[regnum];

  struct gdbarch *gdbarch = regcache->arch ();
  int size = register_size (gdbarch, regnum);
  gdb_byte *buf = (gdb_byte *) alloca (size);
  read_memory (addr, buf, size);
  regcache->raw_supply (regnum, buf);
}

void
ravenscar_arch_ops::fetch_register (struct regcache *regcache,
				    int regnum) const
{
  gdb_assert (regnum != -1);

  struct gdbarch *gdbarch = regcache->arch ();
  /* The tid is the thread_id field, which is a pointer to the thread.  */
  CORE_ADDR thread_descriptor_address
    = (CORE_ADDR) regcache->ptid ().tid ();

  int sp_regno = -1;
  CORE_ADDR stack_address = 0;
  if (regnum >= first_stack_register && regnum <= last_stack_register)
    {
      /* We must supply SP for get_stack_base, so recurse.  */
      sp_regno = gdbarch_sp_regnum (gdbarch);
      gdb_assert (!(sp_regno >= first_stack_register
		    && sp_regno <= last_stack_register));
      fetch_register (regcache, sp_regno);
      stack_address = get_stack_base (regcache);
    }

  if (regnum < offsets.size () && offsets[regnum] != -1)
    supply_one_register (regcache, regnum, thread_descriptor_address,
			 stack_address);
}

void
ravenscar_arch_ops::store_one_register (struct regcache *regcache, int regnum,
					CORE_ADDR descriptor,
					CORE_ADDR stack_base) const
{
  CORE_ADDR addr;
  if (regnum >= first_stack_register && regnum <= last_stack_register)
    addr = stack_base;
  else
    addr = descriptor;
  addr += offsets[regnum];

  struct gdbarch *gdbarch = regcache->arch ();
  int size = register_size (gdbarch, regnum);
  gdb_byte *buf = (gdb_byte *) alloca (size);
  regcache->raw_collect (regnum, buf);
  write_memory (addr, buf, size);
}

void
ravenscar_arch_ops::store_register (struct regcache *regcache,
				    int regnum) const
{
  gdb_assert (regnum != -1);

  /* The tid is the thread_id field, which is a pointer to the thread.  */
  CORE_ADDR thread_descriptor_address
    = (CORE_ADDR) regcache->ptid ().tid ();

  CORE_ADDR stack_address = 0;
  if (regnum >= first_stack_register && regnum <= last_stack_register)
    stack_address = get_stack_base (regcache);

  if (regnum < offsets.size () && offsets[regnum] != -1)
    store_one_register (regcache, regnum, thread_descriptor_address,
			stack_address);
}

/* Temporarily set the ptid of a regcache to some other value.  When
   this object is destroyed, the regcache's original ptid is
   restored.  */

class temporarily_change_regcache_ptid
{
public:

  temporarily_change_regcache_ptid (struct regcache *regcache, ptid_t new_ptid)
    : m_regcache (regcache),
      m_save_ptid (regcache->ptid ())
  {
    m_regcache->set_ptid (new_ptid);
  }

  ~temporarily_change_regcache_ptid ()
  {
    m_regcache->set_ptid (m_save_ptid);
  }

private:

  /* The regcache.  */
  struct regcache *m_regcache;
  /* The saved ptid.  */
  ptid_t m_save_ptid;
};

ravenscar_thread_target::fpu_state
ravenscar_thread_target::get_fpu_state (struct regcache *regcache,
					const ravenscar_arch_ops *arch_ops)
{
  /* We want to return true if the special FP register handling is
     needed.  If this target doesn't have lazy FP, then no special
     treatment is ever needed.  */
  if (!arch_ops->on_demand_fp ())
    return NOTHING_SPECIAL;

  bound_minimal_symbol fpu_context
    = lookup_minimal_symbol (current_program_space,
			     "system__bb__cpu_primitives__current_fpu_context",
			     nullptr, nullptr);
  /* If the symbol can't be found, just fall back.  */
  if (fpu_context.minsym == nullptr)
    return NO_FP_REGISTERS;

  type *ptr_type
    = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
  ptr_type = lookup_pointer_type (ptr_type);
  value *val = value_from_pointer (ptr_type, fpu_context.value_address ());

  int cpu = get_thread_base_cpu (regcache->ptid ());
  /* The array index type has a lower bound of 1 -- it is Ada code --
     so subtract 1 here.  */
  val = value_ptradd (val, cpu - 1);

  val = value_ind (val);
  CORE_ADDR fpu_task = value_as_long (val);

  /* The tid is the thread_id field, which is a pointer to the thread.  */
  CORE_ADDR thread_descriptor_address
    = (CORE_ADDR) regcache->ptid ().tid ();
  if (fpu_task == (thread_descriptor_address
		   + arch_ops->get_fpu_context_offset ()))
    return LIVE_FP_REGISTERS;

  int v_init_offset = arch_ops->get_v_init_offset ();
  gdb_byte init = 0;
  read_memory (thread_descriptor_address + v_init_offset, &init, 1);
  return init ? NOTHING_SPECIAL : NO_FP_REGISTERS;
}

void
ravenscar_thread_target::fetch_registers (struct regcache *regcache,
					  int regnum)
{
  ptid_t ptid = regcache->ptid ();

  if (runtime_initialized () && is_ravenscar_task (ptid))
    {
      struct gdbarch *gdbarch = regcache->arch ();
      bool is_active = task_is_currently_active (ptid);
      struct ravenscar_arch_ops *arch_ops = gdbarch_ravenscar_ops (gdbarch);
      std::optional<fpu_state> fp_state;

      int low_reg = regnum == -1 ? 0 : regnum;
      int high_reg = regnum == -1 ? gdbarch_num_regs (gdbarch) : regnum + 1;

      ptid_t base = get_base_thread_from_ravenscar_task (ptid);
      for (int i = low_reg; i < high_reg; ++i)
	{
	  bool use_beneath = false;
	  if (arch_ops->is_fp_register (i))
	    {
	      if (!fp_state.has_value ())
		fp_state = get_fpu_state (regcache, arch_ops);
	      if (*fp_state == NO_FP_REGISTERS)
		continue;
	      if (*fp_state == LIVE_FP_REGISTERS
		  || (is_active && *fp_state == NOTHING_SPECIAL))
		use_beneath = true;
	    }
	  else
	    use_beneath = is_active;

	  if (use_beneath)
	    {
	      temporarily_change_regcache_ptid changer (regcache, base);
	      beneath ()->fetch_registers (regcache, i);
	    }
	  else
	    arch_ops->fetch_register (regcache, i);
	}
    }
  else
    beneath ()->fetch_registers (regcache, regnum);
}

void
ravenscar_thread_target::store_registers (struct regcache *regcache,
					  int regnum)
{
  ptid_t ptid = regcache->ptid ();

  if (runtime_initialized () && is_ravenscar_task (ptid))
    {
      struct gdbarch *gdbarch = regcache->arch ();
      bool is_active = task_is_currently_active (ptid);
      struct ravenscar_arch_ops *arch_ops = gdbarch_ravenscar_ops (gdbarch);
      std::optional<fpu_state> fp_state;

      int low_reg = regnum == -1 ? 0 : regnum;
      int high_reg = regnum == -1 ? gdbarch_num_regs (gdbarch) : regnum + 1;

      ptid_t base = get_base_thread_from_ravenscar_task (ptid);
      for (int i = low_reg; i < high_reg; ++i)
	{
	  bool use_beneath = false;
	  if (arch_ops->is_fp_register (i))
	    {
	      if (!fp_state.has_value ())
		fp_state = get_fpu_state (regcache, arch_ops);
	      if (*fp_state == NO_FP_REGISTERS)
		continue;
	      if (*fp_state == LIVE_FP_REGISTERS
		  || (is_active && *fp_state == NOTHING_SPECIAL))
		use_beneath = true;
	    }
	  else
	    use_beneath = is_active;

	  if (use_beneath)
	    {
	      temporarily_change_regcache_ptid changer (regcache, base);
	      beneath ()->store_registers (regcache, i);
	    }
	  else
	    arch_ops->store_register (regcache, i);
	}
    }
  else
    beneath ()->store_registers (regcache, regnum);
}

void
ravenscar_thread_target::prepare_to_store (struct regcache *regcache)
{
  ptid_t ptid = regcache->ptid ();

  if (runtime_initialized () && is_ravenscar_task (ptid))
    {
      if (task_is_currently_active (ptid))
	{
	  ptid_t base = get_base_thread_from_ravenscar_task (ptid);
	  temporarily_change_regcache_ptid changer (regcache, base);
	  beneath ()->prepare_to_store (regcache);
	}
      else
	{
	  /* Nothing.  */
	}
    }
  else
    beneath ()->prepare_to_store (regcache);
}

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

bool
ravenscar_thread_target::stopped_by_sw_breakpoint ()
{
  scoped_restore_current_thread saver;
  set_base_thread_from_ravenscar_task (inferior_ptid);
  return beneath ()->stopped_by_sw_breakpoint ();
}

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

bool
ravenscar_thread_target::stopped_by_hw_breakpoint ()
{
  scoped_restore_current_thread saver;
  set_base_thread_from_ravenscar_task (inferior_ptid);
  return beneath ()->stopped_by_hw_breakpoint ();
}

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

bool
ravenscar_thread_target::stopped_by_watchpoint ()
{
  scoped_restore_current_thread saver;
  set_base_thread_from_ravenscar_task (inferior_ptid);
  return beneath ()->stopped_by_watchpoint ();
}

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

bool
ravenscar_thread_target::stopped_data_address (CORE_ADDR *addr_p)
{
  scoped_restore_current_thread saver;
  set_base_thread_from_ravenscar_task (inferior_ptid);
  return beneath ()->stopped_data_address (addr_p);
}

void
ravenscar_thread_target::mourn_inferior ()
{
  m_base_ptid = null_ptid;
  target_ops *beneath = this->beneath ();
  current_inferior ()->unpush_target (this);
  beneath->mourn_inferior ();
}

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

int
ravenscar_thread_target::core_of_thread (ptid_t ptid)
{
  scoped_restore_current_thread saver;
  set_base_thread_from_ravenscar_task (inferior_ptid);
  return beneath ()->core_of_thread (inferior_ptid);
}

/* Implement the target xfer_partial method.  */

enum target_xfer_status
ravenscar_thread_target::xfer_partial (enum target_object object,
				       const char *annex,
				       gdb_byte *readbuf,
				       const gdb_byte *writebuf,
				       ULONGEST offset, ULONGEST len,
				       ULONGEST *xfered_len)
{
  scoped_restore save_ptid = make_scoped_restore (&inferior_ptid);
  /* Calling get_base_thread_from_ravenscar_task can read memory from
     the inferior.  However, that function is written to prefer our
     internal map, so it should not result in recursive calls in
     practice.  */
  inferior_ptid = get_base_thread_from_ravenscar_task (inferior_ptid);
  return beneath ()->xfer_partial (object, annex, readbuf, writebuf,
				   offset, len, xfered_len);
}

/* Observer on inferior_created: push ravenscar thread stratum if needed.  */

static void
ravenscar_inferior_created (inferior *inf)
{
  const char *err_msg;

  if (!ravenscar_task_support
      || gdbarch_ravenscar_ops (current_inferior ()->arch ()) == NULL
      || !has_ravenscar_runtime ())
    return;

  err_msg = ada_get_tcb_types_info ();
  if (err_msg != NULL)
    {
      warning (_("%s. Task/thread support disabled."), err_msg);
      return;
    }

  ravenscar_thread_target *rtarget = new ravenscar_thread_target ();
  inf->push_target (target_ops_up (rtarget));
  thread_info *thr = rtarget->add_active_thread ();
  if (thr != nullptr)
    switch_to_thread (thr);
}

ptid_t
ravenscar_thread_target::get_ada_task_ptid (long lwp, ULONGEST thread)
{
  return ptid_t (m_base_ptid.pid (), 0, thread);
}

/* Command-list for the "set/show ravenscar" prefix command.  */
static struct cmd_list_element *set_ravenscar_list;
static struct cmd_list_element *show_ravenscar_list;

/* Implement the "show ravenscar task-switching" command.  */

static void
show_ravenscar_task_switching_command (struct ui_file *file, int from_tty,
				       struct cmd_list_element *c,
				       const char *value)
{
  if (ravenscar_task_support)
    gdb_printf (file, _("\
Support for Ravenscar task/thread switching is enabled\n"));
  else
    gdb_printf (file, _("\
Support for Ravenscar task/thread switching is disabled\n"));
}

/* Module startup initialization function, automagically called by
   init.c.  */

void _initialize_ravenscar ();
void
_initialize_ravenscar ()
{
  /* Notice when the inferior is created in order to push the
     ravenscar ops if needed.  */
  gdb::observers::inferior_created.attach (ravenscar_inferior_created,
					   "ravenscar-thread");

  add_setshow_prefix_cmd
    ("ravenscar", no_class,
     _("Prefix command for changing Ravenscar-specific settings."),
     _("Prefix command for showing Ravenscar-specific settings."),
     &set_ravenscar_list, &show_ravenscar_list,
     &setlist, &showlist);

  add_setshow_boolean_cmd ("task-switching", class_obscure,
			   &ravenscar_task_support, _("\
Enable or disable support for GNAT Ravenscar tasks."), _("\
Show whether support for GNAT Ravenscar tasks is enabled."),
			   _("\
Enable or disable support for task/thread switching with the GNAT\n\
Ravenscar run-time library for bareboard configuration."),
			   NULL, show_ravenscar_task_switching_command,
			   &set_ravenscar_list, &show_ravenscar_list);
}
