/* Memory-access and commands for "inferior" process, for GDB.

   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 "arch-utils.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "frame.h"
#include "inferior.h"
#include "infrun.h"
#include "gdbsupport/environ.h"
#include "value.h"
#include "gdbcmd.h"
#include "symfile.h"
#include "gdbcore.h"
#include "target.h"
#include "language.h"
#include "objfiles.h"
#include "completer.h"
#include "ui-out.h"
#include "regcache.h"
#include "reggroups.h"
#include "block.h"
#include "solib.h"
#include <ctype.h>
#include "observable.h"
#include "target-descriptions.h"
#include "user-regs.h"
#include "gdbthread.h"
#include "valprint.h"
#include "inline-frame.h"
#include "tracepoint.h"
#include "inf-loop.h"
#include "linespec.h"
#include "thread-fsm.h"
#include "top.h"
#include "interps.h"
#include "skip.h"
#include "gdbsupport/gdb_optional.h"
#include "source.h"
#include "cli/cli-style.h"
#include "dwarf2/loc.h"

/* Local functions: */

static void until_next_command (int);

static void step_1 (int, int, const char *);

#define ERROR_NO_INFERIOR \
   if (!target_has_execution ()) error (_("The program is not being run."));

/* Scratch area where string containing arguments to give to the
   program will be stored by 'set args'.  As soon as anything is
   stored, notice_args_set will move it into per-inferior storage.
   Arguments are separated by spaces.  Empty string (pointer to '\0')
   means no args.  */

static std::string inferior_args_scratch;

/* Scratch area where the new cwd will be stored by 'set cwd'.  */

static std::string inferior_cwd_scratch;

/* Scratch area where 'set inferior-tty' will store user-provided value.
   We'll immediate copy it into per-inferior storage.  */

static std::string inferior_io_terminal_scratch;

/* Pid of our debugged inferior, or 0 if no inferior now.
   Since various parts of infrun.c test this to see whether there is a program
   being debugged it should be nonzero (currently 3 is used) for remote
   debugging.  */

ptid_t inferior_ptid;

/* Nonzero if stopped due to completion of a stack dummy routine.  */

enum stop_stack_kind stop_stack_dummy;

/* Nonzero if stopped due to a random (unexpected) signal in inferior
   process.  */

int stopped_by_random_signal;


/* Whether "finish" should print the value.  */

static bool finish_print = true;



static void
set_inferior_tty_command (const char *args, int from_tty,
			  struct cmd_list_element *c)
{
  /* CLI has assigned the user-provided value to inferior_io_terminal_scratch.
     Now route it to current inferior.  */
  current_inferior ()->set_tty (inferior_io_terminal_scratch);
}

static void
show_inferior_tty_command (struct ui_file *file, int from_tty,
			   struct cmd_list_element *c, const char *value)
{
  /* Note that we ignore the passed-in value in favor of computing it
     directly.  */
  const std::string &inferior_tty = current_inferior ()->tty ();

  gdb_printf (file,
	      _("Terminal for future runs of program being debugged "
		"is \"%s\".\n"), inferior_tty.c_str ());
}

void
set_inferior_args_vector (int argc, char **argv)
{
  gdb::array_view<char * const> args (argv, argc);
  std::string n = construct_inferior_arguments (args);
  current_inferior ()->set_args (std::move (n));
}

/* Notice when `set args' is run.  */

static void
set_args_command (const char *args, int from_tty, struct cmd_list_element *c)
{
  /* CLI has assigned the user-provided value to inferior_args_scratch.
     Now route it to current inferior.  */
  current_inferior ()->set_args (inferior_args_scratch);
}

/* Notice when `show args' is run.  */

static void
show_args_command (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c, const char *value)
{
  /* Note that we ignore the passed-in value in favor of computing it
     directly.  */
  deprecated_show_value_hack (file, from_tty, c,
			      current_inferior ()->args ().c_str ());
}

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

const std::string &
get_inferior_cwd ()
{
  return current_inferior ()->cwd ();
}

/* Handle the 'set cwd' command.  */

static void
set_cwd_command (const char *args, int from_tty, struct cmd_list_element *c)
{
  current_inferior ()->set_cwd (inferior_cwd_scratch);
}

/* Handle the 'show cwd' command.  */

static void
show_cwd_command (struct ui_file *file, int from_tty,
		  struct cmd_list_element *c, const char *value)
{
  const std::string &cwd = current_inferior ()->cwd ();

  if (cwd.empty ())
    gdb_printf (file,
		_("\
You have not set the inferior's current working directory.\n\
The inferior will inherit GDB's cwd if native debugging, or the remote\n\
server's cwd if remote debugging.\n"));
  else
    gdb_printf (file,
		_("Current working directory that will be used "
		  "when starting the inferior is \"%s\".\n"),
		cwd.c_str ());
}


/* This function strips the '&' character (indicating background
   execution) that is added as *the last* of the arguments ARGS of a
   command.  A copy of the incoming ARGS without the '&' is returned,
   unless the resulting string after stripping is empty, in which case
   NULL is returned.  *BG_CHAR_P is an output boolean that indicates
   whether the '&' character was found.  */

static gdb::unique_xmalloc_ptr<char>
strip_bg_char (const char *args, int *bg_char_p)
{
  const char *p;

  if (args == nullptr || *args == '\0')
    {
      *bg_char_p = 0;
      return nullptr;
    }

  p = args + strlen (args);
  if (p[-1] == '&')
    {
      p--;
      while (p > args && isspace (p[-1]))
	p--;

      *bg_char_p = 1;
      if (p != args)
	return gdb::unique_xmalloc_ptr<char>
	  (savestring (args, p - args));
      else
	return gdb::unique_xmalloc_ptr<char> (nullptr);
    }

  *bg_char_p = 0;
  return make_unique_xstrdup (args);
}

/* Common actions to take after creating any sort of inferior, by any
   means (running, attaching, connecting, et cetera).  The target
   should be stopped.  */

void
post_create_inferior (int from_tty)
{

  /* Be sure we own the terminal in case write operations are performed.  */ 
  target_terminal::ours_for_output ();

  infrun_debug_show_threads ("threads in the newly created inferior",
			     current_inferior ()->non_exited_threads ());

  /* If the target hasn't taken care of this already, do it now.
     Targets which need to access registers during to_open,
     to_create_inferior, or to_attach should do it earlier; but many
     don't need to.  */
  target_find_description ();

  /* Now that we know the register layout, retrieve current PC.  But
     if the PC is unavailable (e.g., we're opening a core file with
     missing registers info), ignore it.  */
  thread_info *thr = inferior_thread ();

  thr->clear_stop_pc ();
  try
    {
      regcache *rc = get_thread_regcache (thr);
      thr->set_stop_pc (regcache_read_pc (rc));
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error != NOT_AVAILABLE_ERROR)
	throw;
    }

  if (current_program_space->exec_bfd ())
    {
      const unsigned solib_add_generation
	= current_program_space->solib_add_generation;

      scoped_restore restore_in_initial_library_scan
	= make_scoped_restore (&current_inferior ()->in_initial_library_scan,
			       true);

      /* Create the hooks to handle shared library load and unload
	 events.  */
      solib_create_inferior_hook (from_tty);

      if (current_program_space->solib_add_generation == solib_add_generation)
	{
	  /* The platform-specific hook should load initial shared libraries,
	     but didn't.  FROM_TTY will be incorrectly 0 but such solib
	     targets should be fixed anyway.  Call it only after the solib
	     target has been initialized by solib_create_inferior_hook.  */

	  if (info_verbose)
	    warning (_("platform-specific solib_create_inferior_hook did "
		       "not load initial shared libraries."));

	  /* If the solist is global across processes, there's no need to
	     refetch it here.  */
	  if (!gdbarch_has_global_solist (target_gdbarch ()))
	    solib_add (nullptr, 0, auto_solib_add);
	}
    }

  /* If the user sets watchpoints before execution having started,
     then she gets software watchpoints, because GDB can't know which
     target will end up being pushed, or if it supports hardware
     watchpoints or not.  breakpoint_re_set takes care of promoting
     watchpoints to hardware watchpoints if possible, however, if this
     new inferior doesn't load shared libraries or we don't pull in
     symbols from any other source on this target/arch,
     breakpoint_re_set is never called.  Call it now so that software
     watchpoints get a chance to be promoted to hardware watchpoints
     if the now pushed target supports hardware watchpoints.  */
  breakpoint_re_set ();

  gdb::observers::inferior_created.notify (current_inferior ());
}

/* Kill the inferior if already running.  This function is designed
   to be called when we are about to start the execution of the program
   from the beginning.  Ask the user to confirm that he wants to restart
   the program being debugged when FROM_TTY is non-null.  */

static void
kill_if_already_running (int from_tty)
{
  if (inferior_ptid != null_ptid && target_has_execution ())
    {
      /* Bail out before killing the program if we will not be able to
	 restart it.  */
      target_require_runnable ();

      if (from_tty
	  && !query (_("The program being debugged has been started already.\n\
Start it from the beginning? ")))
	error (_("Program not restarted."));
      target_kill ();
    }
}

/* See inferior.h.  */

void
prepare_execution_command (struct target_ops *target, int background)
{
  /* If we get a request for running in the bg but the target
     doesn't support it, error out.  */
  if (background && !target_can_async_p (target))
    error (_("Asynchronous execution not supported on this target."));

  if (!background)
    {
      /* If we get a request for running in the fg, then we need to
	 simulate synchronous (fg) execution.  Note no cleanup is
	 necessary for this.  stdin is re-enabled whenever an error
	 reaches the top level.  */
      all_uis_on_sync_execution_starting ();
    }
}

/* Determine how the new inferior will behave.  */

enum run_how
  {
    /* Run program without any explicit stop during startup.  */
    RUN_NORMAL,

    /* Stop at the beginning of the program's main function.  */
    RUN_STOP_AT_MAIN,

    /* Stop at the first instruction of the program.  */
    RUN_STOP_AT_FIRST_INSN
  };

/* Implement the "run" command.  Force a stop during program start if
   requested by RUN_HOW.  */

static void
run_command_1 (const char *args, int from_tty, enum run_how run_how)
{
  const char *exec_file;
  struct ui_out *uiout = current_uiout;
  struct target_ops *run_target;
  int async_exec;

  dont_repeat ();

  scoped_disable_commit_resumed disable_commit_resumed ("running");

  kill_if_already_running (from_tty);

  init_wait_for_inferior ();
  clear_breakpoint_hit_counts ();

  /* Clean up any leftovers from other runs.  Some other things from
     this function should probably be moved into target_pre_inferior.  */
  target_pre_inferior (from_tty);

  /* The comment here used to read, "The exec file is re-read every
     time we do a generic_mourn_inferior, so we just have to worry
     about the symbol file."  The `generic_mourn_inferior' function
     gets called whenever the program exits.  However, suppose the
     program exits, and *then* the executable file changes?  We need
     to check again here.  Since reopen_exec_file doesn't do anything
     if the timestamp hasn't changed, I don't see the harm.  */
  reopen_exec_file ();
  reread_symbols (from_tty);

  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
  args = stripped.get ();

  /* Do validation and preparation before possibly changing anything
     in the inferior.  */

  run_target = find_run_target ();

  prepare_execution_command (run_target, async_exec);

  if (non_stop && !run_target->supports_non_stop ())
    error (_("The target does not support running in non-stop mode."));

  /* Done.  Can now set breakpoints, change inferior args, etc.  */

  /* Insert temporary breakpoint in main function if requested.  */
  if (run_how == RUN_STOP_AT_MAIN)
    {
      /* To avoid other inferiors hitting this breakpoint, make it
	 inferior-specific using a condition.  A better solution would be to
	 have proper inferior-specific breakpoint support, in the breakpoint
	 machinery.  We could then avoid inserting a breakpoint in the program
	 spaces unrelated to this inferior.  */
      const char *op
	= ((current_language->la_language == language_ada
	    || current_language->la_language == language_pascal
	    || current_language->la_language == language_m2) ? "=" : "==");
      std::string arg = string_printf
	("-qualified %s if $_inferior %s %d", main_name (), op,
	 current_inferior ()->num);
      tbreak_command (arg.c_str (), 0);
    }

  exec_file = get_exec_file (0);

  /* We keep symbols from add-symbol-file, on the grounds that the
     user might want to add some symbols before running the program
     (right?).  But sometimes (dynamic loading where the user manually
     introduces the new symbols with add-symbol-file), the code which
     the symbols describe does not persist between runs.  Currently
     the user has to manually nuke all symbols between runs if they
     want them to go away (PR 2207).  This is probably reasonable.  */

  /* If there were other args, beside '&', process them.  */
  if (args != nullptr)
    current_inferior ()->set_args (args);

  if (from_tty)
    {
      uiout->field_string (nullptr, "Starting program");
      uiout->text (": ");
      if (exec_file)
	uiout->field_string ("execfile", exec_file,
			     file_name_style.style ());
      uiout->spaces (1);
      uiout->field_string ("infargs", current_inferior ()->args ());
      uiout->text ("\n");
      uiout->flush ();
    }

  run_target->create_inferior (exec_file,
			       current_inferior ()->args (),
			       current_inferior ()->environment.envp (),
			       from_tty);
  /* to_create_inferior should push the target, so after this point we
     shouldn't refer to run_target again.  */
  run_target = nullptr;

  infrun_debug_show_threads ("immediately after create_process",
			     current_inferior ()->non_exited_threads ());

  /* We're starting off a new process.  When we get out of here, in
     non-stop mode, finish the state of all threads of that process,
     but leave other threads alone, as they may be stopped in internal
     events --- the frontend shouldn't see them as stopped.  In
     all-stop, always finish the state of all threads, as we may be
     resuming more than just the new process.  */
  process_stratum_target *finish_target;
  ptid_t finish_ptid;
  if (non_stop)
    {
      finish_target = current_inferior ()->process_target ();
      finish_ptid = ptid_t (current_inferior ()->pid);
    }
  else
    {
      finish_target = nullptr;
      finish_ptid = minus_one_ptid;
    }
  scoped_finish_thread_state finish_state (finish_target, finish_ptid);

  /* Pass zero for FROM_TTY, because at this point the "run" command
     has done its thing; now we are setting up the running program.  */
  post_create_inferior (0);

  /* Queue a pending event so that the program stops immediately.  */
  if (run_how == RUN_STOP_AT_FIRST_INSN)
    {
      thread_info *thr = inferior_thread ();
      target_waitstatus ws;
      ws.set_stopped (GDB_SIGNAL_0);
      thr->set_pending_waitstatus (ws);
    }

  /* Start the target running.  Do not use -1 continuation as it would skip
     breakpoint right at the entry point.  */
  proceed (regcache_read_pc (get_current_regcache ()), GDB_SIGNAL_0);

  /* Since there was no error, there's no need to finish the thread
     states here.  */
  finish_state.release ();

  disable_commit_resumed.reset_and_commit ();
}

