/* Generic remote debugging interface for simulators.

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

   Contributed by Cygnus Support.
   Steve Chamberlain (sac@cygnus.com).

   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 "gdb_bfd.h"
#include "inferior.h"
#include "infrun.h"
#include "value.h"
#include <ctype.h>
#include <fcntl.h>
#include <signal.h>
#include <setjmp.h>
#include "terminal.h"
#include "target.h"
#include "process-stratum-target.h"
#include "gdbcore.h"
#include "gdb/callback.h"
#include "gdb/remote-sim.h"
#include "command.h"
#include "regcache.h"
#include "sim-regno.h"
#include "arch-utils.h"
#include "readline/readline.h"
#include "gdbthread.h"
#include "gdbsupport/byte-vector.h"

/* Prototypes */

static void init_callbacks (void);

static void end_callbacks (void);

static int gdb_os_write_stdout (host_callback *, const char *, int);

static void gdb_os_flush_stdout (host_callback *);

static int gdb_os_write_stderr (host_callback *, const char *, int);

static void gdb_os_flush_stderr (host_callback *);

static int gdb_os_poll_quit (host_callback *);

/* printf_filtered is depreciated.  */
static void gdb_os_printf_filtered (host_callback *, const char *, ...);

static void gdb_os_vprintf_filtered (host_callback *, const char *, va_list);

static void gdb_os_evprintf_filtered (host_callback *, const char *, va_list);

static void gdb_os_error (host_callback *, const char *, ...)
     ATTRIBUTE_NORETURN;

/* Naming convention:

   sim_* are the interface to the simulator (see remote-sim.h).
   gdbsim_* are stuff which is internal to gdb.  */

/* Value of the next pid to allocate for an inferior.  As indicated
   elsewhere, its initial value is somewhat arbitrary; it's critical
   though that it's not zero or negative.  */
static int next_pid;
#define INITIAL_PID 42000

/* Simulator-specific, per-inferior state.  */
struct sim_inferior_data {
  explicit sim_inferior_data (SIM_DESC desc)
    : gdbsim_desc (desc),
      remote_sim_ptid (next_pid, 0, next_pid)
  {
    gdb_assert (remote_sim_ptid != null_ptid);
    ++next_pid;
  }

  ~sim_inferior_data ();

  /* Flag which indicates whether or not the program has been loaded.  */
  int program_loaded = 0;

  /* Simulator descriptor for this inferior.  */
  SIM_DESC gdbsim_desc;

  /* This is the ptid we use for this particular simulator instance.  Its
     value is somewhat arbitrary, as the simulator target don't have a
     notion of tasks or threads, but we need something non-null to place
     in inferior_ptid.  For simulators which permit multiple instances,
     we also need a unique identifier to use for each inferior.  */
  ptid_t remote_sim_ptid;

  /* Signal with which to resume.  */
  enum gdb_signal resume_siggnal = GDB_SIGNAL_0;

  /* Flag which indicates whether resume should step or not.  */
  int resume_step = 0;
};

static const target_info gdbsim_target_info = {
  "sim",
  N_("simulator"),
  N_("Use the compiled-in simulator.")
};

struct gdbsim_target final
  : public memory_breakpoint_target<process_stratum_target>
{
  gdbsim_target () = default;

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

  void close () override;

  void detach (inferior *inf, int) override;

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

  void fetch_registers (struct regcache *, int) override;
  void store_registers (struct regcache *, int) override;
  void prepare_to_store (struct regcache *) 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;

  void files_info () override;

  void kill () override;

  void load (const char *, int) override;

  bool can_create_inferior () override { return true; }
  void create_inferior (const char *, const std::string &,
			char **, int) override;

  void mourn_inferior () override;

  void interrupt () override;

  bool thread_alive (ptid_t ptid) override;

  std::string pid_to_str (ptid_t) override;

  bool has_all_memory ()  override;
  bool has_memory ()  override;

private:
  sim_inferior_data *get_inferior_data_by_ptid (ptid_t ptid,
						int sim_instance_needed);
  void resume_one_inferior (inferior *inf, bool step, gdb_signal siggnal);
  void close_one_inferior (inferior *inf);
};

static struct gdbsim_target gdbsim_ops;

static inferior_key<sim_inferior_data> sim_inferior_data_key;

/* Flag indicating the "open" status of this module.  It's set to 1
   in gdbsim_open() and 0 in gdbsim_close().  */
static int gdbsim_is_open = 0;

/* Argument list to pass to sim_open().  It is allocated in gdbsim_open()
   and deallocated in gdbsim_close().  The lifetime needs to extend beyond
   the call to gdbsim_open() due to the fact that other sim instances other
   than the first will be allocated after the gdbsim_open() call.  */
