/* Variables that describe the inferior process running under GDB:
   Where it is, why it stopped, and how to step it.

   Copyright (C) 1986-2023 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#if !defined (INFERIOR_H)
#define INFERIOR_H 1

#include <exception>
#include <list>

struct target_waitstatus;
class frame_info_ptr;
struct ui_file;
struct type;
struct gdbarch;
struct regcache;
struct ui_out;
struct terminal_info;
struct target_desc_info;
struct inferior;
struct thread_info;

/* For bpstat.  */
#include "breakpoint.h"

/* For enum gdb_signal.  */
#include "target.h"

/* For struct frame_id.  */
#include "frame.h"

/* For gdb_environ.  */
#include "gdbsupport/environ.h"

#include "progspace.h"
#include "registry.h"

#include "symfile-add-flags.h"
#include "gdbsupport/refcounted-object.h"
#include "gdbsupport/forward-scope-exit.h"
#include "gdbsupport/gdb_unique_ptr.h"
#include "gdbsupport/intrusive_list.h"

#include "gdbsupport/common-inferior.h"
#include "gdbthread.h"

#include "process-stratum-target.h"
#include "displaced-stepping.h"

#include <unordered_map>

struct infcall_suspend_state;
struct infcall_control_state;

extern void restore_infcall_suspend_state (struct infcall_suspend_state *);
extern void restore_infcall_control_state (struct infcall_control_state *);

/* A deleter for infcall_suspend_state that calls
   restore_infcall_suspend_state.  */
struct infcall_suspend_state_deleter
{
  void operator() (struct infcall_suspend_state *state) const
  {
    try
      {
	restore_infcall_suspend_state (state);
      }
    catch (const gdb_exception_error &e)
      {
	/* If we are restoring the inferior state due to an exception,
	   some error message will be printed.  So, only warn the user
	   when we cannot restore during normal execution.  */
	bool unwinding;
#if __cpp_lib_uncaught_exceptions
	unwinding = std::uncaught_exceptions () > 0;
#else
	unwinding = std::uncaught_exception ();
#endif
	if (!unwinding)
	  warning (_("Failed to restore inferior state: %s"), e.what ());
      }
  }
};

/* A unique_ptr specialization for infcall_suspend_state.  */
typedef std::unique_ptr<infcall_suspend_state, infcall_suspend_state_deleter>
    infcall_suspend_state_up;

extern infcall_suspend_state_up save_infcall_suspend_state ();

/* A deleter for infcall_control_state that calls
   restore_infcall_control_state.  */
struct infcall_control_state_deleter
{
  void operator() (struct infcall_control_state *state) const
  {
    restore_infcall_control_state (state);
  }
};

/* A unique_ptr specialization for infcall_control_state.  */
typedef std::unique_ptr<infcall_control_state, infcall_control_state_deleter>
    infcall_control_state_up;

extern infcall_control_state_up save_infcall_control_state ();

extern void discard_infcall_suspend_state (struct infcall_suspend_state *);
extern void discard_infcall_control_state (struct infcall_control_state *);

extern readonly_detached_regcache *
  get_infcall_suspend_state_regcache (struct infcall_suspend_state *);

extern void set_sigint_trap (void);

extern void clear_sigint_trap (void);

/* Collected pid, tid, etc. of the debugged inferior.  When there's
   no inferior, inferior_ptid.pid () will be 0.  */

extern ptid_t inferior_ptid;

extern void generic_mourn_inferior (void);

extern CORE_ADDR unsigned_pointer_to_address (struct gdbarch *gdbarch,
					      struct type *type,
					      const gdb_byte *buf);
extern void unsigned_address_to_pointer (struct gdbarch *gdbarch,
					 struct type *type, gdb_byte *buf,
					 CORE_ADDR addr);
extern CORE_ADDR signed_pointer_to_address (struct gdbarch *gdbarch,
					    struct type *type,
					    const gdb_byte *buf);
extern void address_to_signed_pointer (struct gdbarch *gdbarch,
				       struct type *type, gdb_byte *buf,
				       CORE_ADDR addr);

extern void reopen_exec_file (void);

/* From misc files */

extern void default_print_registers_info (struct gdbarch *gdbarch,
					  struct ui_file *file,
					  frame_info_ptr frame,
					  int regnum, int all);