static void
run_command (const char *args, int from_tty)
{
  run_command_1 (args, from_tty, RUN_NORMAL);
}

/* Start the execution of the program up until the beginning of the main
   program.  */

static void
start_command (const char *args, int from_tty)
{
  /* Some languages such as Ada need to search inside the program
     minimal symbols for the location where to put the temporary
     breakpoint before starting.  */
  if (!have_minimal_symbols ())
    error (_("No symbol table loaded.  Use the \"file\" command."));

  /* Run the program until reaching the main procedure...  */
  run_command_1 (args, from_tty, RUN_STOP_AT_MAIN);
}

/* Start the execution of the program stopping at the first
   instruction.  */

static void
starti_command (const char *args, int from_tty)
{
  run_command_1 (args, from_tty, RUN_STOP_AT_FIRST_INSN);
} 

static int
proceed_thread_callback (struct thread_info *thread, void *arg)
{
  /* We go through all threads individually instead of compressing
     into a single target `resume_all' request, because some threads
     may be stopped in internal breakpoints/events, or stopped waiting
     for its turn in the displaced stepping queue (that is, they are
     running && !executing).  The target side has no idea about why
     the thread is stopped, so a `resume_all' command would resume too
     much.  If/when GDB gains a way to tell the target `hold this
     thread stopped until I say otherwise', then we can optimize
     this.  */
  if (thread->state != THREAD_STOPPED)
    return 0;

  if (!thread->inf->has_execution ())
    return 0;

  switch_to_thread (thread);
  clear_proceed_status (0);
  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
  return 0;
}

static void
ensure_valid_thread (void)
{
  if (inferior_ptid == null_ptid
      || inferior_thread ()->state == THREAD_EXITED)
    error (_("Cannot execute this command without a live selected thread."));
}

/* If the user is looking at trace frames, any resumption of execution
   is likely to mix up recorded and live target data.  So simply
   disallow those commands.  */

static void
ensure_not_tfind_mode (void)
{
  if (get_traceframe_number () >= 0)
    error (_("Cannot execute this command while looking at trace frames."));
}

/* Throw an error indicating the current thread is running.  */

static void
error_is_running (void)
{
  error (_("Cannot execute this command while "
	   "the selected thread is running."));
}

/* Calls error_is_running if the current thread is running.  */

static void
ensure_not_running (void)
{
  if (inferior_thread ()->state == THREAD_RUNNING)
    error_is_running ();
}

void
continue_1 (int all_threads)
{
  ERROR_NO_INFERIOR;
  ensure_not_tfind_mode ();

  if (non_stop && all_threads)
    {
      /* Don't error out if the current thread is running, because
	 there may be other stopped threads.  */

      /* Backup current thread and selected frame and restore on scope
	 exit.  */
      scoped_restore_current_thread restore_thread;
      scoped_disable_commit_resumed disable_commit_resumed
	("continue all threads in non-stop");

      iterate_over_threads (proceed_thread_callback, nullptr);

      if (current_ui->prompt_state == PROMPT_BLOCKED)
	{
	  /* If all threads in the target were already running,
	     proceed_thread_callback ends up never calling proceed,
	     and so nothing calls this to put the inferior's terminal
	     settings in effect and remove stdin from the event loop,
	     which we must when running a foreground command.  E.g.:

	      (gdb) c -a&
	      Continuing.
	      <all threads are running now>
	      (gdb) c -a
	      Continuing.
	      <no thread was resumed, but the inferior now owns the terminal>
	  */
	  target_terminal::inferior ();
	}

      disable_commit_resumed.reset_and_commit ();
    }
  else
    {
      ensure_valid_thread ();
      ensure_not_running ();
      clear_proceed_status (0);
      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
    }
}

/* continue [-a] [proceed-count] [&]  */

static void
continue_command (const char *args, int from_tty)
{
  int async_exec;
  bool all_threads_p = false;

  ERROR_NO_INFERIOR;

  /* Find out whether we must run in the background.  */
  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
  args = stripped.get ();

  if (args != nullptr)
    {
      if (startswith (args, "-a"))
	{
	  all_threads_p = true;
	  args += sizeof ("-a") - 1;
	  if (*args == '\0')
	    args = nullptr;
	}
    }

  if (!non_stop && all_threads_p)
    error (_("`-a' is meaningless in all-stop mode."));

  if (args != nullptr && all_threads_p)
    error (_("Can't resume all threads and specify "
	     "proceed count simultaneously."));

  /* If we have an argument left, set proceed count of breakpoint we
     stopped at.  */
  if (args != nullptr)
    {
      bpstat *bs = nullptr;
      int num, stat;
      int stopped = 0;
      struct thread_info *tp;

      if (non_stop)
	tp = inferior_thread ();
      else
	{
	  process_stratum_target *last_target;
	  ptid_t last_ptid;

	  get_last_target_status (&last_target, &last_ptid, nullptr);
	  tp = last_target->find_thread (last_ptid);
	}
      if (tp != nullptr)
	bs = tp->control.stop_bpstat;

      while ((stat = bpstat_num (&bs, &num)) != 0)
	if (stat > 0)
	  {
	    set_ignore_count (num,
			      parse_and_eval_long (args) - 1,
			      from_tty);
	    /* set_ignore_count prints a message ending with a period.
	       So print two spaces before "Continuing.".  */
	    if (from_tty)
	      gdb_printf ("  ");
	    stopped = 1;
	  }

      if (!stopped && from_tty)
	{
	  gdb_printf
	    ("Not stopped at any breakpoint; argument ignored.\n");
	}
    }

  ensure_not_tfind_mode ();

  if (!non_stop || !all_threads_p)
    {
      ensure_valid_thread ();
      ensure_not_running ();
    }

  prepare_execution_command (current_inferior ()->top_target (), async_exec);

  if (from_tty)
    gdb_printf (_("Continuing.\n"));

  continue_1 (all_threads_p);
}

/* Record in TP the starting point of a "step" or "next" command.  */

static void
set_step_frame (thread_info *tp)
{
  /* This can be removed once this function no longer implicitly relies on the
     inferior_ptid value.  */
  gdb_assert (inferior_ptid == tp->ptid);

  frame_info_ptr frame = get_current_frame ();

  symtab_and_line sal = find_frame_sal (frame);
  set_step_info (tp, frame, sal);

  CORE_ADDR pc = get_frame_pc (frame);
  tp->control.step_start_function = find_pc_function (pc);
}

/* Step until outside of current statement.  */

static void
step_command (const char *count_string, int from_tty)
{
  step_1 (0, 0, count_string);
}

/* Likewise, but skip over subroutine calls as if single instructions.  */

static void
next_command (const char *count_string, int from_tty)
{
  step_1 (1, 0, count_string);
}

/* Likewise, but step only one instruction.  */

static void
stepi_command (const char *count_string, int from_tty)
{
  step_1 (0, 1, count_string);
}

static void
nexti_command (const char *count_string, int from_tty)
{
  step_1 (1, 1, count_string);
}

/* Data for the FSM that manages the step/next/stepi/nexti
   commands.  */

struct step_command_fsm : public thread_fsm
{
  /* How many steps left in a "step N"-like command.  */
  int count;

  /* If true, this is a next/nexti, otherwise a step/stepi.  */
  int skip_subroutines;

  /* If true, this is a stepi/nexti, otherwise a step/step.  */
  int single_inst;

  explicit step_command_fsm (struct interp *cmd_interp)
    : thread_fsm (cmd_interp)
  {
  }

  void clean_up (struct thread_info *thread) override;
  bool should_stop (struct thread_info *thread) override;
  enum async_reply_reason do_async_reply_reason () override;
};

/* Prepare for a step/next/etc. command.  Any target resource
   allocated here is undone in the FSM's clean_up method.  */

static void
step_command_fsm_prepare (struct step_command_fsm *sm,
			  int skip_subroutines, int single_inst,
			  int count, struct thread_info *thread)
{
  sm->skip_subroutines = skip_subroutines;
  sm->single_inst = single_inst;
  sm->count = count;

  /* Leave the si command alone.  */
  if (!sm->single_inst || sm->skip_subroutines)
    set_longjmp_breakpoint (thread, get_frame_id (get_current_frame ()));

  thread->control.stepping_command = 1;
}

static int prepare_one_step (thread_info *, struct step_command_fsm *sm);

static void
step_1 (int skip_subroutines, int single_inst, const char *count_string)
{
  int count;
  int async_exec;
  struct thread_info *thr;
  struct step_command_fsm *step_sm;

  ERROR_NO_INFERIOR;
  ensure_not_tfind_mode ();
  ensure_valid_thread ();
  ensure_not_running ();

  gdb::unique_xmalloc_ptr<char> stripped
    = strip_bg_char (count_string, &async_exec);
  count_string = stripped.get ();

  prepare_execution_command (current_inferior ()->top_target (), async_exec);

  count = count_string ? parse_and_eval_long (count_string) : 1;

  clear_proceed_status (1);

  /* Setup the execution command state machine to handle all the COUNT
     steps.  */
  thr = inferior_thread ();
  step_sm = new step_command_fsm (command_interp ());
  thr->set_thread_fsm (std::unique_ptr<thread_fsm> (step_sm));

  step_command_fsm_prepare (step_sm, skip_subroutines,
			    single_inst, count, thr);

  /* Do only one step for now, before returning control to the event
     loop.  Let the continuation figure out how many other steps we
     need to do, and handle them one at the time, through
     step_once.  */
  if (!prepare_one_step (thr, step_sm))
    proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
  else
    {
      /* Stepped into an inline frame.  Pretend that we've
	 stopped.  */
      thr->thread_fsm ()->clean_up (thr);
      bool proceeded = normal_stop ();
      if (!proceeded)
	inferior_event_handler (INF_EXEC_COMPLETE);
      all_uis_check_sync_execution_done ();
    }
}

/* Implementation of the 'should_stop' FSM method for stepping
   commands.  Called after we are done with one step operation, to
   check whether we need to step again, before we print the prompt and
   return control to the user.  If count is > 1, returns false, as we
   will need to keep going.  */

bool
step_command_fsm::should_stop (struct thread_info *tp)
{
  if (tp->control.stop_step)
    {
      /* There are more steps to make, and we did stop due to
	 ending a stepping range.  Do another step.  */
      if (--count > 0)
	return prepare_one_step (tp, this);

      set_finished ();
    }

  return true;
}