static char **sim_argv = NULL;

/* OS-level callback functions for write, flush, etc.  */
static host_callback gdb_callback;
static int callbacks_initialized = 0;

/* Flags indicating whether or not a sim instance is needed.  One of these
   flags should be passed to get_sim_inferior_data().  */

enum {SIM_INSTANCE_NOT_NEEDED = 0, SIM_INSTANCE_NEEDED = 1};

/* Obtain pointer to per-inferior simulator data, allocating it if necessary.
   Attempt to open the sim if SIM_INSTANCE_NEEDED is true.  */

static struct sim_inferior_data *
get_sim_inferior_data (struct inferior *inf, int sim_instance_needed)
{
  SIM_DESC sim_desc = NULL;
  struct sim_inferior_data *sim_data = sim_inferior_data_key.get (inf);

  /* Try to allocate a new sim instance, if needed.  We do this ahead of
     a potential allocation of a sim_inferior_data struct in order to
     avoid needlessly allocating that struct in the event that the sim
     instance allocation fails.  */
  if (sim_instance_needed == SIM_INSTANCE_NEEDED
      && (sim_data == NULL || sim_data->gdbsim_desc == NULL))
    {
      sim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, sim_argv);
      if (sim_desc == NULL)
	error (_("Unable to create simulator instance for inferior %d."),
	       inf->num);

      /* Check if the sim descriptor is the same as that of another
	 inferior.  */
      for (inferior *other_inf : all_inferiors ())
	{
	  sim_inferior_data *other_sim_data
	    = sim_inferior_data_key.get (other_inf);

	  if (other_sim_data != NULL
	      && other_sim_data->gdbsim_desc == sim_desc)
	    {
	      /* We don't close the descriptor due to the fact that it's
		 shared with some other inferior.  If we were to close it,
		 that might needlessly muck up the other inferior.  Of
		 course, it's possible that the damage has already been
		 done...  Note that it *will* ultimately be closed during
		 cleanup of the other inferior.  */
	      sim_desc = NULL;
	      error (
_("Inferior %d and inferior %d would have identical simulator state.\n"
 "(This simulator does not support the running of more than one inferior.)"),
		     inf->num, other_inf->num);
	    }
	}
    }

  if (sim_data == NULL)
    {
      sim_data = sim_inferior_data_key.emplace (inf, sim_desc);
    }
  else if (sim_desc)
    {
      /* This handles the case where sim_data was allocated prior to
	 needing a sim instance.  */
      sim_data->gdbsim_desc = sim_desc;
    }


  return sim_data;
}

/* Return pointer to per-inferior simulator data using PTID to find the
   inferior in question.  Return NULL when no inferior is found or
   when ptid has a zero or negative pid component.  */

sim_inferior_data *
gdbsim_target::get_inferior_data_by_ptid (ptid_t ptid,
					  int sim_instance_needed)
{
  struct inferior *inf;
  int pid = ptid.pid ();

  if (pid <= 0)
    return NULL;

  inf = find_inferior_pid (this, pid);

  if (inf)
    return get_sim_inferior_data (inf, sim_instance_needed);
  else
    return NULL;
}

/* Free the per-inferior simulator data.  */

sim_inferior_data::~sim_inferior_data ()
{
  if (gdbsim_desc)
    sim_close (gdbsim_desc, 0);
}

static void
dump_mem (const gdb_byte *buf, int len)
{
  fputs_unfiltered ("\t", gdb_stdlog);

  if (len == 8 || len == 4)
    {
      uint32_t l[2];

      memcpy (l, buf, len);
      fprintf_unfiltered (gdb_stdlog, "0x%08x", l[0]);
      if (len == 8)
	fprintf_unfiltered (gdb_stdlog, " 0x%08x", l[1]);
    }
  else
    {
      int i;

      for (i = 0; i < len; i++)
	fprintf_unfiltered (gdb_stdlog, "0x%02x ", buf[i]);
    }

  fputs_unfiltered ("\n", gdb_stdlog);
}

/* Initialize gdb_callback.  */

static void
init_callbacks (void)
{
  if (!callbacks_initialized)
    {
      gdb_callback = default_callback;
      gdb_callback.init (&gdb_callback);
      gdb_callback.write_stdout = gdb_os_write_stdout;
      gdb_callback.flush_stdout = gdb_os_flush_stdout;
      gdb_callback.write_stderr = gdb_os_write_stderr;
      gdb_callback.flush_stderr = gdb_os_flush_stderr;
      gdb_callback.printf_filtered = gdb_os_printf_filtered;
      gdb_callback.vprintf_filtered = gdb_os_vprintf_filtered;
      gdb_callback.evprintf_filtered = gdb_os_evprintf_filtered;
      gdb_callback.error = gdb_os_error;
      gdb_callback.poll_quit = gdb_os_poll_quit;
      gdb_callback.magic = HOST_CALLBACK_MAGIC;
      callbacks_initialized = 1;
    }
}