/* Default implementation of gdbarch_print_float_info.  Print
   the values of all floating point registers.  */

extern void default_print_float_info (struct gdbarch *gdbarch,
				      struct ui_file *file,
				      frame_info_ptr frame,
				      const char *args);

/* Try to determine whether TTY is GDB's input terminal.  Returns
   TRIBOOL_UNKNOWN if we can't tell.  */

extern tribool is_gdb_terminal (const char *tty);

/* Helper for sharing_input_terminal.  Try to determine whether pid
   PID is using the same TTY for input as GDB is.  Returns
   TRIBOOL_UNKNOWN if we can't tell.  */

extern tribool sharing_input_terminal (int pid);

/* The type of the function that is called when SIGINT is handled.  */

typedef void c_c_handler_ftype (int);

/* Install a new SIGINT handler in a host-dependent way.  The previous
   handler is returned.  It is fine to pass SIG_IGN for FN, but not
   SIG_DFL.  */

extern c_c_handler_ftype *install_sigint_handler (c_c_handler_ftype *fn);

extern void child_terminal_info (struct target_ops *self, const char *, int);

extern void child_terminal_ours (struct target_ops *self);

extern void child_terminal_ours_for_output (struct target_ops *self);

extern void child_terminal_inferior (struct target_ops *self);

extern void child_terminal_save_inferior (struct target_ops *self);

extern void child_terminal_init (struct target_ops *self);

extern void child_terminal_init_with_pgrp (int pgrp);

extern void child_pass_ctrlc (struct target_ops *self);

extern void child_interrupt (struct target_ops *self);

/* From fork-child.c */

/* Helper function to call STARTUP_INFERIOR with PID and NUM_TRAPS.
   This function already calls set_executing.  Return the ptid_t from
   STARTUP_INFERIOR.  */
extern ptid_t gdb_startup_inferior (pid_t pid, int num_traps);

/* From infcmd.c */

/* Initial inferior setup.  Determines the exec file is not yet known,
   takes any necessary post-attaching actions, fetches the target
   description and syncs the shared library list.  */

extern void setup_inferior (int from_tty);

extern void post_create_inferior (int from_tty);

extern void attach_command (const char *, int);

extern void set_inferior_args_vector (int, char **);

extern void registers_info (const char *, int);

extern void continue_1 (int all_threads);

extern void interrupt_target_1 (bool all_threads);

using delete_longjmp_breakpoint_cleanup
  = FORWARD_SCOPE_EXIT (delete_longjmp_breakpoint);

extern void detach_command (const char *, int);

extern void notice_new_inferior (struct thread_info *, bool, int);

/* Return the value of the result of a function at the end of a 'finish'
   command/BP.  If the result's value cannot be retrieved, return NULL.

   FUNC_SYMBOL is the symbol of the function being returned from.  FUNCTION is
   a value containing the address of the function.  */

extern struct value *get_return_value (struct symbol *func_symbol,
				       struct value *function);

/* Prepare for execution command.  TARGET is the target that will run
   the command.  BACKGROUND determines whether this is a foreground
   (synchronous) or background (asynchronous) command.  */

extern void prepare_execution_command (struct target_ops *target,
				       int background);

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

extern enum stop_stack_kind stop_stack_dummy;

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

extern int stopped_by_random_signal;

/* Print notices on inferior events (attach, detach, etc.), set with
   `set print inferior-events'.  */
extern bool print_inferior_events;

/* Anything but NO_STOP_QUIETLY means we expect a trap and the caller
   will handle it themselves.  STOP_QUIETLY is used when running in
   the shell before the child program has been exec'd and when running
   through shared library loading.  STOP_QUIETLY_REMOTE is used when
   setting up a remote connection; it is like STOP_QUIETLY_NO_SIGSTOP
   except that there is no need to hide a signal.  */