/* Implementation of the 'clean_up' FSM method for stepping commands.  */

void
step_command_fsm::clean_up (struct thread_info *thread)
{
  if (!single_inst || skip_subroutines)
    delete_longjmp_breakpoint (thread->global_num);
}

/* Implementation of the 'async_reply_reason' FSM method for stepping
   commands.  */

enum async_reply_reason
step_command_fsm::do_async_reply_reason ()
{
  return EXEC_ASYNC_END_STEPPING_RANGE;
}

/* Prepare for one step in "step N".  The actual target resumption is
   done by the caller.  Return true if we're done and should thus
   report a stop to the user.  Returns false if the target needs to be
   resumed.  */

static int
prepare_one_step (thread_info *tp, struct step_command_fsm *sm)
{
  /* This can be removed once this function no longer implicitly relies on the
     inferior_ptid value.  */
  gdb_assert (inferior_ptid == tp->ptid);

  if (sm->count > 0)
    {
      frame_info_ptr frame = get_current_frame ();

      set_step_frame (tp);

      if (!sm->single_inst)
	{
	  CORE_ADDR pc;

	  /* Step at an inlined function behaves like "down".  */
	  if (!sm->skip_subroutines
	      && inline_skipped_frames (tp))
	    {
	      ptid_t resume_ptid;
	      const char *fn = nullptr;
	      symtab_and_line sal;
	      struct symbol *sym;

	      /* Pretend that we've ran.  */
	      resume_ptid = user_visible_resume_ptid (1);
	      set_running (tp->inf->process_target (), resume_ptid, true);

	      step_into_inline_frame (tp);

	      frame = get_current_frame ();
	      sal = find_frame_sal (frame);
	      sym = get_frame_function (frame);

	      if (sym != nullptr)
		fn = sym->print_name ();

	      if (sal.line == 0
		  || !function_name_is_marked_for_skip (fn, sal))
		{
		  sm->count--;
		  return prepare_one_step (tp, sm);
		}
	    }

	  pc = get_frame_pc (frame);
	  find_pc_line_pc_range (pc,
				 &tp->control.step_range_start,
				 &tp->control.step_range_end);

	  /* There's a problem in gcc (PR gcc/98780) that causes missing line
	     table entries, which results in a too large stepping range.
	     Use inlined_subroutine info to make the range more narrow.  */
	  if (inline_skipped_frames (tp) > 0)
	    {
	      symbol *sym = inline_skipped_symbol (tp);
	      if (sym->aclass () == LOC_BLOCK)
		{
		  const block *block = sym->value_block ();
		  if (block->end () < tp->control.step_range_end)
		    tp->control.step_range_end = block->end ();
		}
	    }

	  tp->control.may_range_step = 1;

	  /* If we have no line info, switch to stepi mode.  */
	  if (tp->control.step_range_end == 0 && step_stop_if_no_debug)
	    {
	      tp->control.step_range_start = tp->control.step_range_end = 1;
	      tp->control.may_range_step = 0;
	    }
	  else if (tp->control.step_range_end == 0)
	    {
	      const char *name;

	      if (find_pc_partial_function (pc, &name,
					    &tp->control.step_range_start,
					    &tp->control.step_range_end) == 0)
		error (_("Cannot find bounds of current function"));

	      target_terminal::ours_for_output ();
	      gdb_printf (_("Single stepping until exit from function %s,"
			    "\nwhich has no line number information.\n"),
			  name);
	    }
	}
      else
	{
	  /* Say we are stepping, but stop after one insn whatever it does.  */
	  tp->control.step_range_start = tp->control.step_range_end = 1;
	  if (!sm->skip_subroutines)
	    /* It is stepi.
	       Don't step over function calls, not even to functions lacking
	       line numbers.  */
	    tp->control.step_over_calls = STEP_OVER_NONE;
	}

      if (sm->skip_subroutines)
	tp->control.step_over_calls = STEP_OVER_ALL;

      return 0;
    }

  /* Done.  */
  sm->set_finished ();
  return 1;
}


/* Continue program at specified address.  */

static void
jump_command (const char *arg, int from_tty)
{
  struct gdbarch *gdbarch = get_current_arch ();
  CORE_ADDR addr;
  struct symbol *fn;
  struct symbol *sfn;
  int async_exec;

  ERROR_NO_INFERIOR;
  ensure_not_tfind_mode ();
  ensure_valid_thread ();
  ensure_not_running ();

  /* Find out whether we must run in the background.  */
  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
  arg = stripped.get ();

  prepare_execution_command (current_inferior ()->top_target (), async_exec);

  if (!arg)
    error_no_arg (_("starting address"));

  std::vector<symtab_and_line> sals
    = decode_line_with_last_displayed (arg, DECODE_LINE_FUNFIRSTLINE);
  if (sals.size () != 1)
    error (_("Unreasonable jump request"));

  symtab_and_line &sal = sals[0];

  if (sal.symtab == 0 && sal.pc == 0)
    error (_("No source file has been specified."));

  resolve_sal_pc (&sal);	/* May error out.  */

  /* See if we are trying to jump to another function.  */
  fn = get_frame_function (get_current_frame ());
  sfn = find_pc_function (sal.pc);
  if (fn != nullptr && sfn != fn)
    {
      if (!query (_("Line %d is not in `%s'.  Jump anyway? "), sal.line,
		  fn->print_name ()))
	{
	  error (_("Not confirmed."));
	  /* NOTREACHED */
	}
    }

  if (sfn != nullptr)
    {
      struct obj_section *section;

      section = sfn->obj_section (sfn->objfile ());
      if (section_is_overlay (section)
	  && !section_is_mapped (section))
	{
	  if (!query (_("WARNING!!!  Destination is in "
			"unmapped overlay!  Jump anyway? ")))
	    {
	      error (_("Not confirmed."));
	      /* NOTREACHED */
	    }
	}
    }

  addr = sal.pc;

  if (from_tty)
    {
      gdb_printf (_("Continuing at "));
      gdb_puts (paddress (gdbarch, addr));
      gdb_printf (".\n");
    }

  clear_proceed_status (0);
  proceed (addr, GDB_SIGNAL_0);
}

/* Continue program giving it specified signal.  */

static void
signal_command (const char *signum_exp, int from_tty)
{
  enum gdb_signal oursig;
  int async_exec;

  dont_repeat ();		/* Too dangerous.  */
  ERROR_NO_INFERIOR;
  ensure_not_tfind_mode ();
  ensure_valid_thread ();
  ensure_not_running ();

  /* Find out whether we must run in the background.  */
  gdb::unique_xmalloc_ptr<char> stripped
    = strip_bg_char (signum_exp, &async_exec);
  signum_exp = stripped.get ();

  prepare_execution_command (current_inferior ()->top_target (), async_exec);

  if (!signum_exp)
    error_no_arg (_("signal number"));

  /* It would be even slicker to make signal names be valid expressions,
     (the type could be "enum $signal" or some such), then the user could
     assign them to convenience variables.  */
  oursig = gdb_signal_from_name (signum_exp);

  if (oursig == GDB_SIGNAL_UNKNOWN)
    {
      /* No, try numeric.  */
      int num = parse_and_eval_long (signum_exp);

      if (num == 0)
	oursig = GDB_SIGNAL_0;
      else
	oursig = gdb_signal_from_command (num);
    }

  /* Look for threads other than the current that this command ends up
     resuming too (due to schedlock off), and warn if they'll get a
     signal delivered.  "signal 0" is used to suppress a previous
     signal, but if the current thread is no longer the one that got
     the signal, then the user is potentially suppressing the signal
     of the wrong thread.  */
  if (!non_stop)
    {
      int must_confirm = 0;

      /* This indicates what will be resumed.  Either a single thread,
	 a whole process, or all threads of all processes.  */
      ptid_t resume_ptid = user_visible_resume_ptid (0);
      process_stratum_target *resume_target
	= user_visible_resume_target (resume_ptid);

      thread_info *current = inferior_thread ();

      for (thread_info *tp : all_non_exited_threads (resume_target, resume_ptid))
	{
	  if (tp == current)
	    continue;

	  if (tp->stop_signal () != GDB_SIGNAL_0
	      && signal_pass_state (tp->stop_signal ()))
	    {
	      if (!must_confirm)
		gdb_printf (_("Note:\n"));
	      gdb_printf (_("  Thread %s previously stopped with signal %s, %s.\n"),
			  print_thread_id (tp),
			  gdb_signal_to_name (tp->stop_signal ()),
			  gdb_signal_to_string (tp->stop_signal ()));
	      must_confirm = 1;
	    }
	}

      if (must_confirm
	  && !query (_("Continuing thread %s (the current thread) with specified signal will\n"
		       "still deliver the signals noted above to their respective threads.\n"
		       "Continue anyway? "),
		     print_thread_id (inferior_thread ())))
	error (_("Not confirmed."));
    }

  if (from_tty)
    {
      if (oursig == GDB_SIGNAL_0)
	gdb_printf (_("Continuing with no signal.\n"));
      else
	gdb_printf (_("Continuing with signal %s.\n"),
		    gdb_signal_to_name (oursig));
    }

  clear_proceed_status (0);
  proceed ((CORE_ADDR) -1, oursig);
}

/* Queue a signal to be delivered to the current thread.  */

static void
queue_signal_command (const char *signum_exp, int from_tty)
{
  enum gdb_signal oursig;
  struct thread_info *tp;

  ERROR_NO_INFERIOR;
  ensure_not_tfind_mode ();
  ensure_valid_thread ();
  ensure_not_running ();

  if (signum_exp == nullptr)
    error_no_arg (_("signal number"));

  /* It would be even slicker to make signal names be valid expressions,
     (the type could be "enum $signal" or some such), then the user could
     assign them to convenience variables.  */
  oursig = gdb_signal_from_name (signum_exp);

  if (oursig == GDB_SIGNAL_UNKNOWN)
    {
      /* No, try numeric.  */
      int num = parse_and_eval_long (signum_exp);

      if (num == 0)
	oursig = GDB_SIGNAL_0;
      else
	oursig = gdb_signal_from_command (num);
    }

  if (oursig != GDB_SIGNAL_0
      && !signal_pass_state (oursig))
    error (_("Signal handling set to not pass this signal to the program."));

  tp = inferior_thread ();
  tp->set_stop_signal (oursig);
}

/* Data for the FSM that manages the until (with no argument)
   command.  */

struct until_next_fsm : public thread_fsm
{
  /* The thread that as current when the command was executed.  */
  int thread;

  until_next_fsm (struct interp *cmd_interp, int thread)
    : thread_fsm (cmd_interp),
      thread (thread)
  {
  }

  bool should_stop (struct thread_info *thread) override;
  void clean_up (struct thread_info *thread) override;
  enum async_reply_reason do_async_reply_reason () override;
};

/* Implementation of the 'should_stop' FSM method for the until (with
   no arg) command.  */

bool
until_next_fsm::should_stop (struct thread_info *tp)
{
  if (tp->control.stop_step)
    set_finished ();

  return true;
}

/* Implementation of the 'clean_up' FSM method for the until (with no
   arg) command.  */

void
until_next_fsm::clean_up (struct thread_info *thread)
{
  delete_longjmp_breakpoint (thread->global_num);
}

/* Implementation of the 'async_reply_reason' FSM method for the until
   (with no arg) command.  */

enum async_reply_reason
until_next_fsm::do_async_reply_reason ()
{
  return EXEC_ASYNC_END_STEPPING_RANGE;
}

/* Proceed until we reach a different source line with pc greater than
   our current one or exit the function.  We skip calls in both cases.

   Note that eventually this command should probably be changed so
   that only source lines are printed out when we hit the breakpoint
   we set.  This may involve changes to wait_for_inferior and the
   proceed status code.  */