/* Release callbacks (free resources used by them).  */

static void
end_callbacks (void)
{
  if (callbacks_initialized)
    {
      gdb_callback.shutdown (&gdb_callback);
      callbacks_initialized = 0;
    }
}

/* GDB version of os_write_stdout callback.  */

static int
gdb_os_write_stdout (host_callback *p, const char *buf, int len)
{
  gdb_stdtarg->write (buf, len);
  return len;
}

/* GDB version of os_flush_stdout callback.  */

static void
gdb_os_flush_stdout (host_callback *p)
{
  gdb_stdtarg->flush ();
}

/* GDB version of os_write_stderr callback.  */

static int
gdb_os_write_stderr (host_callback *p, const char *buf, int len)
{
  int i;
  char b[2];

  for (i = 0; i < len; i++)
    {
      b[0] = buf[i];
      b[1] = 0;
      gdb_stdtargerr->puts (b);
    }
  return len;
}

/* GDB version of os_flush_stderr callback.  */

static void
gdb_os_flush_stderr (host_callback *p)
{
  gdb_stdtargerr->flush ();
}

/* GDB version of printf_filtered callback.  */

static void ATTRIBUTE_PRINTF (2, 3)
gdb_os_printf_filtered (host_callback * p, const char *format, ...)
{
  va_list args;

  va_start (args, format);
  vfprintf_filtered (gdb_stdout, format, args);
  va_end (args);
}

/* GDB version of error vprintf_filtered.  */

static void ATTRIBUTE_PRINTF (2, 0)
gdb_os_vprintf_filtered (host_callback * p, const char *format, va_list ap)
{
  vfprintf_filtered (gdb_stdout, format, ap);
}

/* GDB version of error evprintf_filtered.  */

static void ATTRIBUTE_PRINTF (2, 0)
gdb_os_evprintf_filtered (host_callback * p, const char *format, va_list ap)
{
  vfprintf_filtered (gdb_stderr, format, ap);
}

/* GDB version of error callback.  */

static void ATTRIBUTE_PRINTF (2, 3)
gdb_os_error (host_callback * p, const char *format, ...)
{
  va_list args;

  va_start (args, format);
  verror (format, args);
  va_end (args);
}

int
one2one_register_sim_regno (struct gdbarch *gdbarch, int regnum)
{
  /* Only makes sense to supply raw registers.  */
  gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch));
  return regnum;
}

void
gdbsim_target::fetch_registers (struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  struct inferior *inf = find_inferior_ptid (this, regcache->ptid ());
  struct sim_inferior_data *sim_data
    = get_sim_inferior_data (inf, SIM_INSTANCE_NEEDED);

  if (regno == -1)
    {
      for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
	fetch_registers (regcache, regno);
      return;
    }

  switch (gdbarch_register_sim_regno (gdbarch, regno))
    {
    case LEGACY_SIM_REGNO_IGNORE:
      break;
    case SIM_REGNO_DOES_NOT_EXIST:
      {
	/* For moment treat a `does not exist' register the same way
	   as an ``unavailable'' register.  */
	regcache->raw_supply_zeroed (regno);
	break;
      }

    default:
      {
	static int warn_user = 1;
	int regsize = register_size (gdbarch, regno);
	gdb::byte_vector buf (regsize, 0);
	int nr_bytes;

	gdb_assert (regno >= 0 && regno < gdbarch_num_regs (gdbarch));
	nr_bytes = sim_fetch_register (sim_data->gdbsim_desc,
				       gdbarch_register_sim_regno
					 (gdbarch, regno),
				       buf.data (), regsize);
	if (nr_bytes > 0 && nr_bytes != regsize && warn_user)
	  {
	    fprintf_unfiltered (gdb_stderr,
				"Size of register %s (%d/%d) "
				"incorrect (%d instead of %d))",
				gdbarch_register_name (gdbarch, regno),
				regno,
				gdbarch_register_sim_regno (gdbarch, regno),
				nr_bytes, regsize);
	    warn_user = 0;
	  }
	/* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0'
	   indicating that GDB and the SIM have different ideas about
	   which registers are fetchable.  */
	/* Else if (nr_bytes < 0): an old simulator, that doesn't
	   think to return the register size.  Just assume all is ok.  */
	regcache->raw_supply (regno, buf.data ());
	if (remote_debug)
	  {
	    fprintf_unfiltered (gdb_stdlog,
				"gdbsim_fetch_register: %d", regno);
	    /* FIXME: We could print something more intelligible.  */
	    dump_mem (buf.data (), regsize);
	  }
	break;
      }
    }
}