/* STOP_QUIETLY_NO_SIGSTOP is used to handle a tricky situation with attach.
   When doing an attach, the kernel stops the debuggee with a SIGSTOP.
   On newer GNU/Linux kernels (>= 2.5.61) the handling of SIGSTOP for
   a ptraced process has changed.  Earlier versions of the kernel
   would ignore these SIGSTOPs, while now SIGSTOP is treated like any
   other signal, i.e. it is not muffled.

   If the gdb user does a 'continue' after the 'attach', gdb passes
   the global variable stop_signal (which stores the signal from the
   attach, SIGSTOP) to the ptrace(PTRACE_CONT,...)  call.  This is
   problematic, because the kernel doesn't ignore such SIGSTOP
   now.  I.e. it is reported back to gdb, which in turn presents it
   back to the user.

   To avoid the problem, we use STOP_QUIETLY_NO_SIGSTOP, which allows
   gdb to clear the value of stop_signal after the attach, so that it
   is not passed back down to the kernel.  */

enum stop_kind
  {
    NO_STOP_QUIETLY = 0,
    STOP_QUIETLY,
    STOP_QUIETLY_REMOTE,
    STOP_QUIETLY_NO_SIGSTOP
  };



/* Base class for target-specific inferior data.  */

struct private_inferior
{
  virtual ~private_inferior () = 0;
};

/* Inferior process specific part of `struct infcall_control_state'.

   Inferior thread counterpart is `struct thread_control_state'.  */

struct inferior_control_state
{
  inferior_control_state ()
    : stop_soon (NO_STOP_QUIETLY)
  {
  }

  explicit inferior_control_state (enum stop_kind when)
    : stop_soon (when)
  {
  }

  /* See the definition of stop_kind above.  */
  enum stop_kind stop_soon;
};

/* Return a pointer to the current inferior.  */
extern inferior *current_inferior ();

extern void set_current_inferior (inferior *);

/* Switch inferior (and program space) to INF, and switch to no thread
   selected.  */
extern void switch_to_inferior_no_thread (inferior *inf);

/* Info about an inferior's target description.  There's one of these
   for each inferior.  */

struct target_desc_info
{
  /* Returns true if this target description information has been supplied by
     the user.  */
  bool from_user_p ()
  { return !this->filename.empty (); }

  /* A flag indicating that a description has already been fetched
     from the target, so it should not be queried again.  */
  bool fetched = false;

  /* The description fetched from the target, or NULL if the target
     did not supply any description.  Only valid when
     FETCHED is set.  Only the description initialization
     code should access this; normally, the description should be
     accessed through the gdbarch object.  */
  const struct target_desc *tdesc = nullptr;

  /* If not empty, the filename to read a target description from, as set by
     "set tdesc filename ...".

     If empty, there is not filename specified by the user.  */
  std::string filename;
};

/* GDB represents the state of each program execution with an object
   called an inferior.  An inferior typically corresponds to a process
   but is more general and applies also to targets that do not have a
   notion of processes.  Each run of an executable creates a new
   inferior, as does each attachment to an existing process.
   Inferiors have unique internal identifiers that are different from
   target process ids.  Each inferior may in turn have multiple
   threads running in it.

   Inferiors are intrusively refcounted objects.  Unlike thread
   objects, being the user-selected inferior is considered a strong
   reference and is thus accounted for in the inferior object's
   refcount (see set_current_inferior).  When GDB needs to remember
   the selected inferior to later restore it, GDB temporarily bumps
   the inferior object's refcount, to prevent something deleting the
   inferior object before reverting back (e.g., due to a
   "remove-inferiors" command (see
   scoped_restore_current_inferior).  All other inferior
   references are considered weak references.  Inferiors are always
   listed exactly once in the inferior list, so placing an inferior in
   the inferior list is an implicit, not counted strong reference.  */