static void
until_next_command (int from_tty)
{
  frame_info_ptr frame;
  CORE_ADDR pc;
  struct symbol *func;
  struct symtab_and_line sal;
  struct thread_info *tp = inferior_thread ();
  int thread = tp->global_num;
  struct until_next_fsm *sm;

  clear_proceed_status (0);
  set_step_frame (tp);

  frame = get_current_frame ();

  /* Step until either exited from this function or greater
     than the current line (if in symbolic section) or pc (if
     not).  */

  pc = get_frame_pc (frame);
  func = find_pc_function (pc);

  if (!func)
    {
      struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc);

      if (msymbol.minsym == nullptr)
	error (_("Execution is not within a known function."));

      tp->control.step_range_start = msymbol.value_address ();
      /* The upper-bound of step_range is exclusive.  In order to make PC
	 within the range, set the step_range_end with PC + 1.  */
      tp->control.step_range_end = pc + 1;
    }
  else
    {
      sal = find_pc_line (pc, 0);

      tp->control.step_range_start = func->value_block ()->entry_pc ();
      tp->control.step_range_end = sal.end;

      /* By setting the step_range_end based on the current pc, we are
	 assuming that the last line table entry for any given source line
	 will have is_stmt set to true.  This is not necessarily the case,
	 there may be additional entries for the same source line with
	 is_stmt set false.  Consider the following code:

	 for (int i = 0; i < 10; i++)
	   loop_body ();

	 Clang-13, will generate multiple line table entries at the end of
	 the loop all associated with the 'for' line.  The first of these
	 entries is marked is_stmt true, but the other entries are is_stmt
	 false.

	 If we only use the values in SAL, then our stepping range may not
	 extend to the end of the loop. The until command will reach the
	 end of the range, find a non is_stmt instruction, and step to the
	 next is_stmt instruction. This stopping point, however, will be
	 inside the loop, which is not what we wanted.

	 Instead, we now check any subsequent line table entries to see if
	 they are for the same line.  If they are, and they are marked
	 is_stmt false, then we extend the end of our stepping range.

	 When we finish this process the end of the stepping range will
	 point either to a line with a different line number, or, will
	 point at an address for the same line number that is marked as a
	 statement.  */

      struct symtab_and_line final_sal
	= find_pc_line (tp->control.step_range_end, 0);

      while (final_sal.line == sal.line && final_sal.symtab == sal.symtab
	     && !final_sal.is_stmt)
	{
	  tp->control.step_range_end = final_sal.end;
	  final_sal = find_pc_line (final_sal.end, 0);
	}
    }
  tp->control.may_range_step = 1;

  tp->control.step_over_calls = STEP_OVER_ALL;

  set_longjmp_breakpoint (tp, get_frame_id (frame));
  delete_longjmp_breakpoint_cleanup lj_deleter (thread);

  sm = new until_next_fsm (command_interp (), tp->global_num);
  tp->set_thread_fsm (std::unique_ptr<thread_fsm> (sm));
  lj_deleter.release ();

  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
}

static void
until_command (const char *arg, int from_tty)
{
  int async_exec;

  ERROR_NO_INFERIOR;
  ensure_not_tfind_mode ();
  ensure_valid_thread ();
  ensure_not_running ();

  /* Find out whether we must run in the background.  */
  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
  arg = stripped.get ();

  prepare_execution_command (current_inferior ()->top_target (), async_exec);

  if (arg)
    until_break_command (arg, from_tty, 0);
  else
    until_next_command (from_tty);
}

static void
advance_command (const char *arg, int from_tty)
{
  int async_exec;

  ERROR_NO_INFERIOR;
  ensure_not_tfind_mode ();
  ensure_valid_thread ();
  ensure_not_running ();

  if (arg == nullptr)
    error_no_arg (_("a location"));

  /* Find out whether we must run in the background.  */
  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
  arg = stripped.get ();

  prepare_execution_command (current_inferior ()->top_target (), async_exec);

  until_break_command (arg, from_tty, 1);
}

/* See inferior.h.  */

struct value *
get_return_value (struct symbol *func_symbol, struct value *function)
{
  regcache *stop_regs = get_current_regcache ();
  struct gdbarch *gdbarch = stop_regs->arch ();
  struct value *value;

  struct type *value_type
    = check_typedef (func_symbol->type ()->target_type ());
  gdb_assert (value_type->code () != TYPE_CODE_VOID);

  if (is_nocall_function (check_typedef (function->type ())))
    {
      warning (_("Function '%s' does not follow the target calling "
		 "convention, cannot determine its returned value."),
	       func_symbol->print_name ());

      return nullptr;
    }

  /* FIXME: 2003-09-27: When returning from a nested inferior function
     call, it's possible (with no help from the architecture vector)
     to locate and return/print a "struct return" value.  This is just
     a more complicated case of what is already being done in the
     inferior function call code.  In fact, when inferior function
     calls are made async, this will likely be made the norm.  */

  switch (gdbarch_return_value_as_value (gdbarch, function, value_type,
					 nullptr, nullptr, nullptr))
    {
    case RETURN_VALUE_REGISTER_CONVENTION:
    case RETURN_VALUE_ABI_RETURNS_ADDRESS:
    case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
      gdbarch_return_value_as_value (gdbarch, function, value_type, stop_regs,
				     &value, nullptr);
      break;
    case RETURN_VALUE_STRUCT_CONVENTION:
      value = nullptr;
      break;
    default:
      internal_error (_("bad switch"));
    }

  return value;
}

/* The captured function return value/type and its position in the
   value history.  */

struct return_value_info
{
  /* The captured return value.  May be NULL if we weren't able to
     retrieve it.  See get_return_value.  */
  struct value *value;

  /* The return type.  In some cases, we'll not be able extract the
     return value, but we always know the type.  */
  struct type *type;

  /* If we captured a value, this is the value history index.  */
  int value_history_index;
};

/* Helper for print_return_value.  */

static void
print_return_value_1 (struct ui_out *uiout, struct return_value_info *rv)
{
  if (rv->value != nullptr)
    {
      /* Print it.  */
      uiout->text ("Value returned is ");
      uiout->field_fmt ("gdb-result-var", "$%d",
			 rv->value_history_index);
      uiout->text (" = ");

      if (finish_print)
	{
	  struct value_print_options opts;
	  get_user_print_options (&opts);

	  string_file stb;
	  value_print (rv->value, &stb, &opts);
	  uiout->field_stream ("return-value", stb);
	}
      else
	uiout->field_string ("return-value", _("<not displayed>"),
			     metadata_style.style ());
      uiout->text ("\n");
    }
  else
    {
      std::string type_name = type_to_string (rv->type);
      uiout->text ("Value returned has type: ");
      uiout->field_string ("return-type", type_name);
      uiout->text (".");
      uiout->text (" Cannot determine contents\n");
    }
}

/* Print the result of a function at the end of a 'finish' command.
   RV points at an object representing the captured return value/type
   and its position in the value history.  */

void
print_return_value (struct ui_out *uiout, struct return_value_info *rv)
{
  if (rv->type == nullptr
      || check_typedef (rv->type)->code () == TYPE_CODE_VOID)
    return;

  try
    {
      /* print_return_value_1 can throw an exception in some
	 circumstances.  We need to catch this so that we still
	 delete the breakpoint.  */
      print_return_value_1 (uiout, rv);
    }
  catch (const gdb_exception_error &ex)
    {
      exception_print (gdb_stdout, ex);
    }
}

/* Data for the FSM that manages the finish command.  */

struct finish_command_fsm : public thread_fsm
{
  /* The momentary breakpoint set at the function's return address in
     the caller.  */
  breakpoint_up breakpoint;

  /* The function that we're stepping out of.  */
  struct symbol *function = nullptr;

  /* If the FSM finishes successfully, this stores the function's
     return value.  */
  struct return_value_info return_value_info {};

  /* If the current function uses the "struct return convention",
     this holds the address at which the value being returned will
     be stored, or zero if that address could not be determined or
     the "struct return convention" is not being used.  */
  CORE_ADDR return_buf;

  explicit finish_command_fsm (struct interp *cmd_interp)
    : thread_fsm (cmd_interp)
  {
  }

  bool should_stop (struct thread_info *thread) override;
  void clean_up (struct thread_info *thread) override;
  struct return_value_info *return_value () override;
  enum async_reply_reason do_async_reply_reason () override;
};

/* Implementation of the 'should_stop' FSM method for the finish
   commands.  Detects whether the thread stepped out of the function
   successfully, and if so, captures the function's return value and
   marks the FSM finished.  */

bool
finish_command_fsm::should_stop (struct thread_info *tp)
{
  struct return_value_info *rv = &return_value_info;

  if (function != nullptr
      && bpstat_find_breakpoint (tp->control.stop_bpstat,
				 breakpoint.get ()) != nullptr)
    {
      /* We're done.  */
      set_finished ();

      rv->type = function->type ()->target_type ();
      if (rv->type == nullptr)
	internal_error (_("finish_command: function has no target type"));

      if (check_typedef (rv->type)->code () != TYPE_CODE_VOID)
	{
	  struct value *func;

	  func = read_var_value (function, nullptr, get_current_frame ());

	  if (return_buf != 0)
	    /* Retrieve return value from the buffer where it was saved.  */
	      rv->value = value_at (rv->type, return_buf);
	  else
	      rv->value = get_return_value (function, func);

	  if (rv->value != nullptr)
	    rv->value_history_index = rv->value->record_latest ();
	}
    }
  else if (tp->control.stop_step)
    {
      /* Finishing from an inline frame, or reverse finishing.  In
	 either case, there's no way to retrieve the return value.  */
      set_finished ();
    }

  return true;
}

/* Implementation of the 'clean_up' FSM method for the finish
   commands.  */

void
finish_command_fsm::clean_up (struct thread_info *thread)
{
  breakpoint.reset ();
  delete_longjmp_breakpoint (thread->global_num);
}

/* Implementation of the 'return_value' FSM method for the finish
   commands.  */

struct return_value_info *
finish_command_fsm::return_value ()
{
  return &return_value_info;
}

/* Implementation of the 'async_reply_reason' FSM method for the
   finish commands.  */

enum async_reply_reason
finish_command_fsm::do_async_reply_reason ()
{
  if (execution_direction == EXEC_REVERSE)
    return EXEC_ASYNC_END_STEPPING_RANGE;
  else
    return EXEC_ASYNC_FUNCTION_FINISHED;
}

/* finish_backward -- helper function for finish_command.  */

static void
finish_backward (struct finish_command_fsm *sm)
{
  struct symtab_and_line sal;
  struct thread_info *tp = inferior_thread ();
  CORE_ADDR pc;
  CORE_ADDR func_addr;
  CORE_ADDR alt_entry_point;
  CORE_ADDR entry_point;
  frame_info_ptr frame = get_selected_frame (nullptr);
  struct gdbarch *gdbarch = get_frame_arch (frame);

  pc = get_frame_pc (get_current_frame ());

  if (find_pc_partial_function (pc, nullptr, &func_addr, nullptr) == 0)
    error (_("Cannot find bounds of current function"));

  sal = find_pc_line (func_addr, 0);
  alt_entry_point = sal.pc;
  entry_point = alt_entry_point;

  if (gdbarch_skip_entrypoint_p (gdbarch))
    /* Some architectures, like PowerPC use local and global entry points.
       There is only one Entry Point (GEP = LEP) for other architectures.
       The GEP is an alternate entry point.  The LEP is the normal entry point.
       The value of entry_point was initialized to the alternate entry point
       (GEP).  It will be adjusted to the normal entry point if the function
       has two entry points.  */
    entry_point = gdbarch_skip_entrypoint (gdbarch, sal.pc);

  tp->control.proceed_to_finish = 1;
  /* Special case: if we're sitting at the function entry point,
     then all we need to do is take a reverse singlestep.  We
     don't need to set a breakpoint, and indeed it would do us
     no good to do so.

     Note that this can only happen at frame #0, since there's
     no way that a function up the stack can have a return address
     that's equal to its entry point.  */

  if ((pc < alt_entry_point) || (pc > entry_point))
    {
      /* We are in the body of the function.  Set a breakpoint to go back to
	 the normal entry point.  */
      symtab_and_line sr_sal;
      sr_sal.pc = entry_point;
      sr_sal.pspace = get_frame_program_space (frame);
      insert_step_resume_breakpoint_at_sal (gdbarch,
					    sr_sal, null_frame_id);

      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
    }
  else
    {
      /* We are either at one of the entry points or between the entry points.
	 If we are not at the alt_entry point, go back to the alt_entry_point
	 If we at the normal entry point step back one instruction, when we
	 stop we will determine if we entered via the entry point or the
	 alternate entry point.  If we are at the alternate entry point,
	 single step back to the function call.  */
      tp->control.step_range_start = tp->control.step_range_end = 1;
      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
    }
}

/* finish_forward -- helper function for finish_command.  FRAME is the
   frame that called the function we're about to step out of.  */

static void
finish_forward (struct finish_command_fsm *sm, frame_info_ptr frame)
{
  struct frame_id frame_id = get_frame_id (frame);
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct symtab_and_line sal;
  struct thread_info *tp = inferior_thread ();

  sal = find_pc_line (get_frame_pc (frame), 0);
  sal.pc = get_frame_pc (frame);

  sm->breakpoint = set_momentary_breakpoint (gdbarch, sal,
					     get_stack_frame_id (frame),
					     bp_finish);

  /* set_momentary_breakpoint invalidates FRAME.  */
  frame = nullptr;

  set_longjmp_breakpoint (tp, frame_id);

  /* We want to print return value, please...  */
  tp->control.proceed_to_finish = 1;

  proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
}