void
gdbsim_target::store_registers (struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = regcache->arch ();
  struct inferior *inf = find_inferior_ptid (this, regcache->ptid ());
  struct sim_inferior_data *sim_data
    = get_sim_inferior_data (inf, SIM_INSTANCE_NEEDED);

  if (regno == -1)
    {
      for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
	store_registers (regcache, regno);
      return;
    }
  else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0)
    {
      int regsize = register_size (gdbarch, regno);
      gdb::byte_vector tmp (regsize);
      int nr_bytes;

      regcache->cooked_read (regno, tmp.data ());
      nr_bytes = sim_store_register (sim_data->gdbsim_desc,
				     gdbarch_register_sim_regno
				       (gdbarch, regno),
				     tmp.data (), regsize);

      if (nr_bytes > 0 && nr_bytes != regsize)
	internal_error (__FILE__, __LINE__,
			_("Register size different to expected"));
      if (nr_bytes < 0)
	internal_error (__FILE__, __LINE__,
			_("Register %d not updated"), regno);
      if (nr_bytes == 0)
	warning (_("Register %s not updated"),
		 gdbarch_register_name (gdbarch, regno));

      if (remote_debug)
	{
	  fprintf_unfiltered (gdb_stdlog, "gdbsim_store_register: %d", regno);
	  /* FIXME: We could print something more intelligible.  */
	  dump_mem (tmp.data (), regsize);
	}
    }
}

/* Kill the running program.  This may involve closing any open files
   and releasing other resources acquired by the simulated program.  */

void
gdbsim_target::kill ()
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "gdbsim_kill\n");

  /* There is no need to `kill' running simulator - the simulator is
     not running.  Mourning it is enough.  */
  target_mourn_inferior (inferior_ptid);
}

/* Load an executable file into the target process.  This is expected to
   not only bring new code into the target process, but also to update
   GDB's symbol tables to match.  */

void
gdbsim_target::load (const char *args, int fromtty)
{
  const char *prog;
  struct sim_inferior_data *sim_data
    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);

  if (args == NULL)
      error_no_arg (_("program to load"));

  gdb_argv argv (args);

  prog = tilde_expand (argv[0]);

  if (argv[1] != NULL)
    error (_("GDB sim does not yet support a load offset."));

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "gdbsim_load: prog \"%s\"\n", prog);

  /* FIXME: We will print two messages on error.
     Need error to either not print anything if passed NULL or need
     another routine that doesn't take any arguments.  */
  if (sim_load (sim_data->gdbsim_desc, prog, NULL, fromtty) == SIM_RC_FAIL)
    error (_("unable to load program"));

  /* FIXME: If a load command should reset the targets registers then
     a call to sim_create_inferior() should go here.  */

  sim_data->program_loaded = 1;
}


/* Start an inferior process and set inferior_ptid to its pid.
   EXEC_FILE is the file to run.
   ARGS is a string containing the arguments to the program.
   ENV is the environment vector to pass.  Errors reported with error().
   On VxWorks and various standalone systems, we ignore exec_file.  */
/* This is called not only when we first attach, but also when the
   user types "run" after having attached.  */

void
gdbsim_target::create_inferior (const char *exec_file,
				const std::string &allargs,
				char **env, int from_tty)
{
  struct sim_inferior_data *sim_data
    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
  int len;
  char *arg_buf;
  const char *args = allargs.c_str ();

  if (exec_file == 0 || exec_bfd == 0)
    warning (_("No executable file specified."));
  if (!sim_data->program_loaded)
    warning (_("No program loaded."));

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog,
			"gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n",
			(exec_file ? exec_file : "(NULL)"),
			args);

  if (inferior_ptid == sim_data->remote_sim_ptid)
    kill ();
  remove_breakpoints ();
  init_wait_for_inferior ();

  gdb_argv built_argv;
  if (exec_file != NULL)
    {
      len = strlen (exec_file) + 1 + allargs.size () + 1 + /*slop */ 10;
      arg_buf = (char *) alloca (len);
      arg_buf[0] = '\0';
      strcat (arg_buf, exec_file);
      strcat (arg_buf, " ");
      strcat (arg_buf, args);
      built_argv.reset (arg_buf);
    }

  if (sim_create_inferior (sim_data->gdbsim_desc, exec_bfd,
			   built_argv.get (), env)
      != SIM_RC_OK)
    error (_("Unable to create sim inferior."));

  inferior_appeared (current_inferior (),
		     sim_data->remote_sim_ptid.pid ());
  thread_info *thr = add_thread_silent (this, sim_data->remote_sim_ptid);
  switch_to_thread (thr);

  insert_breakpoints ();	/* Needed to get correct instruction
				   in cache.  */

  clear_proceed_status (0);
}