class inferior : public refcounted_object,
		 public intrusive_list_node<inferior>
{
public:
  explicit inferior (int pid);
  ~inferior ();

  /* Returns true if we can delete this inferior.  */
  bool deletable () const { return refcount () == 0; }

  /* Push T in this inferior's target stack.  */
  void push_target (struct target_ops *t)
  { m_target_stack.push (t); }

  /* An overload that deletes the target on failure.  */
  void push_target (target_ops_up &&t)
  {
    m_target_stack.push (t.get ());
    t.release ();
  }

  /* Unpush T from this inferior's target stack.  */
  int unpush_target (struct target_ops *t);

  /* Returns true if T is pushed in this inferior's target stack.  */
  bool target_is_pushed (const target_ops *t) const
  { return m_target_stack.is_pushed (t); }

  /* Find the target beneath T in this inferior's target stack.  */
  target_ops *find_target_beneath (const target_ops *t)
  { return m_target_stack.find_beneath (t); }

  /* Return the target at the top of this inferior's target stack.  */
  target_ops *top_target ()
  { return m_target_stack.top (); }

  /* Unpush all targets except the dummy target from m_target_stack.  As
     targets are removed from m_target_stack their reference count is
     decremented, which may cause a target to close.  */
  void pop_all_targets ()
  { pop_all_targets_above (dummy_stratum); }

  /* Unpush all targets above STRATUM from m_target_stack.  As targets are
     removed from m_target_stack their reference count is decremented,
     which may cause a target to close.  */
  void pop_all_targets_above (enum strata stratum);

  /* Unpush all targets at and above STRATUM from m_target_stack.  As
     targets are removed from m_target_stack their reference count is
     decremented, which may cause a target to close.  */
  void pop_all_targets_at_and_above (enum strata stratum);

  /* Return the target at process_stratum level in this inferior's
     target stack.  */
  struct process_stratum_target *process_target ()
  { return (process_stratum_target *) m_target_stack.at (process_stratum); }

  /* Return the target at STRATUM in this inferior's target stack.  */
  target_ops *target_at (enum strata stratum)
  { return m_target_stack.at (stratum); }

  bool has_execution ()
  { return target_has_execution (this); }

  /* This inferior's thread list, sorted by creation order.  */
  intrusive_list<thread_info> thread_list;

  /* A map of ptid_t to thread_info*, for average O(1) ptid_t lookup.
     Exited threads do not appear in the map.  */
  std::unordered_map<ptid_t, thread_info *, hash_ptid> ptid_thread_map;

  /* Returns a range adapter covering the inferior's threads,
     including exited threads.  Used like this:

       for (thread_info *thr : inf->threads ())
	 { .... }
  */
  inf_threads_range threads ()
  { return inf_threads_range (this->thread_list.begin ()); }

  /* Returns a range adapter covering the inferior's non-exited
     threads.  Used like this:

       for (thread_info *thr : inf->non_exited_threads ())
	 { .... }
  */
  inf_non_exited_threads_range non_exited_threads ()
  { return inf_non_exited_threads_range (this->thread_list.begin ()); }

  /* Like inferior::threads(), but returns a range adapter that can be
     used with range-for, safely.  I.e., it is safe to delete the
     currently-iterated thread, like this:

     for (thread_info *t : inf->threads_safe ())
       if (some_condition ())
	 delete f;
  */
  inline safe_inf_threads_range threads_safe ()
  { return safe_inf_threads_range (this->thread_list.begin ()); }

  /* Delete all threads in the thread list.  If SILENT, exit threads
     silently.  */
  void clear_thread_list (bool silent);

  /* Continuations-related methods.  A continuation is an std::function
     to be called to finish the execution of a command when running
     GDB asynchronously.  A continuation is executed after any thread
     of this inferior stops.  Continuations are used by the attach
     command and the remote target when a new inferior is detected.  */
  void add_continuation (std::function<void ()> &&cont);
  void do_all_continuations ();

  /* Set/get file name for default use for standard in/out in the inferior.

     On Unix systems, we try to make TERMINAL_NAME the inferior's controlling
     terminal.

     If TERMINAL_NAME is the empty string, then the inferior inherits GDB's
     terminal (or GDBserver's if spawning a remote process).  */
  void set_tty (std::string terminal_name);
  const std::string &tty ();

  /* Set the argument string to use when running this inferior.

     An empty string can be used to represent "no arguments".  */
  void set_args (std::string args)
  {
    m_args = std::move (args);
  };

  /* Get the argument string to use when running this inferior.

     No arguments is represented by an empty string.  */
  const std::string &args () const
  {
    return m_args;
  }

  /* Set the inferior current working directory.

     If CWD is empty, unset the directory.  */
  void set_cwd (std::string cwd)
  {
    m_cwd = std::move (cwd);
  }

  /* Get the inferior current working directory.

     Return an empty string if the current working directory is not
     specified.  */
  const std::string &cwd () const
  {
    return m_cwd;
  }

  /* Convenient handle (GDB inferior id).  Unique across all
     inferiors.  */
  int num = 0;

  /* Actual target inferior id, usually, a process id.  This matches
     the ptid_t.pid member of threads of this inferior.  */
  int pid = 0;
  /* True if the PID was actually faked by GDB.  */
  bool fake_pid_p = false;

  /* The highest thread number this inferior ever had.  */
  int highest_thread_num = 0;

  /* State of GDB control of inferior process execution.
     See `struct inferior_control_state'.  */
  inferior_control_state control;

  /* True if this was an auto-created inferior, e.g. created from
     following a fork; false, if this inferior was manually added by
     the user, and we should not attempt to prune it
     automatically.  */
  bool removable = false;

  /* The address space bound to this inferior.  */
  struct address_space *aspace = NULL;

  /* The program space bound to this inferior.  */
  struct program_space *pspace = NULL;

  /* The terminal state as set by the last target_terminal::terminal_*
     call.  */
  target_terminal_state terminal_state = target_terminal_state::is_ours;

  /* Environment to use for running inferior,
     in format described in environ.h.  */
  gdb_environ environment;

  /* True if this child process was attached rather than forked.  */
  bool attach_flag = false;

  /* If this inferior is a vfork child, then this is the pointer to
     its vfork parent, if GDB is still attached to it.  */
  inferior *vfork_parent = NULL;

  /* If this process is a vfork parent, this is the pointer to the
     child.  Since a vfork parent is left frozen by the kernel until
     the child execs or exits, a process can only have one vfork child
     at a given time.  */
  inferior *vfork_child = NULL;

  /* True if this inferior should be detached when it's vfork sibling
     exits or execs.  */
  bool pending_detach = false;

  /* If non-nullptr, points to a thread that called vfork and is now waiting
     for a vfork child not under our control to be done with the shared memory
     region, either by exiting or execing.  */
  thread_info *thread_waiting_for_vfork_done = nullptr;

  /* True if we're in the process of detaching from this inferior.  */
  bool detaching = false;

  /* True if setup_inferior wasn't called for this inferior yet.
     Until that is done, we must not access inferior memory or
     registers, as we haven't determined the target
     architecture/description.  */
  bool needs_setup = false;

  /* True if the inferior is starting up (inside startup_inferior),
     and we're nursing it along (through the shell) until it is ready
     to execute its first instruction.  Until that is done, we must
     not access inferior memory or registers, as we haven't determined
     the target architecture/description.  */
  bool starting_up = false;

  /* True when we are reading the library list of the inferior during an
     attach or handling a fork child.  */
  bool in_initial_library_scan = false;

  /* Private data used by the target vector implementation.  */
  std::unique_ptr<private_inferior> priv;

  /* HAS_EXIT_CODE is true if the inferior exited with an exit code.
     In this case, the EXIT_CODE field is also valid.  */
  bool has_exit_code = false;
  LONGEST exit_code = 0;

  /* Default flags to pass to the symbol reading functions.  These are
     used whenever a new objfile is created.  */
  symfile_add_flags symfile_flags = 0;

  /* Info about an inferior's target description (if it's fetched; the
     user supplied description's filename, if any; etc.).  */
  target_desc_info tdesc_info;

  /* The architecture associated with the inferior through the
     connection to the target.

     The architecture vector provides some information that is really
     a property of the inferior, accessed through a particular target:
     ptrace operations; the layout of certain RSP packets; the
     solib_ops vector; etc.  To differentiate architecture accesses to
     per-inferior/target properties from
     per-thread/per-frame/per-objfile properties, accesses to
     per-inferior/target properties should be made through
     this gdbarch.  */
  struct gdbarch *gdbarch = NULL;

  /* Data related to displaced stepping.  */
  displaced_step_inferior_state displaced_step_state;

  /* Per inferior data-pointers required by other GDB modules.  */
  registry<inferior> registry_fields;

private:

  /* Unpush TARGET and assert that it worked.  */
  void unpush_target_and_assert (struct target_ops *target);

  /* The inferior's target stack.  */
  target_stack m_target_stack;

  /* The name of terminal device to use for I/O.  */
  std::string m_terminal;

  /* The list of continuations.  */
  std::list<std::function<void ()>> m_continuations;

  /* The arguments string to use when running.  */
  std::string m_args;

  /* The current working directory that will be used when starting
     this inferior.  */
  std::string m_cwd;
};