/* Skip frames for "finish".  */

static frame_info_ptr
skip_finish_frames (frame_info_ptr frame)
{
  frame_info_ptr start;

  do
    {
      start = frame;

      frame = skip_tailcall_frames (frame);
      if (frame == nullptr)
	break;

      frame = skip_unwritable_frames (frame);
      if (frame == nullptr)
	break;
    }
  while (start != frame);

  return frame;
}

/* "finish": Set a temporary breakpoint at the place the selected
   frame will return to, then continue.  */

static void
finish_command (const char *arg, int from_tty)
{
  frame_info_ptr frame;
  int async_exec;
  struct finish_command_fsm *sm;
  struct thread_info *tp;

  ERROR_NO_INFERIOR;
  ensure_not_tfind_mode ();
  ensure_valid_thread ();
  ensure_not_running ();

  /* Find out whether we must run in the background.  */
  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
  arg = stripped.get ();

  prepare_execution_command (current_inferior ()->top_target (), async_exec);

  if (arg)
    error (_("The \"finish\" command does not take any arguments."));

  frame = get_prev_frame (get_selected_frame (_("No selected frame.")));
  if (frame == 0)
    error (_("\"finish\" not meaningful in the outermost frame."));

  clear_proceed_status (0);

  tp = inferior_thread ();

  sm = new finish_command_fsm (command_interp ());

  tp->set_thread_fsm (std::unique_ptr<thread_fsm> (sm));

  /* Finishing from an inline frame is completely different.  We don't
     try to show the "return value" - no way to locate it.  */
  if (get_frame_type (get_selected_frame (_("No selected frame.")))
      == INLINE_FRAME)
    {
      /* Claim we are stepping in the calling frame.  An empty step
	 range means that we will stop once we aren't in a function
	 called by that frame.  We don't use the magic "1" value for
	 step_range_end, because then infrun will think this is nexti,
	 and not step over the rest of this inlined function call.  */
      set_step_info (tp, frame, {});
      tp->control.step_range_start = get_frame_pc (frame);
      tp->control.step_range_end = tp->control.step_range_start;
      tp->control.step_over_calls = STEP_OVER_ALL;

      /* Print info on the selected frame, including level number but not
	 source.  */
      if (from_tty)
	{
	  gdb_printf (_("Run till exit from "));
	  print_stack_frame (get_selected_frame (nullptr), 1, LOCATION, 0);
	}

      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
      return;
    }

  /* Find the function we will return from.  */
  frame_info_ptr callee_frame = get_selected_frame (nullptr);
  sm->function = find_pc_function (get_frame_pc (callee_frame));
  sm->return_buf = 0;    /* Initialize buffer address is not available.  */

  /* Determine the return convention.  If it is RETURN_VALUE_STRUCT_CONVENTION,
     attempt to determine the address of the return buffer.  */
  if (sm->function != nullptr)
    {
      enum return_value_convention return_value;
      struct gdbarch *gdbarch = get_frame_arch (callee_frame);

      struct type * val_type
	= check_typedef (sm->function->type ()->target_type ());

      return_value
	= gdbarch_return_value_as_value (gdbarch,
					 read_var_value (sm->function, nullptr,
							 callee_frame),
					 val_type, nullptr, nullptr, nullptr);

      if (return_value == RETURN_VALUE_STRUCT_CONVENTION
	  && val_type->code () != TYPE_CODE_VOID)
	sm->return_buf = gdbarch_get_return_buf_addr (gdbarch, val_type,
						      callee_frame);
    }

  /* Print info on the selected frame, including level number but not
     source.  */
  if (from_tty)
    {
      if (execution_direction == EXEC_REVERSE)
	gdb_printf (_("Run back to call of "));
      else
	{
	  if (sm->function != nullptr && TYPE_NO_RETURN (sm->function->type ())
	      && !query (_("warning: Function %s does not return normally.\n"
			   "Try to finish anyway? "),
			 sm->function->print_name ()))
	    error (_("Not confirmed."));
	  gdb_printf (_("Run till exit from "));
	}

      print_stack_frame (callee_frame, 1, LOCATION, 0);
    }

  if (execution_direction == EXEC_REVERSE)
    finish_backward (sm);
  else
    {
      frame = skip_finish_frames (frame);

      if (frame == nullptr)
	error (_("Cannot find the caller frame."));

      finish_forward (sm, frame);
    }
}


static void
info_program_command (const char *args, int from_tty)
{
  scoped_restore_current_thread restore_thread;

  thread_info *tp;

  /* In non-stop, since every thread is controlled individually, we'll
     show execution info about the current thread.  In all-stop, we'll
     show execution info about the last stop.  */

  if (non_stop)
    {
      if (!target_has_execution ())
	{
	  gdb_printf (_("The program being debugged is not being run.\n"));
	  return;
	}

      if (inferior_ptid == null_ptid)
	error (_("No selected thread."));

      tp = inferior_thread ();

      gdb_printf (_("Selected thread %s (%s).\n"),
		  print_thread_id (tp),
		  target_pid_to_str (tp->ptid).c_str ());

      if (tp->state == THREAD_EXITED)
	{
	  gdb_printf (_("Selected thread has exited.\n"));
	  return;
	}
      else if (tp->state == THREAD_RUNNING)
	{
	  gdb_printf (_("Selected thread is running.\n"));
	  return;
	}
    }
  else
    {
      tp = get_previous_thread ();

      if (tp == nullptr)
	{
	  gdb_printf (_("The program being debugged is not being run.\n"));
	  return;
	}

      switch_to_thread (tp);

      gdb_printf (_("Last stopped for thread %s (%s).\n"),
		  print_thread_id (tp),
		  target_pid_to_str (tp->ptid).c_str ());

      if (tp->state == THREAD_EXITED)
	{
	  gdb_printf (_("Thread has since exited.\n"));
	  return;
	}

      if (tp->state == THREAD_RUNNING)
	{
	  gdb_printf (_("Thread is now running.\n"));
	  return;
	}
    }

  int num;
  bpstat *bs = tp->control.stop_bpstat;
  int stat = bpstat_num (&bs, &num);

  target_files_info ();
  gdb_printf (_("Program stopped at %s.\n"),
	      paddress (target_gdbarch (), tp->stop_pc ()));
  if (tp->control.stop_step)
    gdb_printf (_("It stopped after being stepped.\n"));
  else if (stat != 0)
    {
      /* There may be several breakpoints in the same place, so this
	 isn't as strange as it seems.  */
      while (stat != 0)
	{
	  if (stat < 0)
	    {
	      gdb_printf (_("It stopped at a breakpoint "
			    "that has since been deleted.\n"));
	    }
	  else
	    gdb_printf (_("It stopped at breakpoint %d.\n"), num);
	  stat = bpstat_num (&bs, &num);
	}
    }
  else if (tp->stop_signal () != GDB_SIGNAL_0)
    {
      gdb_printf (_("It stopped with signal %s, %s.\n"),
		  gdb_signal_to_name (tp->stop_signal ()),
		  gdb_signal_to_string (tp->stop_signal ()));
    }

  if (from_tty)
    {
      gdb_printf (_("Type \"info stack\" or \"info "
		    "registers\" for more information.\n"));
    }
}

static void
environment_info (const char *var, int from_tty)
{
  if (var)
    {
      const char *val = current_inferior ()->environment.get (var);

      if (val)
	{
	  gdb_puts (var);
	  gdb_puts (" = ");
	  gdb_puts (val);
	  gdb_puts ("\n");
	}
      else
	{
	  gdb_puts ("Environment variable \"");
	  gdb_puts (var);
	  gdb_puts ("\" not defined.\n");
	}
    }
  else
    {
      char **envp = current_inferior ()->environment.envp ();

      for (int idx = 0; envp[idx] != nullptr; ++idx)
	{
	  gdb_puts (envp[idx]);
	  gdb_puts ("\n");
	}
    }
}

static void
set_environment_command (const char *arg, int from_tty)
{
  const char *p, *val;
  int nullset = 0;

  if (arg == 0)
    error_no_arg (_("environment variable and value"));

  /* Find separation between variable name and value.  */
  p = (char *) strchr (arg, '=');
  val = (char *) strchr (arg, ' ');

  if (p != 0 && val != 0)
    {
      /* We have both a space and an equals.  If the space is before the
	 equals, walk forward over the spaces til we see a nonspace 
	 (possibly the equals).  */
      if (p > val)
	while (*val == ' ')
	  val++;

      /* Now if the = is after the char following the spaces,
	 take the char following the spaces.  */
      if (p > val)
	p = val - 1;
    }
  else if (val != 0 && p == 0)
    p = val;

  if (p == arg)
    error_no_arg (_("environment variable to set"));

  if (p == 0 || p[1] == 0)
    {
      nullset = 1;
      if (p == 0)
	p = arg + strlen (arg);	/* So that savestring below will work.  */
    }
  else
    {
      /* Not setting variable value to null.  */
      val = p + 1;
      while (*val == ' ' || *val == '\t')
	val++;
    }

  while (p != arg && (p[-1] == ' ' || p[-1] == '\t'))
    p--;

  std::string var (arg, p - arg);
  if (nullset)
    {
      gdb_printf (_("Setting environment variable "
		    "\"%s\" to null value.\n"),
		  var.c_str ());
      current_inferior ()->environment.set (var.c_str (), "");
    }
  else
    current_inferior ()->environment.set (var.c_str (), val);
}

static void
unset_environment_command (const char *var, int from_tty)
{
  if (var == 0)
    {
      /* If there is no argument, delete all environment variables.
	 Ask for confirmation if reading from the terminal.  */
      if (!from_tty || query (_("Delete all environment variables? ")))
	current_inferior ()->environment.clear ();
    }
  else
    current_inferior ()->environment.unset (var);
}

/* Handle the execution path (PATH variable).  */

static const char path_var_name[] = "PATH";

static void
path_info (const char *args, int from_tty)
{
  gdb_puts ("Executable and object file path: ");
  gdb_puts (current_inferior ()->environment.get (path_var_name));
  gdb_puts ("\n");
}

/* Add zero or more directories to the front of the execution path.  */

static void
path_command (const char *dirname, int from_tty)
{
  const char *env;

  dont_repeat ();
  env = current_inferior ()->environment.get (path_var_name);
  /* Can be null if path is not set.  */
  if (!env)
    env = "";
  std::string exec_path = env;
  mod_path (dirname, exec_path);
  current_inferior ()->environment.set (path_var_name, exec_path.c_str ());
  if (from_tty)
    path_info (nullptr, from_tty);
}


static void
pad_to_column (string_file &stream, int col)
{
  /* At least one space must be printed to separate columns.  */
  stream.putc (' ');
  const int size = stream.size ();
  if (size < col)
    stream.puts (n_spaces (col - size));
}

/* Print out the register NAME with value VAL, to FILE, in the default
   fashion.  */

static void
default_print_one_register_info (struct ui_file *file,
				 const char *name,
				 struct value *val)
{
  struct type *regtype = val->type ();
  int print_raw_format;
  string_file format_stream;
  enum tab_stops
    {
      value_column_1 = 15,
      /* Give enough room for "0x", 16 hex digits and two spaces in
	 preceding column.  */
      value_column_2 = value_column_1 + 2 + 16 + 2,
    };

  format_stream.puts (name);
  pad_to_column (format_stream, value_column_1);

  print_raw_format = (val->entirely_available ()
		      && !val->optimized_out ());

  /* If virtual format is floating, print it that way, and in raw
     hex.  */
  if (regtype->code () == TYPE_CODE_FLT
      || regtype->code () == TYPE_CODE_DECFLOAT)
    {
      struct value_print_options opts;
      const gdb_byte *valaddr = val->contents_for_printing ().data ();
      enum bfd_endian byte_order = type_byte_order (regtype);

      get_user_print_options (&opts);
      opts.deref_ref = true;

      common_val_print (val, &format_stream, 0, &opts, current_language);

      if (print_raw_format)
	{
	  pad_to_column (format_stream, value_column_2);
	  format_stream.puts ("(raw ");
	  print_hex_chars (&format_stream, valaddr, regtype->length (),
			   byte_order, true);
	  format_stream.putc (')');
	}
    }
  else
    {
      struct value_print_options opts;

      /* Print the register in hex.  */
      get_formatted_print_options (&opts, 'x');
      opts.deref_ref = true;
      common_val_print (val, &format_stream, 0, &opts, current_language);
      /* If not a vector register, print it also according to its
	 natural format.  */
      if (print_raw_format && regtype->is_vector () == 0)
	{
	  pad_to_column (format_stream, value_column_2);
	  get_user_print_options (&opts);
	  opts.deref_ref = true;
	  common_val_print (val, &format_stream, 0, &opts, current_language);
	}
    }