/* The open routine takes the rest of the parameters from the command,
   and (if successful) pushes a new target onto the stack.
   Targets should supply this routine, if only to provide an error message.  */
/* Called when selecting the simulator.  E.g. (gdb) target sim name.  */

static void
gdbsim_target_open (const char *args, int from_tty)
{
  int len;
  char *arg_buf;
  struct sim_inferior_data *sim_data;
  const char *sysroot;
  SIM_DESC gdbsim_desc;

  sysroot = gdb_sysroot;
  if (is_target_filename (sysroot))
    sysroot += strlen (TARGET_SYSROOT_PREFIX);

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog,
			"gdbsim_open: args \"%s\"\n", args ? args : "(null)");

  /* Ensure that the sim target is not on the target stack.  This is
     necessary, because if it is on the target stack, the call to
     push_target below will invoke sim_close(), thus freeing various
     state (including a sim instance) that we allocate prior to
     invoking push_target().  We want to delay the push_target()
     operation until after we complete those operations which could
     error out.  */
  if (gdbsim_is_open)
    unpush_target (&gdbsim_ops);

  len = (7 + 1			/* gdbsim */
	 + strlen (" -E little")
	 + strlen (" --architecture=xxxxxxxxxx")
	 + strlen (" --sysroot=") + strlen (sysroot) +
	 + (args ? strlen (args) : 0)
	 + 50) /* slack */ ;
  arg_buf = (char *) alloca (len);
  strcpy (arg_buf, "gdbsim");	/* 7 */
  /* Specify the byte order for the target when it is explicitly
     specified by the user (not auto detected).  */
  switch (selected_byte_order ())
    {
    case BFD_ENDIAN_BIG:
      strcat (arg_buf, " -E big");
      break;
    case BFD_ENDIAN_LITTLE:
      strcat (arg_buf, " -E little");
      break;
    case BFD_ENDIAN_UNKNOWN:
      break;
    }
  /* Specify the architecture of the target when it has been
     explicitly specified */
  if (selected_architecture_name () != NULL)
    {
      strcat (arg_buf, " --architecture=");
      strcat (arg_buf, selected_architecture_name ());
    }
  /* Pass along gdb's concept of the sysroot.  */
  strcat (arg_buf, " --sysroot=");
  strcat (arg_buf, sysroot);
  /* finally, any explicit args */
  if (args)
    {
      strcat (arg_buf, " ");	/* 1 */
      strcat (arg_buf, args);
    }

  gdb_argv argv (arg_buf);
  sim_argv = argv.release ();

  init_callbacks ();
  gdbsim_desc = sim_open (SIM_OPEN_DEBUG, &gdb_callback, exec_bfd, sim_argv);

  if (gdbsim_desc == 0)
    {
      freeargv (sim_argv);
      sim_argv = NULL;
      error (_("unable to create simulator instance"));
    }

  /* Reset the pid numberings for this batch of sim instances.  */
  next_pid = INITIAL_PID;

  /* Allocate the inferior data, but do not allocate a sim instance
     since we've already just done that.  */
  sim_data = get_sim_inferior_data (current_inferior (),
				    SIM_INSTANCE_NOT_NEEDED);

  sim_data->gdbsim_desc = gdbsim_desc;

  push_target (&gdbsim_ops);
  printf_filtered ("Connected to the simulator.\n");

  /* There's nothing running after "target sim" or "load"; not until
     "run".  */
  switch_to_no_thread ();

  gdbsim_is_open = 1;
}

/* Helper for gdbsim_target::close.  */

void
gdbsim_target::close_one_inferior (inferior *inf)
{
  struct sim_inferior_data *sim_data = sim_inferior_data_key.get (inf);
  if (sim_data != NULL)
    {
      ptid_t ptid = sim_data->remote_sim_ptid;

      sim_inferior_data_key.clear (inf);

      /* Having a ptid allocated and stored in remote_sim_ptid does
	 not mean that a corresponding inferior was ever created.
	 Thus we need to verify the existence of an inferior using the
	 pid in question before setting inferior_ptid via
	 switch_to_thread() or mourning the inferior.  */
      if (find_inferior_ptid (this, ptid) != NULL)
	{
	  switch_to_thread (this, ptid);
	  generic_mourn_inferior ();
	}
    }
}