/* Add an inferior to the inferior list, print a message that a new
   inferior is found, and return the pointer to the new inferior.
   Caller may use this pointer to initialize the private inferior
   data.  */
extern struct inferior *add_inferior (int pid);

/* Same as add_inferior, but don't print new inferior notifications to
   the CLI.  */
extern struct inferior *add_inferior_silent (int pid);

extern void delete_inferior (struct inferior *todel);

/* Delete an existing inferior list entry, due to inferior detaching.  */
extern void detach_inferior (inferior *inf);

extern void exit_inferior (inferior *inf);

extern void exit_inferior_silent (inferior *inf);

extern void exit_inferior_num_silent (int num);

extern void inferior_appeared (struct inferior *inf, int pid);

/* Search function to lookup an inferior of TARG by target 'pid'.  */
extern struct inferior *find_inferior_pid (process_stratum_target *targ,
					   int pid);

/* Search function to lookup an inferior of TARG whose pid is equal to
   'ptid.pid'. */
extern struct inferior *find_inferior_ptid (process_stratum_target *targ,
					    ptid_t ptid);

/* Search function to lookup an inferior by GDB 'num'.  */
extern struct inferior *find_inferior_id (int num);

/* Find an inferior bound to PSPACE, giving preference to the current
   inferior.  */