  gdb_puts (format_stream.c_str (), file);
  gdb_printf (file, "\n");
}

/* Print out the machine register regnum.  If regnum is -1, print all
   registers (print_all == 1) or all non-float and non-vector
   registers (print_all == 0).

   For most machines, having all_registers_info() print the
   register(s) one per line is good enough.  If a different format is
   required, (eg, for MIPS or Pyramid 90x, which both have lots of
   regs), or there is an existing convention for showing all the
   registers, define the architecture method PRINT_REGISTERS_INFO to
   provide that format.  */

void
default_print_registers_info (struct gdbarch *gdbarch,
			      struct ui_file *file,
			      frame_info_ptr frame,
			      int regnum, int print_all)
{
  int i;
  const int numregs = gdbarch_num_cooked_regs (gdbarch);

  for (i = 0; i < numregs; i++)
    {
      /* Decide between printing all regs, non-float / vector regs, or
	 specific reg.  */
      if (regnum == -1)
	{
	  if (print_all)
	    {
	      if (!gdbarch_register_reggroup_p (gdbarch, i, all_reggroup))
		continue;
	    }
	  else
	    {
	      if (!gdbarch_register_reggroup_p (gdbarch, i, general_reggroup))
		continue;
	    }
	}
      else
	{
	  if (i != regnum)
	    continue;
	}

      /* If the register name is empty, it is undefined for this
	 processor, so don't display anything.  */
      if (*(gdbarch_register_name (gdbarch, i)) == '\0')
	continue;

      default_print_one_register_info (file,
				       gdbarch_register_name (gdbarch, i),
				       value_of_register (i, frame));
    }
}

void
registers_info (const char *addr_exp, int fpregs)
{
  frame_info_ptr frame;
  struct gdbarch *gdbarch;

  if (!target_has_registers ())
    error (_("The program has no registers now."));
  frame = get_selected_frame (nullptr);
  gdbarch = get_frame_arch (frame);

  if (!addr_exp)
    {
      gdbarch_print_registers_info (gdbarch, gdb_stdout,
				    frame, -1, fpregs);
      return;
    }

  while (*addr_exp != '\0')
    {
      const char *start;
      const char *end;

      /* Skip leading white space.  */
      addr_exp = skip_spaces (addr_exp);

      /* Discard any leading ``$''.  Check that there is something
	 resembling a register following it.  */
      if (addr_exp[0] == '$')
	addr_exp++;
      if (isspace ((*addr_exp)) || (*addr_exp) == '\0')
	error (_("Missing register name"));

      /* Find the start/end of this register name/num/group.  */
      start = addr_exp;
      while ((*addr_exp) != '\0' && !isspace ((*addr_exp)))
	addr_exp++;
      end = addr_exp;

      /* Figure out what we've found and display it.  */

      /* A register name?  */
      {
	int regnum = user_reg_map_name_to_regnum (gdbarch, start, end - start);

	if (regnum >= 0)
	  {
	    /* User registers lie completely outside of the range of
	       normal registers.  Catch them early so that the target
	       never sees them.  */
	    if (regnum >= gdbarch_num_cooked_regs (gdbarch))
	      {
		struct value *regval = value_of_user_reg (regnum, frame);
		const char *regname = user_reg_map_regnum_to_name (gdbarch,
								   regnum);

		/* Print in the same fashion
		   gdbarch_print_registers_info's default
		   implementation prints.  */
		default_print_one_register_info (gdb_stdout,
						 regname,
						 regval);
	      }
	    else
	      gdbarch_print_registers_info (gdbarch, gdb_stdout,
					    frame, regnum, fpregs);
	    continue;
	  }
      }

      /* A register group?  */
      {
	const struct reggroup *group = nullptr;
	for (const struct reggroup *g : gdbarch_reggroups (gdbarch))
	  {
	    /* Don't bother with a length check.  Should the user
	       enter a short register group name, go with the first
	       group that matches.  */
	    if (strncmp (start, g->name (), end - start) == 0)
	      {
		group = g;
		break;
	      }
	  }
	if (group != nullptr)
	  {
	    int regnum;

	    for (regnum = 0;
		 regnum < gdbarch_num_cooked_regs (gdbarch);
		 regnum++)
	      {
		if (gdbarch_register_reggroup_p (gdbarch, regnum, group))
		  gdbarch_print_registers_info (gdbarch,
						gdb_stdout, frame,
						regnum, fpregs);
	      }
	    continue;
	  }
      }

      /* Nothing matched.  */
      error (_("Invalid register `%.*s'"), (int) (end - start), start);
    }
}

static void
info_all_registers_command (const char *addr_exp, int from_tty)
{
  registers_info (addr_exp, 1);
}

static void
info_registers_command (const char *addr_exp, int from_tty)
{
  registers_info (addr_exp, 0);
}

static void
print_vector_info (struct ui_file *file,
		   frame_info_ptr frame, const char *args)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);

  if (gdbarch_print_vector_info_p (gdbarch))
    gdbarch_print_vector_info (gdbarch, file, frame, args);
  else
    {
      int regnum;
      int printed_something = 0;

      for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
	{
	  if (gdbarch_register_reggroup_p (gdbarch, regnum, vector_reggroup))
	    {
	      printed_something = 1;
	      gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1);
	    }
	}
      if (!printed_something)
	gdb_printf (file, "No vector information\n");
    }
}

static void
info_vector_command (const char *args, int from_tty)
{
  if (!target_has_registers ())
    error (_("The program has no registers now."));

  print_vector_info (gdb_stdout, get_selected_frame (nullptr), args);
}

/* Kill the inferior process.  Make us have no inferior.  */

static void
kill_command (const char *arg, int from_tty)
{
  /* FIXME:  This should not really be inferior_ptid (or target_has_execution).
     It should be a distinct flag that indicates that a target is active, cuz
     some targets don't have processes!  */

  if (inferior_ptid == null_ptid)
    error (_("The program is not being run."));
  if (!query (_("Kill the program being debugged? ")))
    error (_("Not confirmed."));

  int pid = current_inferior ()->pid;
  /* Save the pid as a string before killing the inferior, since that
     may unpush the current target, and we need the string after.  */
  std::string pid_str = target_pid_to_str (ptid_t (pid));
  int infnum = current_inferior ()->num;

  target_kill ();
  bfd_cache_close_all ();

  update_previous_thread ();

  if (print_inferior_events)
    gdb_printf (_("[Inferior %d (%s) killed]\n"),
		infnum, pid_str.c_str ());
}

/* Used in `attach&' command.  Proceed threads of inferior INF iff
   they stopped due to debugger request, and when they did, they
   reported a clean stop (GDB_SIGNAL_0).  Do not proceed threads that
   have been explicitly been told to stop.  */

static void
proceed_after_attach (inferior *inf)
{
  /* Don't error out if the current thread is running, because
     there may be other stopped threads.  */

  /* Backup current thread and selected frame.  */
  scoped_restore_current_thread restore_thread;

  for (thread_info *thread : inf->non_exited_threads ())
    if (!thread->executing ()
	&& !thread->stop_requested
	&& thread->stop_signal () == GDB_SIGNAL_0)
      {
	switch_to_thread (thread);
	clear_proceed_status (0);
	proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
      }
}

/* See inferior.h.  */

void
setup_inferior (int from_tty)
{
  struct inferior *inferior;

  inferior = current_inferior ();
  inferior->needs_setup = false;

  /* If no exec file is yet known, try to determine it from the
     process itself.  */
  if (get_exec_file (0) == nullptr)
    exec_file_locate_attach (inferior_ptid.pid (), 1, from_tty);
  else
    {
      reopen_exec_file ();
      reread_symbols (from_tty);
    }

  /* Take any necessary post-attaching actions for this platform.  */
  target_post_attach (inferior_ptid.pid ());

  post_create_inferior (from_tty);
}

/* What to do after the first program stops after attaching.  */
enum attach_post_wait_mode
{
  /* Do nothing.  Leaves threads as they are.  */
  ATTACH_POST_WAIT_NOTHING,

  /* Re-resume threads that are marked running.  */
  ATTACH_POST_WAIT_RESUME,

  /* Stop all threads.  */
  ATTACH_POST_WAIT_STOP,
};

/* Called after we've attached to a process and we've seen it stop for
   the first time.  Resume, stop, or don't touch the threads according
   to MODE.  */

static void
attach_post_wait (int from_tty, enum attach_post_wait_mode mode)
{
  struct inferior *inferior;

  inferior = current_inferior ();
  inferior->control.stop_soon = NO_STOP_QUIETLY;

  if (inferior->needs_setup)
    setup_inferior (from_tty);

  if (mode == ATTACH_POST_WAIT_RESUME)
    {
      /* The user requested an `attach&', so be sure to leave threads
	 that didn't get a signal running.  */

      /* Immediately resume all suspended threads of this inferior,
	 and this inferior only.  This should have no effect on
	 already running threads.  If a thread has been stopped with a
	 signal, leave it be.  */
      if (non_stop)
	proceed_after_attach (inferior);
      else
	{
	  if (inferior_thread ()->stop_signal () == GDB_SIGNAL_0)
	    {
	      clear_proceed_status (0);
	      proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
	    }
	}
    }
  else if (mode == ATTACH_POST_WAIT_STOP)
    {
      /* The user requested a plain `attach', so be sure to leave
	 the inferior stopped.  */

      /* At least the current thread is already stopped.  */

      /* In all-stop, by definition, all threads have to be already
	 stopped at this point.  In non-stop, however, although the
	 selected thread is stopped, others may still be executing.
	 Be sure to explicitly stop all threads of the process.  This
	 should have no effect on already stopped threads.  */
      if (non_stop)
	target_stop (ptid_t (inferior->pid));
      else if (target_is_non_stop_p ())
	{
	  struct thread_info *lowest = inferior_thread ();

	  stop_all_threads ("attaching");

	  /* It's not defined which thread will report the attach
	     stop.  For consistency, always select the thread with
	     lowest GDB number, which should be the main thread, if it
	     still exists.  */
	  for (thread_info *thread : current_inferior ()->non_exited_threads ())
	    if (thread->inf->num < lowest->inf->num
		|| thread->per_inf_num < lowest->per_inf_num)
	      lowest = thread;

	  switch_to_thread (lowest);
	}

      /* Tell the user/frontend where we're stopped.  */
      normal_stop ();
      if (deprecated_attach_hook)
	deprecated_attach_hook ();
    }
}

/* "attach" command entry point.  Takes a program started up outside
   of gdb and ``attaches'' to it.  This stops it cold in its tracks
   and allows us to start debugging it.  */