/* Close out all files and local state before this target loses control.  */

void
gdbsim_target::close ()
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "gdbsim_close\n");

  for (inferior *inf : all_inferiors (this))
    close_one_inferior (inf);

  if (sim_argv != NULL)
    {
      freeargv (sim_argv);
      sim_argv = NULL;
    }

  end_callbacks ();

  gdbsim_is_open = 0;
}

/* Takes a program previously attached to and detaches it.
   The program may resume execution (some targets do, some don't) and will
   no longer stop on signals, etc.  We better not have left any breakpoints
   in the program or it'll die when it hits one.  FROM_TTY says whether to be
   verbose or not.  */
/* Terminate the open connection to the remote debugger.
   Use this when you want to detach and do something else with your gdb.  */

void
gdbsim_target::detach (inferior *inf, int from_tty)
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "gdbsim_detach\n");

  unpush_target (this);		/* calls gdbsim_close to do the real work */
  if (from_tty)
    printf_filtered ("Ending simulator %s debugging\n", target_shortname);
}

/* Resume execution of the target process.  STEP says whether to single-step
   or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
   to the target, or zero for no signal.  */

void
gdbsim_target::resume_one_inferior (inferior *inf, bool step,
				    gdb_signal siggnal)
{
  struct sim_inferior_data *sim_data
    = get_sim_inferior_data (inf, SIM_INSTANCE_NOT_NEEDED);

  if (sim_data)
    {
      sim_data->resume_siggnal = siggnal;
      sim_data->resume_step = step;

      if (remote_debug)
	fprintf_unfiltered (gdb_stdlog,
			    _("gdbsim_resume: pid %d, step %d, signal %d\n"),
			    inf->pid, step, siggnal);
    }
}

void
gdbsim_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
{
  struct sim_inferior_data *sim_data
    = get_inferior_data_by_ptid (ptid, SIM_INSTANCE_NOT_NEEDED);

  /* We don't access any sim_data members within this function.
     What's of interest is whether or not the call to
     get_sim_inferior_data_by_ptid(), above, is able to obtain a
     non-NULL pointer.  If it managed to obtain a non-NULL pointer, we
     know we have a single inferior to consider.  If it's NULL, we
     either have multiple inferiors to resume or an error condition.  */

  if (sim_data)
    resume_one_inferior (find_inferior_ptid (this, ptid), step, siggnal);
  else if (ptid == minus_one_ptid)
    {
      for (inferior *inf : all_inferiors (this))
	resume_one_inferior (inf, step, siggnal);
    }
  else
    error (_("The program is not being run."));
}

/* Notify the simulator of an asynchronous request to interrupt.

   The simulator shall ensure that the interrupt request is eventually
   delivered to the simulator.  If the call is made while the
   simulator is not running then the interrupt request is processed when
   the simulator is next resumed.

   For simulators that do not support this operation, just abort.  */

void
gdbsim_target::interrupt ()
{
  for (inferior *inf : all_inferiors ())
    {
      sim_inferior_data *sim_data
	= get_sim_inferior_data (inf, SIM_INSTANCE_NEEDED);

      if (sim_data != nullptr && !sim_stop (sim_data->gdbsim_desc))
	  quit ();
    }
}

/* GDB version of os_poll_quit callback.
   Taken from gdb/util.c - should be in a library.  */

static int
gdb_os_poll_quit (host_callback *p)
{
  if (deprecated_ui_loop_hook != NULL)
    deprecated_ui_loop_hook (0);

  if (check_quit_flag ())	/* gdb's idea of quit */
    return 1;
  return 0;
}

/* Wait for inferior process to do something.  Return pid of child,
   or -1 in case of error; store status through argument pointer STATUS,
   just as `wait' would.  */

static void
gdbsim_cntrl_c (int signo)
{
  gdbsim_ops.interrupt ();
}

ptid_t
gdbsim_target::wait (ptid_t ptid, struct target_waitstatus *status, int options)
{
  struct sim_inferior_data *sim_data;
  static sighandler_t prev_sigint;
  int sigrc = 0;
  enum sim_stop reason = sim_running;

  /* This target isn't able to (yet) resume more than one inferior at a time.
     When ptid is minus_one_ptid, just use the current inferior.  If we're
     given an explicit pid, we'll try to find it and use that instead.  */
  if (ptid == minus_one_ptid)
    sim_data = get_sim_inferior_data (current_inferior (),
				      SIM_INSTANCE_NEEDED);
  else
    {
      sim_data = get_inferior_data_by_ptid (ptid, SIM_INSTANCE_NEEDED);
      if (sim_data == NULL)
	error (_("Unable to wait for pid %d.  Inferior not found."),
	       ptid.pid ());
    }

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "gdbsim_wait\n");

