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

   Copyright (C) 1986-2022 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"

/* 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 == NULL || *args == '\0')
    {
      *bg_char_p = 0;
      return NULL;
    }

  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 (NULL, 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)
    {
      std::string arg = string_printf ("-qualified %s", main_name ());
      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 != NULL)
    current_inferior ()->set_args (args);

  if (from_tty)
    {
      uiout->field_string (NULL, "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 = NULL;

  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, NULL);

      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 != NULL)
    {
      if (startswith (args, "-a"))
	{
	  all_threads_p = true;
	  args += sizeof ("-a") - 1;
	  if (*args == '\0')
	    args = NULL;
	}
    }

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

  if (args != NULL && 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 != NULL)
    {
      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 = find_thread_ptid (last_target, last_ptid);
	}
      if (tp != NULL)
	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");
	}
    }

  ERROR_NO_INFERIOR;
  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 *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
    {
      int proceeded;

      /* Stepped into an inline frame.  Pretend that we've
	 stopped.  */
      thr->thread_fsm ()->clean_up (thr);
      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)
    {
      struct frame_info *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 = NULL;
	      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 != NULL)
		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 != NULL && sfn != fn)
    {
      if (!query (_("Line %d is not in `%s'.  Jump anyway? "), sal.line,
		  fn->print_name ()))
	{
	  error (_("Not confirmed."));
	  /* NOTREACHED */
	}
    }

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

      fixup_symbol_section (sfn, 0);
      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 == NULL)
    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)
{
  struct frame_info *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 == NULL)
	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 == NULL)
    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 (TYPE_TARGET_TYPE (func_symbol->type ()));
  gdb_assert (value_type->code () != TYPE_CODE_VOID);

  if (is_nocall_function (check_typedef (::value_type (function))))
    {
      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 (gdbarch, function, value_type,
				NULL, NULL, NULL))
    {
    case RETURN_VALUE_REGISTER_CONVENTION:
    case RETURN_VALUE_ABI_RETURNS_ADDRESS:
    case RETURN_VALUE_ABI_PRESERVES_ADDRESS:
      value = allocate_value (value_type);
      gdbarch_return_value (gdbarch, function, value_type, stop_regs,
			    value_contents_raw (value).data (), NULL);
      break;
    case RETURN_VALUE_STRUCT_CONVENTION:
      value = NULL;
      break;
    default:
      internal_error (__FILE__, __LINE__, _("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 != NULL)
    {
      /* 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 == NULL
      || 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 &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 {};

  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 != NULL
      && bpstat_find_breakpoint (tp->control.stop_bpstat,
				 breakpoint.get ()) != NULL)
    {
      /* We're done.  */
      set_finished ();

      rv->type = TYPE_TARGET_TYPE (function->type ());
      if (rv->type == NULL)
	internal_error (__FILE__, __LINE__,
			_("finish_command: function has no target type"));

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

	  func = read_var_value (function, NULL, get_current_frame ());
	  rv->value = get_return_value (function, func);
	  if (rv->value != NULL)
	    rv->value_history_index = record_latest_value (rv->value);
	}
    }
  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;

  pc = get_frame_pc (get_current_frame ());

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

  sal = find_pc_line (func_addr, 0);

  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 (sal.pc != pc)
    {
      struct frame_info *frame = get_selected_frame (NULL);
      struct gdbarch *gdbarch = get_frame_arch (frame);

      /* Set a step-resume at the function's entry point.  Once that's
	 hit, we'll do one more step backwards.  */
      symtab_and_line sr_sal;
      sr_sal.pc = sal.pc;
      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're almost there -- we just need to back up by one more
	 single-step.  */
      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, struct frame_info *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 = NULL;

  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 struct frame_info *
skip_finish_frames (struct frame_info *frame)
{
  struct frame_info *start;

  do
    {
      start = frame;

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

      frame = skip_unwritable_frames (frame);
      if (frame == NULL)
	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)
{
  struct frame_info *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 (NULL), 1, LOCATION, 0);
	}

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

  /* Find the function we will return from.  */

  sm->function = find_pc_function (get_frame_pc (get_selected_frame (NULL)));

  /* 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 != NULL && 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 (get_selected_frame (NULL), 1, LOCATION, 0);
    }

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

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

      finish_forward (sm, frame);
    }
}


static void
info_program_command (const char *args, int from_tty)
{
  bpstat *bs;
  int num, stat;
  ptid_t ptid;
  process_stratum_target *proc_target;

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

  if (non_stop)
    {
      ptid = inferior_ptid;
      proc_target = current_inferior ()->process_target ();
    }
  else
    get_last_target_status (&proc_target, &ptid, nullptr);

  if (ptid == null_ptid || ptid == minus_one_ptid)
    error (_("No selected thread."));

  thread_info *tp = find_thread_ptid (proc_target, ptid);

  if (tp->state == THREAD_EXITED)
    error (_("Invalid selected thread."));
  else if (tp->state == THREAD_RUNNING)
    error (_("Selected thread is running."));

  bs = tp->control.stop_bpstat;
  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] != NULL; ++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 (NULL, 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 = value_type (val);
  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 = (value_entirely_available (val)
		      && !value_optimized_out (val));

  /* 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 = value_contents_for_printing (val).data ();
      enum bfd_endian byte_order = type_byte_order (regtype);

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

      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, TYPE_LENGTH (regtype),
			   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 = 1;
      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 = 1;
	  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,
			      struct frame_info *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) == NULL
	  || *(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)
{
  struct frame_info *frame;
  struct gdbarch *gdbarch;

  if (!target_has_registers ())
    error (_("The program has no registers now."));
  frame = get_selected_frame (NULL);
  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 != NULL)
	  {
	    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,
		   struct frame_info *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 (NULL), 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 ();

  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 = 0;

  /* If no exec file is yet known, try to determine it from the
     process itself.  */
  if (get_exec_file (0) == NULL)
    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 = NULL;

  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 (1);

  /* 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 = 1;

  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);

  /* 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 (NULL, 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 (NULL, from_tty);
  init_thread_list ();
  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 != NULL
	  && 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,
			  struct frame_info *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)
{
  struct frame_info *frame;

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

  frame = get_selected_frame (NULL);
  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 = NULL;
  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, "", NULL, -1, 1);
  gdb_assert (c != NULL);
  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, "", NULL, -1, 1);
  gdb_assert (c != NULL);
  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, "", NULL, -1, 1);
  gdb_assert (c != NULL);
  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."), NULL,
			   NULL,
			   show_print_finish,
			   &setprintlist, &showprintlist);
}