void
attach_command (const char *args, int from_tty)
{
  int async_exec;
  struct target_ops *attach_target;
  struct inferior *inferior = current_inferior ();
  enum attach_post_wait_mode mode;

  dont_repeat ();		/* Not for the faint of heart */

  scoped_disable_commit_resumed disable_commit_resumed ("attaching");

  if (gdbarch_has_global_solist (target_gdbarch ()))
    /* Don't complain if all processes share the same symbol
       space.  */
    ;
  else if (target_has_execution ())
    {
      if (query (_("A program is being debugged already.  Kill it? ")))
	target_kill ();
      else
	error (_("Not killed."));
    }

  /* Clean up any leftovers from other runs.  Some other things from
     this function should probably be moved into target_pre_inferior.  */
  target_pre_inferior (from_tty);

  gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (args, &async_exec);
  args = stripped.get ();

  attach_target = find_attach_target ();

  prepare_execution_command (attach_target, async_exec);

  if (non_stop && !attach_target->supports_non_stop ())
    error (_("Cannot attach to this target in non-stop mode"));

  attach_target->attach (args, from_tty);
  /* to_attach should push the target, so after this point we
     shouldn't refer to attach_target again.  */
  attach_target = nullptr;

  infrun_debug_show_threads ("immediately after attach",
			     current_inferior ()->non_exited_threads ());

  /* Enable async mode if it is supported by the target.  */
  if (target_can_async_p ())
    target_async (true);

  /* Set up the "saved terminal modes" of the inferior
     based on what modes we are starting it with.  */
  target_terminal::init ();

  /* Install inferior's terminal modes.  This may look like a no-op,
     as we've just saved them above, however, this does more than
     restore terminal settings:

     - installs a SIGINT handler that forwards SIGINT to the inferior.
       Otherwise a Ctrl-C pressed just while waiting for the initial
       stop would end up as a spurious Quit.

     - removes stdin from the event loop, which we need if attaching
       in the foreground, otherwise on targets that report an initial
       stop on attach (which are most) we'd process input/commands
       while we're in the event loop waiting for that stop.  That is,
       before the attach continuation runs and the command is really
       finished.  */
  target_terminal::inferior ();

  /* Set up execution context to know that we should return from
     wait_for_inferior as soon as the target reports a stop.  */
  init_wait_for_inferior ();

  inferior->needs_setup = true;

  if (target_is_non_stop_p ())
    {
      /* If we find that the current thread isn't stopped, explicitly
	 do so now, because we're going to install breakpoints and
	 poke at memory.  */

      if (async_exec)
	/* The user requested an `attach&'; stop just one thread.  */
	target_stop (inferior_ptid);
      else
	/* The user requested an `attach', so stop all threads of this
	   inferior.  */
	target_stop (ptid_t (inferior_ptid.pid ()));
    }

  /* Check for exec file mismatch, and let the user solve it.  */
  validate_exec_file (from_tty);

  mode = async_exec ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_STOP;

  /* Some system don't generate traps when attaching to inferior.
     E.g. Mach 3 or GNU hurd.  */
  if (!target_attach_no_wait ())
    {
      /* Careful here.  See comments in inferior.h.  Basically some
	 OSes don't ignore SIGSTOPs on continue requests anymore.  We
	 need a way for handle_inferior_event to reset the stop_signal
	 variable after an attach, and this is what
	 STOP_QUIETLY_NO_SIGSTOP is for.  */
      inferior->control.stop_soon = STOP_QUIETLY_NO_SIGSTOP;

      /* Wait for stop.  */
      inferior->add_continuation ([=] ()
	{
	  attach_post_wait (from_tty, mode);
	});

      /* Let infrun consider waiting for events out of this
	 target.  */
      inferior->process_target ()->threads_executing = true;

      if (!target_is_async_p ())
	mark_infrun_async_event_handler ();
      return;
    }
  else
    attach_post_wait (from_tty, mode);

  disable_commit_resumed.reset_and_commit ();
}

/* We had just found out that the target was already attached to an
   inferior.  PTID points at a thread of this new inferior, that is
   the most likely to be stopped right now, but not necessarily so.
   The new inferior is assumed to be already added to the inferior
   list at this point.  If LEAVE_RUNNING, then leave the threads of
   this inferior running, except those we've explicitly seen reported
   as stopped.  */

void
notice_new_inferior (thread_info *thr, bool leave_running, int from_tty)
{
  enum attach_post_wait_mode mode
    = leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING;

  gdb::optional<scoped_restore_current_thread> restore_thread;

  if (inferior_ptid != null_ptid)
    restore_thread.emplace ();

  /* Avoid reading registers -- we haven't fetched the target
     description yet.  */
  switch_to_thread_no_regs (thr);

  /* When we "notice" a new inferior we need to do all the things we
     would normally do if we had just attached to it.  */

  if (thr->executing ())
    {
      struct inferior *inferior = current_inferior ();

      /* We're going to install breakpoints, and poke at memory,
	 ensure that the inferior is stopped for a moment while we do
	 that.  */
      target_stop (inferior_ptid);

      inferior->control.stop_soon = STOP_QUIETLY_REMOTE;

      /* Wait for stop before proceeding.  */
      inferior->add_continuation ([=] ()
	{
	  attach_post_wait (from_tty, mode);
	});

      return;
    }

  attach_post_wait (from_tty, mode);
}

/*
 * detach_command --
 * takes a program previously attached to and detaches it.
 * The program resumes execution 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.  For this
 * to work, it may be necessary for the process to have been
 * previously attached.  It *might* work if the program was
 * started via the normal ptrace (PTRACE_TRACEME).
 */

void
detach_command (const char *args, int from_tty)
{
  dont_repeat ();		/* Not for the faint of heart.  */

  if (inferior_ptid == null_ptid)
    error (_("The program is not being run."));

  scoped_disable_commit_resumed disable_commit_resumed ("detaching");

  query_if_trace_running (from_tty);

  disconnect_tracing ();

  /* Hold a strong reference to the target while (maybe)
     detaching the parent.  Otherwise detaching could close the
     target.  */
  auto target_ref
    = target_ops_ref::new_reference (current_inferior ()->process_target ());

  /* Save this before detaching, since detaching may unpush the
     process_stratum target.  */
  bool was_non_stop_p = target_is_non_stop_p ();

  target_detach (current_inferior (), from_tty);

  update_previous_thread ();

  /* The current inferior process was just detached successfully.  Get
     rid of breakpoints that no longer make sense.  Note we don't do
     this within target_detach because that is also used when
     following child forks, and in that case we will want to transfer
     breakpoints to the child, not delete them.  */
  breakpoint_init_inferior (inf_exited);

  /* If the solist is global across inferiors, don't clear it when we
     detach from a single inferior.  */
  if (!gdbarch_has_global_solist (target_gdbarch ()))
    no_shared_libraries (nullptr, from_tty);

  if (deprecated_detach_hook)
    deprecated_detach_hook ();

  if (!was_non_stop_p)
    restart_after_all_stop_detach (as_process_stratum_target (target_ref.get ()));

  disable_commit_resumed.reset_and_commit ();
}

/* Disconnect from the current target without resuming it (leaving it
   waiting for a debugger).

   We'd better not have left any breakpoints in the program or the
   next debugger will get confused.  Currently only supported for some
   remote targets, since the normal attach mechanisms don't work on
   stopped processes on some native platforms (e.g. GNU/Linux).  */

static void
disconnect_command (const char *args, int from_tty)
{
  dont_repeat ();		/* Not for the faint of heart.  */
  query_if_trace_running (from_tty);
  disconnect_tracing ();
  target_disconnect (args, from_tty);
  no_shared_libraries (nullptr, from_tty);
  init_thread_list ();
  update_previous_thread ();
  if (deprecated_detach_hook)
    deprecated_detach_hook ();
}

/* Stop PTID in the current target, and tag the PTID threads as having
   been explicitly requested to stop.  PTID can be a thread, a
   process, or minus_one_ptid, meaning all threads of all inferiors of
   the current target.  */

static void
stop_current_target_threads_ns (ptid_t ptid)
{
  target_stop (ptid);

  /* Tag the thread as having been explicitly requested to stop, so
     other parts of gdb know not to resume this thread automatically,
     if it was stopped due to an internal event.  Limit this to
     non-stop mode, as when debugging a multi-threaded application in
     all-stop mode, we will only get one stop event --- it's undefined
     which thread will report the event.  */
  set_stop_requested (current_inferior ()->process_target (),
		      ptid, 1);
}

/* See inferior.h.  */

void
interrupt_target_1 (bool all_threads)
{
  scoped_disable_commit_resumed disable_commit_resumed ("interrupting");

  if (non_stop)
    {
      if (all_threads)
	{
	  scoped_restore_current_thread restore_thread;

	  for (inferior *inf : all_inferiors ())
	    {
	      switch_to_inferior_no_thread (inf);
	      stop_current_target_threads_ns (minus_one_ptid);
	    }
	}
      else
	stop_current_target_threads_ns (inferior_ptid);
    }
  else
    target_interrupt ();

  disable_commit_resumed.reset_and_commit ();
}

/* interrupt [-a]
   Stop the execution of the target while running in async mode, in
   the background.  In all-stop, stop the whole process.  In non-stop
   mode, stop the current thread only by default, or stop all threads
   if the `-a' switch is used.  */

static void
interrupt_command (const char *args, int from_tty)
{
  if (target_can_async_p ())
    {
      int all_threads = 0;

      dont_repeat ();		/* Not for the faint of heart.  */

      if (args != nullptr
	  && startswith (args, "-a"))
	all_threads = 1;

      interrupt_target_1 (all_threads);
    }
}

/* See inferior.h.  */

void
default_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
			  frame_info_ptr frame, const char *args)
{
  int regnum;
  int printed_something = 0;

  for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
    {
      if (gdbarch_register_reggroup_p (gdbarch, regnum, float_reggroup))
	{
	  printed_something = 1;
	  gdbarch_print_registers_info (gdbarch, file, frame, regnum, 1);
	}
    }
  if (!printed_something)
    gdb_printf (file, "No floating-point info "
		"available for this processor.\n");
}

static void
info_float_command (const char *args, int from_tty)
{
  frame_info_ptr frame;

  if (!target_has_registers ())
    error (_("The program has no registers now."));

  frame = get_selected_frame (nullptr);
  gdbarch_print_float_info (get_frame_arch (frame), gdb_stdout, frame, args);
}

/* Implement `info proc' family of commands.  */

static void
info_proc_cmd_1 (const char *args, enum info_proc_what what, int from_tty)
{
  struct gdbarch *gdbarch = get_current_arch ();

  if (!target_info_proc (args, what))
    {
      if (gdbarch_info_proc_p (gdbarch))
	gdbarch_info_proc (gdbarch, args, what);
      else
	error (_("Not supported on this target."));
    }
}

/* Implement `info proc' when given without any further parameters.  */

static void
info_proc_cmd (const char *args, int from_tty)
{
  info_proc_cmd_1 (args, IP_MINIMAL, from_tty);
}

/* Implement `info proc mappings'.  */

static void
info_proc_cmd_mappings (const char *args, int from_tty)
{
  info_proc_cmd_1 (args, IP_MAPPINGS, from_tty);
}

/* Implement `info proc stat'.  */

static void
info_proc_cmd_stat (const char *args, int from_tty)
{
  info_proc_cmd_1 (args, IP_STAT, from_tty);
}

/* Implement `info proc status'.  */

static void
info_proc_cmd_status (const char *args, int from_tty)
{
  info_proc_cmd_1 (args, IP_STATUS, from_tty);
}

/* Implement `info proc cwd'.  */

static void
info_proc_cmd_cwd (const char *args, int from_tty)
{
  info_proc_cmd_1 (args, IP_CWD, from_tty);
}

/* Implement `info proc cmdline'.  */

static void
info_proc_cmd_cmdline (const char *args, int from_tty)
{
  info_proc_cmd_1 (args, IP_CMDLINE, from_tty);
}

/* Implement `info proc exe'.  */

static void
info_proc_cmd_exe (const char *args, int from_tty)
{
  info_proc_cmd_1 (args, IP_EXE, from_tty);
}

/* Implement `info proc files'.  */

static void
info_proc_cmd_files (const char *args, int from_tty)
{
  info_proc_cmd_1 (args, IP_FILES, from_tty);
}

/* Implement `info proc all'.  */

static void
info_proc_cmd_all (const char *args, int from_tty)
{
  info_proc_cmd_1 (args, IP_ALL, from_tty);
}

/* Implement `show print finish'.  */

static void
show_print_finish (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c,
		   const char *value)
{
  gdb_printf (file, _("\
Printing of return value after `finish' is %s.\n"),
	      value);
}


/* This help string is used for the run, start, and starti commands.
   It is defined as a macro to prevent duplication.  */

#define RUN_ARGS_HELP \
"You may specify arguments to give it.\n\
Args may include \"*\", or \"[...]\"; they are expanded using the\n\
shell that will start the program (specified by the \"$SHELL\" environment\n\
variable).  Input and output redirection with \">\", \"<\", or \">>\"\n\
are also allowed.\n\
\n\
With no arguments, uses arguments last specified (with \"run\" or \n\
\"set args\").  To cancel previous arguments and run with no arguments,\n\
use \"set args\" without arguments.\n\
\n\
To start the inferior without using a shell, use \"set startup-with-shell off\"."