#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
  {
    struct sigaction sa, osa;
    sa.sa_handler = gdbsim_cntrl_c;
    sigemptyset (&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction (SIGINT, &sa, &osa);
    prev_sigint = osa.sa_handler;
  }
#else
  prev_sigint = signal (SIGINT, gdbsim_cntrl_c);
#endif
  sim_resume (sim_data->gdbsim_desc, sim_data->resume_step,
	      sim_data->resume_siggnal);

  signal (SIGINT, prev_sigint);
  sim_data->resume_step = 0;

  sim_stop_reason (sim_data->gdbsim_desc, &reason, &sigrc);

  switch (reason)
    {
    case sim_exited:
      status->kind = TARGET_WAITKIND_EXITED;
      status->value.integer = sigrc;
      break;
    case sim_stopped:
      switch (sigrc)
	{
	case GDB_SIGNAL_ABRT:
	  quit ();
	  break;
	case GDB_SIGNAL_INT:
	case GDB_SIGNAL_TRAP:
	default:
	  status->kind = TARGET_WAITKIND_STOPPED;
	  status->value.sig = (enum gdb_signal) sigrc;
	  break;
	}
      break;
    case sim_signalled:
      status->kind = TARGET_WAITKIND_SIGNALLED;
      status->value.sig = (enum gdb_signal) sigrc;
      break;
    case sim_running:
    case sim_polling:
      /* FIXME: Is this correct?  */
      break;
    }

  return sim_data->remote_sim_ptid;
}

/* Get ready to modify the registers array.  On machines which store
   individual registers, this doesn't need to do anything.  On machines
   which store all the registers in one fell swoop, this makes sure
   that registers contains all the registers from the program being
   debugged.  */

void
gdbsim_target::prepare_to_store (struct regcache *regcache)
{
  /* Do nothing, since we can store individual regs.  */
}

/* Helper for gdbsim_xfer_partial that handles memory transfers.
   Arguments are like target_xfer_partial.  */

static enum target_xfer_status
gdbsim_xfer_memory (struct target_ops *target,
		    gdb_byte *readbuf, const gdb_byte *writebuf,
		    ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len)
{
  struct sim_inferior_data *sim_data
    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NOT_NEEDED);
  int l;

  /* If this target doesn't have memory yet, return 0 causing the
     request to be passed to a lower target, hopefully an exec
     file.  */
  if (!target->has_memory ())
    return TARGET_XFER_EOF;

  if (!sim_data->program_loaded)
    error (_("No program loaded."));

  /* Note that we obtained the sim_data pointer above using
     SIM_INSTANCE_NOT_NEEDED.  We do this so that we don't needlessly
     allocate a sim instance prior to loading a program.   If we
     get to this point in the code though, gdbsim_desc should be
     non-NULL.  (Note that a sim instance is needed in order to load
     the program...)  */
  gdb_assert (sim_data->gdbsim_desc != NULL);

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog,
			"gdbsim_xfer_memory: readbuf %s, writebuf %s, "
			"memaddr %s, len %s\n",
			host_address_to_string (readbuf),
			host_address_to_string (writebuf),
			paddress (target_gdbarch (), memaddr),
			pulongest (len));

  if (writebuf)
    {
      if (remote_debug && len > 0)
	dump_mem (writebuf, len);
      l = sim_write (sim_data->gdbsim_desc, memaddr, writebuf, len);
    }
  else
    {
      l = sim_read (sim_data->gdbsim_desc, memaddr, readbuf, len);
      if (remote_debug && len > 0)
	dump_mem (readbuf, len);
    }
  if (l > 0)
    {
      *xfered_len = (ULONGEST) l;
      return TARGET_XFER_OK;
    }
  else if (l == 0)
    return TARGET_XFER_EOF;
  else
    return TARGET_XFER_E_IO;
}

/* Target to_xfer_partial implementation.  */

enum target_xfer_status
gdbsim_target::xfer_partial (enum target_object object,
			     const char *annex, gdb_byte *readbuf,
			     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
			     ULONGEST *xfered_len)
{
  switch (object)
    {
    case TARGET_OBJECT_MEMORY:
      return gdbsim_xfer_memory (this, readbuf, writebuf, offset, len,
				 xfered_len);

    default:
      return TARGET_XFER_E_IO;
    }
}