extern struct inferior *
  find_inferior_for_program_space (struct program_space *pspace);

/* Returns true if the inferior list is not empty.  */
extern int have_inferiors (void);

/* Returns the number of live inferiors running on PROC_TARGET (real
   live processes with execution).  */
extern int number_of_live_inferiors (process_stratum_target *proc_target);

/* Returns true if there are any live inferiors in the inferior list
   (not cores, not executables, real live processes).  */
extern int have_live_inferiors (void);

/* Save/restore the current inferior.  */

class scoped_restore_current_inferior
{
public:
  scoped_restore_current_inferior ()
    : m_saved_inf (current_inferior ())
  {}

  ~scoped_restore_current_inferior ()
  { set_current_inferior (m_saved_inf); }

  DISABLE_COPY_AND_ASSIGN (scoped_restore_current_inferior);

private:
  inferior *m_saved_inf;
};


/* Traverse all inferiors.  */

extern intrusive_list<inferior> inferior_list;

/* Pull in the internals of the inferiors ranges and iterators.  Must
   be done after struct inferior is defined.  */
#include "inferior-iter.h"

/* Return a range that can be used to walk over all inferiors
   inferiors, with range-for, safely.  I.e., it is safe to delete the
   currently-iterated inferior.  When combined with range-for, this
   allow convenient patterns like this:

     for (inferior *inf : all_inferiors_safe ())
       if (some_condition ())
	 delete inf;
*/

inline all_inferiors_safe_range
all_inferiors_safe ()
{
  return all_inferiors_safe_range (nullptr, inferior_list);
}

/* Returns a range representing all inferiors, suitable to use with
   range-for, like this:

   for (inferior *inf : all_inferiors ())
     [...]
*/

inline all_inferiors_range
all_inferiors (process_stratum_target *proc_target = nullptr)
{
  return all_inferiors_range (proc_target, inferior_list);
}

/* Return a range that can be used to walk over all inferiors with PID
   not zero, with range-for.  */

inline all_non_exited_inferiors_range
all_non_exited_inferiors (process_stratum_target *proc_target = nullptr)
{
  return all_non_exited_inferiors_range (proc_target, inferior_list);
}

/* Prune away automatically added inferiors that aren't required
   anymore.  */
extern void prune_inferiors (void);

extern int number_of_inferiors (void);

extern struct inferior *add_inferior_with_spaces (void);

/* Print the current selected inferior.  */
extern void print_selected_inferior (struct ui_out *uiout);

/* Switch to inferior NEW_INF, a new inferior, and unless
   NO_CONNECTION is true, push the process_stratum_target of ORG_INF
   to NEW_INF.  */

extern void switch_to_inferior_and_push_target
  (inferior *new_inf, bool no_connection, inferior *org_inf);

#endif /* !defined (INFERIOR_H) */