void _initialize_infcmd ();
void
_initialize_infcmd ()
{
  static struct cmd_list_element *info_proc_cmdlist;
  struct cmd_list_element *c = nullptr;
  const char *cmd_name;

  /* Add the filename of the terminal connected to inferior I/O.  */
  add_setshow_optional_filename_cmd ("inferior-tty", class_run,
				     &inferior_io_terminal_scratch, _("\
Set terminal for future runs of program being debugged."), _("\
Show terminal for future runs of program being debugged."), _("\
Usage: set inferior-tty [TTY]\n\n\
If TTY is omitted, the default behavior of using the same terminal as GDB\n\
is restored."),
				     set_inferior_tty_command,
				     show_inferior_tty_command,
				     &setlist, &showlist);
  cmd_name = "inferior-tty";
  c = lookup_cmd (&cmd_name, setlist, "", nullptr, -1, 1);
  gdb_assert (c != nullptr);
  add_alias_cmd ("tty", c, class_run, 0, &cmdlist);

  cmd_name = "args";
  add_setshow_string_noescape_cmd (cmd_name, class_run,
				   &inferior_args_scratch, _("\
Set argument list to give program being debugged when it is started."), _("\
Show argument list to give program being debugged when it is started."), _("\
Follow this command with any number of args, to be passed to the program."),
				   set_args_command,
				   show_args_command,
				   &setlist, &showlist);
  c = lookup_cmd (&cmd_name, setlist, "", nullptr, -1, 1);
  gdb_assert (c != nullptr);
  set_cmd_completer (c, filename_completer);

  cmd_name = "cwd";
  add_setshow_string_noescape_cmd (cmd_name, class_run,
				   &inferior_cwd_scratch, _("\
Set the current working directory to be used when the inferior is started.\n\
Changing this setting does not have any effect on inferiors that are\n\
already running."),
				   _("\
Show the current working directory that is used when the inferior is started."),
				   _("\
Use this command to change the current working directory that will be used\n\
when the inferior is started.  This setting does not affect GDB's current\n\
working directory."),
				   set_cwd_command,
				   show_cwd_command,
				   &setlist, &showlist);
  c = lookup_cmd (&cmd_name, setlist, "", nullptr, -1, 1);
  gdb_assert (c != nullptr);
  set_cmd_completer (c, filename_completer);

  c = add_cmd ("environment", no_class, environment_info, _("\
The environment to give the program, or one variable's value.\n\
With an argument VAR, prints the value of environment variable VAR to\n\
give the program being debugged.  With no arguments, prints the entire\n\
environment to be given to the program."), &showlist);
  set_cmd_completer (c, noop_completer);

  add_basic_prefix_cmd ("unset", no_class,
			_("Complement to certain \"set\" commands."),
			&unsetlist, 0, &cmdlist);

  c = add_cmd ("environment", class_run, unset_environment_command, _("\
Cancel environment variable VAR for the program.\n\
This does not affect the program until the next \"run\" command."),
	       &unsetlist);
  set_cmd_completer (c, noop_completer);

  c = add_cmd ("environment", class_run, set_environment_command, _("\
Set environment variable value to give the program.\n\
Arguments are VAR VALUE where VAR is variable name and VALUE is value.\n\
VALUES of environment variables are uninterpreted strings.\n\
This does not affect the program until the next \"run\" command."),
	       &setlist);
  set_cmd_completer (c, noop_completer);

  c = add_com ("path", class_files, path_command, _("\
Add directory DIR(s) to beginning of search path for object files.\n\
$cwd in the path means the current working directory.\n\
This path is equivalent to the $PATH shell variable.  It is a list of\n\
directories, separated by colons.  These directories are searched to find\n\
fully linked executable files and separately compiled object files as \
needed."));
  set_cmd_completer (c, filename_completer);

  c = add_cmd ("paths", no_class, path_info, _("\
Current search path for finding object files.\n\
$cwd in the path means the current working directory.\n\
This path is equivalent to the $PATH shell variable.  It is a list of\n\
directories, separated by colons.  These directories are searched to find\n\
fully linked executable files and separately compiled object files as \
needed."),
	       &showlist);
  set_cmd_completer (c, noop_completer);

  add_prefix_cmd ("kill", class_run, kill_command,
		  _("Kill execution of program being debugged."),
		  &killlist, 0, &cmdlist);

  add_com ("attach", class_run, attach_command, _("\
Attach to a process or file outside of GDB.\n\
This command attaches to another target, of the same type as your last\n\
\"target\" command (\"info files\" will show your target stack).\n\
The command may take as argument a process id or a device file.\n\
For a process id, you must have permission to send the process a signal,\n\
and it must have the same effective uid as the debugger.\n\
When using \"attach\" with a process id, the debugger finds the\n\
program running in the process, looking first in the current working\n\
directory, or (if not found there) using the source file search path\n\
(see the \"directory\" command).  You can also use the \"file\" command\n\
to specify the program, and to load its symbol table."));

  add_prefix_cmd ("detach", class_run, detach_command, _("\
Detach a process or file previously attached.\n\
If a process, it is no longer traced, and it continues its execution.  If\n\
you were debugging a file, the file is closed and gdb no longer accesses it."),
		  &detachlist, 0, &cmdlist);

  add_com ("disconnect", class_run, disconnect_command, _("\
Disconnect from a target.\n\
The target will wait for another debugger to connect.  Not available for\n\
all targets."));

  c = add_com ("signal", class_run, signal_command, _("\
Continue program with the specified signal.\n\
Usage: signal SIGNAL\n\
The SIGNAL argument is processed the same as the handle command.\n\
\n\
An argument of \"0\" means continue the program without sending it a signal.\n\
This is useful in cases where the program stopped because of a signal,\n\
and you want to resume the program while discarding the signal.\n\
\n\
In a multi-threaded program the signal is delivered to, or discarded from,\n\
the current thread only."));
  set_cmd_completer (c, signal_completer);

  c = add_com ("queue-signal", class_run, queue_signal_command, _("\
Queue a signal to be delivered to the current thread when it is resumed.\n\
Usage: queue-signal SIGNAL\n\
The SIGNAL argument is processed the same as the handle command.\n\
It is an error if the handling state of SIGNAL is \"nopass\".\n\
\n\
An argument of \"0\" means remove any currently queued signal from\n\
the current thread.  This is useful in cases where the program stopped\n\
because of a signal, and you want to resume it while discarding the signal.\n\
\n\
In a multi-threaded program the signal is queued with, or discarded from,\n\
the current thread only."));
  set_cmd_completer (c, signal_completer);

  cmd_list_element *stepi_cmd
    = add_com ("stepi", class_run, stepi_command, _("\
Step one instruction exactly.\n\
Usage: stepi [N]\n\
Argument N means step N times (or till program stops for another \
reason)."));
  add_com_alias ("si", stepi_cmd, class_run, 0);

  cmd_list_element *nexti_cmd
   = add_com ("nexti", class_run, nexti_command, _("\
Step one instruction, but proceed through subroutine calls.\n\
Usage: nexti [N]\n\
Argument N means step N times (or till program stops for another \
reason)."));
  add_com_alias ("ni", nexti_cmd, class_run, 0);

  cmd_list_element *finish_cmd
    = add_com ("finish", class_run, finish_command, _("\
Execute until selected stack frame returns.\n\
Usage: finish\n\
Upon return, the value returned is printed and put in the value history."));
  add_com_alias ("fin", finish_cmd, class_run, 1);

  cmd_list_element *next_cmd
    = add_com ("next", class_run, next_command, _("\
Step program, proceeding through subroutine calls.\n\
Usage: next [N]\n\
Unlike \"step\", if the current source line calls a subroutine,\n\
this command does not enter the subroutine, but instead steps over\n\
the call, in effect treating it as a single source line."));
  add_com_alias ("n", next_cmd, class_run, 1);

  cmd_list_element *step_cmd
    = add_com ("step", class_run, step_command, _("\
Step program until it reaches a different source line.\n\
Usage: step [N]\n\
Argument N means step N times (or till program stops for another \
reason)."));
  add_com_alias ("s", step_cmd, class_run, 1);

  cmd_list_element *until_cmd
    = add_com ("until", class_run, until_command, _("\
Execute until past the current line or past a LOCATION.\n\
Execute until the program reaches a source line greater than the current\n\
or a specified location (same args as break command) within the current \
frame."));
  set_cmd_completer (until_cmd, location_completer);
  add_com_alias ("u", until_cmd, class_run, 1);

  c = add_com ("advance", class_run, advance_command, _("\
Continue the program up to the given location (same form as args for break \
command).\n\
Execution will also stop upon exit from the current stack frame."));
  set_cmd_completer (c, location_completer);

  cmd_list_element *jump_cmd
    = add_com ("jump", class_run, jump_command, _("\
Continue program being debugged at specified line or address.\n\
Usage: jump LOCATION\n\
Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\
for an address to start at."));
  set_cmd_completer (jump_cmd, location_completer);
  add_com_alias ("j", jump_cmd, class_run, 1);

  cmd_list_element *continue_cmd
    = add_com ("continue", class_run, continue_command, _("\
Continue program being debugged, after signal or breakpoint.\n\
Usage: continue [N]\n\
If proceeding from breakpoint, a number N may be used as an argument,\n\
which means to set the ignore count of that breakpoint to N - 1 (so that\n\
the breakpoint won't break until the Nth time it is reached).\n\
\n\
If non-stop mode is enabled, continue only the current thread,\n\
otherwise all the threads in the program are continued.  To \n\
continue all stopped threads in non-stop mode, use the -a option.\n\
Specifying -a and an ignore count simultaneously is an error."));
  add_com_alias ("c", continue_cmd, class_run, 1);
  add_com_alias ("fg", continue_cmd, class_run, 1);

  cmd_list_element *run_cmd
    = add_com ("run", class_run, run_command, _("\
Start debugged program.\n"
RUN_ARGS_HELP));
  set_cmd_completer (run_cmd, filename_completer);
  add_com_alias ("r", run_cmd, class_run, 1);

  c = add_com ("start", class_run, start_command, _("\
Start the debugged program stopping at the beginning of the main procedure.\n"
RUN_ARGS_HELP));
  set_cmd_completer (c, filename_completer);

  c = add_com ("starti", class_run, starti_command, _("\
Start the debugged program stopping at the first instruction.\n"
RUN_ARGS_HELP));
  set_cmd_completer (c, filename_completer);

  add_com ("interrupt", class_run, interrupt_command,
	   _("Interrupt the execution of the debugged program.\n\
If non-stop mode is enabled, interrupt only the current thread,\n\
otherwise all the threads in the program are stopped.  To \n\
interrupt all running threads in non-stop mode, use the -a option."));

  cmd_list_element *info_registers_cmd
    = add_info ("registers", info_registers_command, _("\
List of integer registers and their contents, for selected stack frame.\n\
One or more register names as argument means describe the given registers.\n\
One or more register group names as argument means describe the registers\n\
in the named register groups."));
  add_info_alias ("r", info_registers_cmd, 1);
  set_cmd_completer (info_registers_cmd, reg_or_group_completer);

  c = add_info ("all-registers", info_all_registers_command, _("\
List of all registers and their contents, for selected stack frame.\n\
One or more register names as argument means describe the given registers.\n\
One or more register group names as argument means describe the registers\n\
in the named register groups."));
  set_cmd_completer (c, reg_or_group_completer);

  add_info ("program", info_program_command,
	    _("Execution status of the program."));

  add_info ("float", info_float_command,
	    _("Print the status of the floating point unit."));

  add_info ("vector", info_vector_command,
	    _("Print the status of the vector unit."));

  add_prefix_cmd ("proc", class_info, info_proc_cmd,
		  _("\
Show additional information about a process.\n\
Specify any process id, or use the program being debugged by default."),
		  &info_proc_cmdlist,
		  1/*allow-unknown*/, &infolist);

  add_cmd ("mappings", class_info, info_proc_cmd_mappings, _("\
List memory regions mapped by the specified process."),
	   &info_proc_cmdlist);

  add_cmd ("stat", class_info, info_proc_cmd_stat, _("\
List process info from /proc/PID/stat."),
	   &info_proc_cmdlist);

  add_cmd ("status", class_info, info_proc_cmd_status, _("\
List process info from /proc/PID/status."),
	   &info_proc_cmdlist);

  add_cmd ("cwd", class_info, info_proc_cmd_cwd, _("\
List current working directory of the specified process."),
	   &info_proc_cmdlist);

  add_cmd ("cmdline", class_info, info_proc_cmd_cmdline, _("\
List command line arguments of the specified process."),
	   &info_proc_cmdlist);

  add_cmd ("exe", class_info, info_proc_cmd_exe, _("\
List absolute filename for executable of the specified process."),
	   &info_proc_cmdlist);

  add_cmd ("files", class_info, info_proc_cmd_files, _("\
List files opened by the specified process."),
	   &info_proc_cmdlist);

  add_cmd ("all", class_info, info_proc_cmd_all, _("\
List all available info about the specified process."),
	   &info_proc_cmdlist);

  add_setshow_boolean_cmd ("finish", class_support,
			   &finish_print, _("\
Set whether `finish' prints the return value."), _("\
Show whether `finish' prints the return value."), nullptr,
			   nullptr,
			   show_print_finish,
			   &setprintlist, &showprintlist);
}