void
gdbsim_target::files_info ()
{
  struct sim_inferior_data *sim_data
    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
  const char *file = "nothing";

  if (exec_bfd)
    file = bfd_get_filename (exec_bfd);

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "gdbsim_files_info: file \"%s\"\n", file);

  if (exec_bfd)
    {
      fprintf_unfiltered (gdb_stdlog, "\tAttached to %s running program %s\n",
			  target_shortname, file);
      sim_info (sim_data->gdbsim_desc, 0);
    }
}

/* Clear the simulator's notion of what the break points are.  */

void
gdbsim_target::mourn_inferior ()
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "gdbsim_mourn_inferior:\n");

  remove_breakpoints ();
  generic_mourn_inferior ();
}

/* Pass the command argument through to the simulator verbatim.  The
   simulator must do any command interpretation work.  */

static void
simulator_command (const char *args, int from_tty)
{
  struct sim_inferior_data *sim_data;

  /* We use inferior_data() instead of get_sim_inferior_data() here in
     order to avoid attaching a sim_inferior_data struct to an
     inferior unnecessarily.  The reason we take such care here is due
     to the fact that this function, simulator_command(), may be called
     even when the sim target is not active.  If we were to use
     get_sim_inferior_data() here, it is possible that this call would
     be made either prior to gdbsim_open() or after gdbsim_close(),
     thus allocating memory that would not be garbage collected until
     the ultimate destruction of the associated inferior.  */

  sim_data  = sim_inferior_data_key.get (current_inferior ());
  if (sim_data == NULL || sim_data->gdbsim_desc == NULL)
    {

      /* PREVIOUSLY: The user may give a command before the simulator
	 is opened. [...] (??? assuming of course one wishes to
	 continue to allow commands to be sent to unopened simulators,
	 which isn't entirely unreasonable).  */

      /* The simulator is a builtin abstraction of a remote target.
	 Consistent with that model, access to the simulator, via sim
	 commands, is restricted to the period when the channel to the
	 simulator is open.  */

      error (_("Not connected to the simulator target"));
    }

  sim_do_command (sim_data->gdbsim_desc, args);

  /* Invalidate the register cache, in case the simulator command does
     something funny.  */
  registers_changed ();
}

static void
sim_command_completer (struct cmd_list_element *ignore,
		       completion_tracker &tracker,
		       const char *text, const char *word)
{
  struct sim_inferior_data *sim_data;

  sim_data = sim_inferior_data_key.get (current_inferior ());
  if (sim_data == NULL || sim_data->gdbsim_desc == NULL)
    return;

  /* sim_complete_command returns a NULL-terminated malloc'ed array of
     malloc'ed strings.  */
  struct sim_completions_deleter
  {
    void operator() (char **ptr) const
    {
      for (size_t i = 0; ptr[i] != NULL; i++)
	xfree (ptr[i]);
      xfree (ptr);
    }
  };

  std::unique_ptr<char *[], sim_completions_deleter> sim_completions
    (sim_complete_command (sim_data->gdbsim_desc, text, word));
  if (sim_completions == NULL)
    return;

  /* Count the elements and add completions from tail to head because
     below we'll swap elements out of the array in case add_completion
     throws and the deleter deletes until it finds a NULL element.  */
  size_t count = 0;
  while (sim_completions[count] != NULL)
    count++;

  for (size_t i = count; i > 0; i--)
    {
      gdb::unique_xmalloc_ptr<char> match (sim_completions[i - 1]);
      sim_completions[i - 1] = NULL;
      tracker.add_completion (std::move (match));
    }
}

/* Check to see if a thread is still alive.  */

bool
gdbsim_target::thread_alive (ptid_t ptid)
{
  struct sim_inferior_data *sim_data
    = get_inferior_data_by_ptid (ptid, SIM_INSTANCE_NOT_NEEDED);

  if (sim_data == NULL)
    return false;

  if (ptid == sim_data->remote_sim_ptid)
    /* The simulators' task is always alive.  */
    return true;

  return false;
}

/* Convert a thread ID to a string.  */

std::string
gdbsim_target::pid_to_str (ptid_t ptid)
{
  return normal_pid_to_str (ptid);
}

/* Simulator memory may be accessed after the program has been loaded.  */

bool
gdbsim_target::has_all_memory ()
{
  struct sim_inferior_data *sim_data
    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NOT_NEEDED);

  if (!sim_data->program_loaded)
    return false;

  return true;
}

bool
gdbsim_target::has_memory ()
{
  struct sim_inferior_data *sim_data
    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NOT_NEEDED);

  if (!sim_data->program_loaded)
    return false;

  return true;
}

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

  add_target (gdbsim_target_info, gdbsim_target_open);

  c = add_com ("sim", class_obscure, simulator_command,
	       _("Send a command to the simulator."));
  set_cmd_completer (c, sim_command_completer);
}
