/* Target-struct-independent code to start (run) and stop an inferior
   process.

   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
   1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include "gdb_string.h"
#include <ctype.h>
#include "symtab.h"
#include "frame.h"
#include "inferior.h"
#include "breakpoint.h"
#include "gdb_wait.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "cli/cli-script.h"
#include "target.h"
#include "gdbthread.h"
#include "annotate.h"
#include "symfile.h"
#include "top.h"
#include <signal.h>
#include "inf-loop.h"
#include "regcache.h"
#include "value.h"
#include "observer.h"
#include "language.h"
#include "gdb_assert.h"

/* Prototypes for local functions */

static void signals_info (char *, int);

static void handle_command (char *, int);

static void sig_print_info (enum target_signal);

static void sig_print_header (void);

static void resume_cleanups (void *);

static int hook_stop_stub (void *);

static void delete_breakpoint_current_contents (void *);

static int restore_selected_frame (void *);

static void build_infrun (void);

static int follow_fork (void);

static void set_schedlock_func (char *args, int from_tty,
				struct cmd_list_element *c);

struct execution_control_state;

static int currently_stepping (struct execution_control_state *ecs);

static void xdb_handle_command (char *args, int from_tty);

static int prepare_to_proceed (void);

void _initialize_infrun (void);

int inferior_ignoring_startup_exec_events = 0;
int inferior_ignoring_leading_exec_events = 0;

/* When set, stop the 'step' command if we enter a function which has
   no line number information.  The normal behavior is that we step
   over such function.  */
int step_stop_if_no_debug = 0;

/* In asynchronous mode, but simulating synchronous execution. */

int sync_execution = 0;

/* wait_for_inferior and normal_stop use this to notify the user
   when the inferior stopped in a different thread than it had been
   running in.  */

static ptid_t previous_inferior_ptid;

/* This is true for configurations that may follow through execl() and
   similar functions.  At present this is only true for HP-UX native.  */

#ifndef MAY_FOLLOW_EXEC
#define MAY_FOLLOW_EXEC (0)
#endif

static int may_follow_exec = MAY_FOLLOW_EXEC;

/* If the program uses ELF-style shared libraries, then calls to
   functions in shared libraries go through stubs, which live in a
   table called the PLT (Procedure Linkage Table).  The first time the
   function is called, the stub sends control to the dynamic linker,
   which looks up the function's real address, patches the stub so
   that future calls will go directly to the function, and then passes
   control to the function.

   If we are stepping at the source level, we don't want to see any of
   this --- we just want to skip over the stub and the dynamic linker.
   The simple approach is to single-step until control leaves the
   dynamic linker.

   However, on some systems (e.g., Red Hat's 5.2 distribution) the
   dynamic linker calls functions in the shared C library, so you
   can't tell from the PC alone whether the dynamic linker is still
   running.  In this case, we use a step-resume breakpoint to get us
   past the dynamic linker, as if we were using "next" to step over a
   function call.

   IN_SOLIB_DYNSYM_RESOLVE_CODE says whether we're in the dynamic
   linker code or not.  Normally, this means we single-step.  However,
   if SKIP_SOLIB_RESOLVER then returns non-zero, then its value is an
   address where we can place a step-resume breakpoint to get past the
   linker's symbol resolution function.

   IN_SOLIB_DYNSYM_RESOLVE_CODE can generally be implemented in a
   pretty portable way, by comparing the PC against the address ranges
   of the dynamic linker's sections.

   SKIP_SOLIB_RESOLVER is generally going to be system-specific, since
   it depends on internal details of the dynamic linker.  It's usually
   not too hard to figure out where to put a breakpoint, but it
   certainly isn't portable.  SKIP_SOLIB_RESOLVER should do plenty of
   sanity checking.  If it can't figure things out, returning zero and
   getting the (possibly confusing) stepping behavior is better than
   signalling an error, which will obscure the change in the
   inferior's state.  */

#ifndef IN_SOLIB_DYNSYM_RESOLVE_CODE
#define IN_SOLIB_DYNSYM_RESOLVE_CODE(pc) 0
#endif

/* This function returns TRUE if pc is the address of an instruction
   that lies within the dynamic linker (such as the event hook, or the
   dld itself).

   This function must be used only when a dynamic linker event has
   been caught, and the inferior is being stepped out of the hook, or
   undefined results are guaranteed.  */

#ifndef SOLIB_IN_DYNAMIC_LINKER
#define SOLIB_IN_DYNAMIC_LINKER(pid,pc) 0
#endif

/* On MIPS16, a function that returns a floating point value may call
   a library helper function to copy the return value to a floating point
   register.  The IGNORE_HELPER_CALL macro returns non-zero if we
   should ignore (i.e. step over) this function call.  */
#ifndef IGNORE_HELPER_CALL
#define IGNORE_HELPER_CALL(pc)	0
#endif

/* On some systems, the PC may be left pointing at an instruction that  won't
   actually be executed.  This is usually indicated by a bit in the PSW.  If
   we find ourselves in such a state, then we step the target beyond the
   nullified instruction before returning control to the user so as to avoid
   confusion. */

#ifndef INSTRUCTION_NULLIFIED
#define INSTRUCTION_NULLIFIED 0
#endif

/* We can't step off a permanent breakpoint in the ordinary way, because we
   can't remove it.  Instead, we have to advance the PC to the next
   instruction.  This macro should expand to a pointer to a function that
   does that, or zero if we have no such function.  If we don't have a
   definition for it, we have to report an error.  */
#ifndef SKIP_PERMANENT_BREAKPOINT
#define SKIP_PERMANENT_BREAKPOINT (default_skip_permanent_breakpoint)
static void
default_skip_permanent_breakpoint (void)
{
  error ("\
The program is stopped at a permanent breakpoint, but GDB does not know\n\
how to step past a permanent breakpoint on this architecture.  Try using\n\
a command like `return' or `jump' to continue execution.");
}
#endif


/* Convert the #defines into values.  This is temporary until wfi control
   flow is completely sorted out.  */

#ifndef HAVE_STEPPABLE_WATCHPOINT
#define HAVE_STEPPABLE_WATCHPOINT 0
#else
#undef  HAVE_STEPPABLE_WATCHPOINT
#define HAVE_STEPPABLE_WATCHPOINT 1
#endif

#ifndef CANNOT_STEP_HW_WATCHPOINTS
#define CANNOT_STEP_HW_WATCHPOINTS 0
#else
#undef  CANNOT_STEP_HW_WATCHPOINTS
#define CANNOT_STEP_HW_WATCHPOINTS 1
#endif

/* Tables of how to react to signals; the user sets them.  */

static unsigned char *signal_stop;
static unsigned char *signal_print;
static unsigned char *signal_program;

#define SET_SIGS(nsigs,sigs,flags) \
  do { \
    int signum = (nsigs); \
    while (signum-- > 0) \
      if ((sigs)[signum]) \
	(flags)[signum] = 1; \
  } while (0)

#define UNSET_SIGS(nsigs,sigs,flags) \
  do { \
    int signum = (nsigs); \
    while (signum-- > 0) \
      if ((sigs)[signum]) \
	(flags)[signum] = 0; \
  } while (0)

/* Value to pass to target_resume() to cause all threads to resume */

#define RESUME_ALL (pid_to_ptid (-1))

/* Command list pointer for the "stop" placeholder.  */

static struct cmd_list_element *stop_command;

/* Nonzero if breakpoints are now inserted in the inferior.  */

static int breakpoints_inserted;

/* Function inferior was in as of last step command.  */

static struct symbol *step_start_function;

/* Nonzero if we are expecting a trace trap and should proceed from it.  */

static int trap_expected;

#ifdef SOLIB_ADD
/* Nonzero if we want to give control to the user when we're notified
   of shared library events by the dynamic linker.  */
static int stop_on_solib_events;
#endif

#ifdef HP_OS_BUG
/* Nonzero if the next time we try to continue the inferior, it will
   step one instruction and generate a spurious trace trap.
   This is used to compensate for a bug in HP-UX.  */

static int trap_expected_after_continue;
#endif

/* Nonzero means expecting a trace trap
   and should stop the inferior and return silently when it happens.  */

int stop_after_trap;

/* Nonzero means expecting a trap and caller will handle it themselves.
   It is used after attach, due to attaching to a process;
   when running in the shell before the child program has been exec'd;
   and when running some kinds of remote stuff (FIXME?).  */

enum stop_kind stop_soon;

/* Nonzero if proceed is being used for a "finish" command or a similar
   situation when stop_registers should be saved.  */

int proceed_to_finish;

/* Save register contents here when about to pop a stack dummy frame,
   if-and-only-if proceed_to_finish is set.
   Thus this contains the return value from the called function (assuming
   values are returned in a register).  */

struct regcache *stop_registers;

/* Nonzero if program stopped due to error trying to insert breakpoints.  */

static int breakpoints_failed;

/* Nonzero after stop if current stack frame should be printed.  */

static int stop_print_frame;

static struct breakpoint *step_resume_breakpoint = NULL;
static struct breakpoint *through_sigtramp_breakpoint = NULL;

/* On some platforms (e.g., HP-UX), hardware watchpoints have bad
   interactions with an inferior that is running a kernel function
   (aka, a system call or "syscall").  wait_for_inferior therefore
   may have a need to know when the inferior is in a syscall.  This
   is a count of the number of inferior threads which are known to
   currently be running in a syscall. */
static int number_of_threads_in_syscalls;

/* This is a cached copy of the pid/waitstatus of the last event
   returned by target_wait()/target_wait_hook().  This information is
   returned by get_last_target_status(). */
static ptid_t target_last_wait_ptid;
static struct target_waitstatus target_last_waitstatus;

/* This is used to remember when a fork, vfork or exec event
   was caught by a catchpoint, and thus the event is to be
   followed at the next resume of the inferior, and not
   immediately. */
static struct
{
  enum target_waitkind kind;
  struct
  {
    int parent_pid;
    int child_pid;
  }
  fork_event;
  char *execd_pathname;
}
pending_follow;

static const char follow_fork_mode_child[] = "child";
static const char follow_fork_mode_parent[] = "parent";

static const char *follow_fork_mode_kind_names[] = {
  follow_fork_mode_child,
  follow_fork_mode_parent,
  NULL
};

static const char *follow_fork_mode_string = follow_fork_mode_parent;


static int
follow_fork (void)
{
  int follow_child = (follow_fork_mode_string == follow_fork_mode_child);

  return target_follow_fork (follow_child);
}

void
follow_inferior_reset_breakpoints (void)
{
  /* Was there a step_resume breakpoint?  (There was if the user
     did a "next" at the fork() call.)  If so, explicitly reset its
     thread number.

     step_resumes are a form of bp that are made to be per-thread.
     Since we created the step_resume bp when the parent process
     was being debugged, and now are switching to the child process,
     from the breakpoint package's viewpoint, that's a switch of
     "threads".  We must update the bp's notion of which thread
     it is for, or it'll be ignored when it triggers.  */

  if (step_resume_breakpoint)
    breakpoint_re_set_thread (step_resume_breakpoint);

  /* Reinsert all breakpoints in the child.  The user may have set
     breakpoints after catching the fork, in which case those
     were never set in the child, but only in the parent.  This makes
     sure the inserted breakpoints match the breakpoint list.  */

  breakpoint_re_set ();
  insert_breakpoints ();
}

/* EXECD_PATHNAME is assumed to be non-NULL. */

static void
follow_exec (int pid, char *execd_pathname)
{
  int saved_pid = pid;
  struct target_ops *tgt;

  if (!may_follow_exec)
    return;

  /* This is an exec event that we actually wish to pay attention to.
     Refresh our symbol table to the newly exec'd program, remove any
     momentary bp's, etc.

     If there are breakpoints, they aren't really inserted now,
     since the exec() transformed our inferior into a fresh set
     of instructions.

     We want to preserve symbolic breakpoints on the list, since
     we have hopes that they can be reset after the new a.out's
     symbol table is read.

     However, any "raw" breakpoints must be removed from the list
     (e.g., the solib bp's), since their address is probably invalid
     now.

     And, we DON'T want to call delete_breakpoints() here, since
     that may write the bp's "shadow contents" (the instruction
     value that was overwritten witha TRAP instruction).  Since
     we now have a new a.out, those shadow contents aren't valid. */
  update_breakpoints_after_exec ();

  /* If there was one, it's gone now.  We cannot truly step-to-next
     statement through an exec(). */
  step_resume_breakpoint = NULL;
  step_range_start = 0;
  step_range_end = 0;

  /* If there was one, it's gone now. */
  through_sigtramp_breakpoint = NULL;

  /* What is this a.out's name? */
  printf_unfiltered ("Executing new program: %s\n", execd_pathname);

  /* We've followed the inferior through an exec.  Therefore, the
     inferior has essentially been killed & reborn. */

  /* First collect the run target in effect.  */
  tgt = find_run_target ();
  /* If we can't find one, things are in a very strange state...  */
  if (tgt == NULL)
    error ("Could find run target to save before following exec");

  gdb_flush (gdb_stdout);
  target_mourn_inferior ();
  inferior_ptid = pid_to_ptid (saved_pid);
  /* Because mourn_inferior resets inferior_ptid. */
  push_target (tgt);

  /* That a.out is now the one to use. */
  exec_file_attach (execd_pathname, 0);

  /* And also is where symbols can be found. */
  symbol_file_add_main (execd_pathname, 0);

  /* Reset the shared library package.  This ensures that we get
     a shlib event when the child reaches "_start", at which point
     the dld will have had a chance to initialize the child. */
#if defined(SOLIB_RESTART)
  SOLIB_RESTART ();
#endif
#ifdef SOLIB_CREATE_INFERIOR_HOOK
  SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
#endif

  /* Reinsert all breakpoints.  (Those which were symbolic have
     been reset to the proper address in the new a.out, thanks
     to symbol_file_command...) */
  insert_breakpoints ();

  /* The next resume of this inferior should bring it to the shlib
     startup breakpoints.  (If the user had also set bp's on
     "main" from the old (parent) process, then they'll auto-
     matically get reset there in the new process.) */
}

/* Non-zero if we just simulating a single-step.  This is needed
   because we cannot remove the breakpoints in the inferior process
   until after the `wait' in `wait_for_inferior'.  */
static int singlestep_breakpoints_inserted_p = 0;

/* The thread we inserted single-step breakpoints for.  */
static ptid_t singlestep_ptid;

/* If another thread hit the singlestep breakpoint, we save the original
   thread here so that we can resume single-stepping it later.  */
static ptid_t saved_singlestep_ptid;
static int stepping_past_singlestep_breakpoint;


/* Things to clean up if we QUIT out of resume ().  */
static void
resume_cleanups (void *ignore)
{
  normal_stop ();
}

static const char schedlock_off[] = "off";
static const char schedlock_on[] = "on";
static const char schedlock_step[] = "step";
static const char *scheduler_mode = schedlock_off;
static const char *scheduler_enums[] = {
  schedlock_off,
  schedlock_on,
  schedlock_step,
  NULL
};

static void
set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
{
  /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones
     the set command passed as a parameter.  The clone operation will
     include (BUG?) any ``set'' command callback, if present.
     Commands like ``info set'' call all the ``show'' command
     callbacks.  Unfortunately, for ``show'' commands cloned from
     ``set'', this includes callbacks belonging to ``set'' commands.
     Making this worse, this only occures if add_show_from_set() is
     called after add_cmd_sfunc() (BUG?).  */
  if (cmd_type (c) == set_cmd)
    if (!target_can_lock_scheduler)
      {
	scheduler_mode = schedlock_off;
	error ("Target '%s' cannot support this command.", target_shortname);
      }
}


/* Resume the inferior, but allow a QUIT.  This is useful if the user
   wants to interrupt some lengthy single-stepping operation
   (for child processes, the SIGINT goes to the inferior, and so
   we get a SIGINT random_signal, but for remote debugging and perhaps
   other targets, that's not true).

   STEP nonzero if we should step (zero to continue instead).
   SIG is the signal to give the inferior (zero for none).  */
void
resume (int step, enum target_signal sig)
{
  int should_resume = 1;
  struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
  QUIT;

  /* FIXME: calling breakpoint_here_p (read_pc ()) three times! */


  /* Some targets (e.g. Solaris x86) have a kernel bug when stepping
     over an instruction that causes a page fault without triggering
     a hardware watchpoint. The kernel properly notices that it shouldn't
     stop, because the hardware watchpoint is not triggered, but it forgets
     the step request and continues the program normally.
     Work around the problem by removing hardware watchpoints if a step is
     requested, GDB will check for a hardware watchpoint trigger after the
     step anyway.  */
  if (CANNOT_STEP_HW_WATCHPOINTS && step && breakpoints_inserted)
    remove_hw_watchpoints ();


  /* Normally, by the time we reach `resume', the breakpoints are either
     removed or inserted, as appropriate.  The exception is if we're sitting
     at a permanent breakpoint; we need to step over it, but permanent
     breakpoints can't be removed.  So we have to test for it here.  */
  if (breakpoint_here_p (read_pc ()) == permanent_breakpoint_here)
    SKIP_PERMANENT_BREAKPOINT ();

  if (SOFTWARE_SINGLE_STEP_P () && step)
    {
      /* Do it the hard way, w/temp breakpoints */
      SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ );
      /* ...and don't ask hardware to do it.  */
      step = 0;
      /* and do not pull these breakpoints until after a `wait' in
         `wait_for_inferior' */
      singlestep_breakpoints_inserted_p = 1;
      singlestep_ptid = inferior_ptid;
    }

  /* Handle any optimized stores to the inferior NOW...  */
#ifdef DO_DEFERRED_STORES
  DO_DEFERRED_STORES;
#endif

  /* If there were any forks/vforks/execs that were caught and are
     now to be followed, then do so.  */
  switch (pending_follow.kind)
    {
    case TARGET_WAITKIND_FORKED:
    case TARGET_WAITKIND_VFORKED:
      pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
      if (follow_fork ())
	should_resume = 0;
      break;

    case TARGET_WAITKIND_EXECD:
      /* follow_exec is called as soon as the exec event is seen. */
      pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
      break;

    default:
      break;
    }

  /* Install inferior's terminal modes.  */
  target_terminal_inferior ();

  if (should_resume)
    {
      ptid_t resume_ptid;

      resume_ptid = RESUME_ALL;	/* Default */

      if ((step || singlestep_breakpoints_inserted_p) &&
	  (stepping_past_singlestep_breakpoint
	   || (!breakpoints_inserted && breakpoint_here_p (read_pc ()))))
	{
	  /* Stepping past a breakpoint without inserting breakpoints.
	     Make sure only the current thread gets to step, so that
	     other threads don't sneak past breakpoints while they are
	     not inserted. */

	  resume_ptid = inferior_ptid;
	}

      if ((scheduler_mode == schedlock_on) ||
	  (scheduler_mode == schedlock_step &&
	   (step || singlestep_breakpoints_inserted_p)))
	{
	  /* User-settable 'scheduler' mode requires solo thread resume. */
	  resume_ptid = inferior_ptid;
	}

      if (CANNOT_STEP_BREAKPOINT)
	{
	  /* Most targets can step a breakpoint instruction, thus
	     executing it normally.  But if this one cannot, just
	     continue and we will hit it anyway.  */
	  if (step && breakpoints_inserted && breakpoint_here_p (read_pc ()))
	    step = 0;
	}
      target_resume (resume_ptid, step, sig);
    }

  discard_cleanups (old_cleanups);
}


/* Clear out all variables saying what to do when inferior is continued.
   First do this, then set the ones you want, then call `proceed'.  */

void
clear_proceed_status (void)
{
  trap_expected = 0;
  step_range_start = 0;
  step_range_end = 0;
  step_frame_id = null_frame_id;
  step_over_calls = STEP_OVER_UNDEBUGGABLE;
  stop_after_trap = 0;
  stop_soon = NO_STOP_QUIETLY;
  proceed_to_finish = 0;
  breakpoint_proceeded = 1;	/* We're about to proceed... */

  /* Discard any remaining commands or status from previous stop.  */
  bpstat_clear (&stop_bpstat);
}

/* This should be suitable for any targets that support threads. */

static int
prepare_to_proceed (void)
{
  ptid_t wait_ptid;
  struct target_waitstatus wait_status;

  /* Get the last target status returned by target_wait().  */
  get_last_target_status (&wait_ptid, &wait_status);

  /* Make sure we were stopped either at a breakpoint, or because
     of a Ctrl-C.  */
  if (wait_status.kind != TARGET_WAITKIND_STOPPED
      || (wait_status.value.sig != TARGET_SIGNAL_TRAP &&
          wait_status.value.sig != TARGET_SIGNAL_INT))
    {
      return 0;
    }

  if (!ptid_equal (wait_ptid, minus_one_ptid)
      && !ptid_equal (inferior_ptid, wait_ptid))
    {
      /* Switched over from WAIT_PID.  */
      CORE_ADDR wait_pc = read_pc_pid (wait_ptid);

      if (wait_pc != read_pc ())
	{
	  /* Switch back to WAIT_PID thread.  */
	  inferior_ptid = wait_ptid;

	  /* FIXME: This stuff came from switch_to_thread() in
	     thread.c (which should probably be a public function).  */
	  flush_cached_frames ();
	  registers_changed ();
	  stop_pc = wait_pc;
	  select_frame (get_current_frame ());
	}

	/* We return 1 to indicate that there is a breakpoint here,
	   so we need to step over it before continuing to avoid
	   hitting it straight away. */
	if (breakpoint_here_p (wait_pc))
	   return 1;
    }

  return 0;
  
}

/* Record the pc of the program the last time it stopped.  This is
   just used internally by wait_for_inferior, but need to be preserved
   over calls to it and cleared when the inferior is started.  */
static CORE_ADDR prev_pc;

/* Basic routine for continuing the program in various fashions.

   ADDR is the address to resume at, or -1 for resume where stopped.
   SIGGNAL is the signal to give it, or 0 for none,
   or -1 for act according to how it stopped.
   STEP is nonzero if should trap after one instruction.
   -1 means return after that and print nothing.
   You should probably set various step_... variables
   before calling here, if you are stepping.

   You should call clear_proceed_status before calling proceed.  */

void
proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
{
  int oneproc = 0;

  if (step > 0)
    step_start_function = find_pc_function (read_pc ());
  if (step < 0)
    stop_after_trap = 1;

  if (addr == (CORE_ADDR) -1)
    {
      /* If there is a breakpoint at the address we will resume at,
         step one instruction before inserting breakpoints
         so that we do not stop right away (and report a second
         hit at this breakpoint).  */

      if (read_pc () == stop_pc && breakpoint_here_p (read_pc ()))
	oneproc = 1;

#ifndef STEP_SKIPS_DELAY
#define STEP_SKIPS_DELAY(pc) (0)
#define STEP_SKIPS_DELAY_P (0)
#endif
      /* Check breakpoint_here_p first, because breakpoint_here_p is fast
         (it just checks internal GDB data structures) and STEP_SKIPS_DELAY
         is slow (it needs to read memory from the target).  */
      if (STEP_SKIPS_DELAY_P
	  && breakpoint_here_p (read_pc () + 4)
	  && STEP_SKIPS_DELAY (read_pc ()))
	oneproc = 1;
    }
  else
    {
      write_pc (addr);
    }

  /* In a multi-threaded task we may select another thread
     and then continue or step.

     But if the old thread was stopped at a breakpoint, it
     will immediately cause another breakpoint stop without
     any execution (i.e. it will report a breakpoint hit
     incorrectly).  So we must step over it first.

     prepare_to_proceed checks the current thread against the thread
     that reported the most recent event.  If a step-over is required
     it returns TRUE and sets the current thread to the old thread. */
  if (prepare_to_proceed () && breakpoint_here_p (read_pc ()))
    oneproc = 1;

#ifdef HP_OS_BUG
  if (trap_expected_after_continue)
    {
      /* If (step == 0), a trap will be automatically generated after
         the first instruction is executed.  Force step one
         instruction to clear this condition.  This should not occur
         if step is nonzero, but it is harmless in that case.  */
      oneproc = 1;
      trap_expected_after_continue = 0;
    }
#endif /* HP_OS_BUG */

  if (oneproc)
    /* We will get a trace trap after one instruction.
       Continue it automatically and insert breakpoints then.  */
    trap_expected = 1;
  else
    {
      insert_breakpoints ();
      /* If we get here there was no call to error() in 
	 insert breakpoints -- so they were inserted.  */
      breakpoints_inserted = 1;
    }

  if (siggnal != TARGET_SIGNAL_DEFAULT)
    stop_signal = siggnal;
  /* If this signal should not be seen by program,
     give it zero.  Used for debugging signals.  */
  else if (!signal_program[stop_signal])
    stop_signal = TARGET_SIGNAL_0;

  annotate_starting ();

  /* Make sure that output from GDB appears before output from the
     inferior.  */
  gdb_flush (gdb_stdout);

  /* Refresh prev_pc value just prior to resuming.  This used to be
     done in stop_stepping, however, setting prev_pc there did not handle
     scenarios such as inferior function calls or returning from
     a function via the return command.  In those cases, the prev_pc
     value was not set properly for subsequent commands.  The prev_pc value 
     is used to initialize the starting line number in the ecs.  With an 
     invalid value, the gdb next command ends up stopping at the position
     represented by the next line table entry past our start position.
     On platforms that generate one line table entry per line, this
     is not a problem.  However, on the ia64, the compiler generates
     extraneous line table entries that do not increase the line number.
     When we issue the gdb next command on the ia64 after an inferior call
     or a return command, we often end up a few instructions forward, still 
     within the original line we started.

     An attempt was made to have init_execution_control_state () refresh
     the prev_pc value before calculating the line number.  This approach
     did not work because on platforms that use ptrace, the pc register
     cannot be read unless the inferior is stopped.  At that point, we
     are not guaranteed the inferior is stopped and so the read_pc ()
     call can fail.  Setting the prev_pc value here ensures the value is 
     updated correctly when the inferior is stopped.  */  
  prev_pc = read_pc ();

  /* Resume inferior.  */
  resume (oneproc || step || bpstat_should_step (), stop_signal);

  /* Wait for it to stop (if not standalone)
     and in any case decode why it stopped, and act accordingly.  */
  /* Do this only if we are not using the event loop, or if the target
     does not support asynchronous execution. */
  if (!event_loop_p || !target_can_async_p ())
    {
      wait_for_inferior ();
      normal_stop ();
    }
}


/* Start remote-debugging of a machine over a serial link.  */

void
start_remote (void)
{
  init_thread_list ();
  init_wait_for_inferior ();
  stop_soon = STOP_QUIETLY;
  trap_expected = 0;

  /* Always go on waiting for the target, regardless of the mode. */
  /* FIXME: cagney/1999-09-23: At present it isn't possible to
     indicate to wait_for_inferior that a target should timeout if
     nothing is returned (instead of just blocking).  Because of this,
     targets expecting an immediate response need to, internally, set
     things up so that the target_wait() is forced to eventually
     timeout. */
  /* FIXME: cagney/1999-09-24: It isn't possible for target_open() to
     differentiate to its caller what the state of the target is after
     the initial open has been performed.  Here we're assuming that
     the target has stopped.  It should be possible to eventually have
     target_open() return to the caller an indication that the target
     is currently running and GDB state should be set to the same as
     for an async run. */
  wait_for_inferior ();
  normal_stop ();
}

/* Initialize static vars when a new inferior begins.  */

void
init_wait_for_inferior (void)
{
  /* These are meaningless until the first time through wait_for_inferior.  */
  prev_pc = 0;

#ifdef HP_OS_BUG
  trap_expected_after_continue = 0;
#endif
  breakpoints_inserted = 0;
  breakpoint_init_inferior (inf_starting);

  /* Don't confuse first call to proceed(). */
  stop_signal = TARGET_SIGNAL_0;

  /* The first resume is not following a fork/vfork/exec. */
  pending_follow.kind = TARGET_WAITKIND_SPURIOUS;	/* I.e., none. */

  /* See wait_for_inferior's handling of SYSCALL_ENTRY/RETURN events. */
  number_of_threads_in_syscalls = 0;

  clear_proceed_status ();

  stepping_past_singlestep_breakpoint = 0;
}

static void
delete_breakpoint_current_contents (void *arg)
{
  struct breakpoint **breakpointp = (struct breakpoint **) arg;
  if (*breakpointp != NULL)
    {
      delete_breakpoint (*breakpointp);
      *breakpointp = NULL;
    }
}

/* This enum encodes possible reasons for doing a target_wait, so that
   wfi can call target_wait in one place.  (Ultimately the call will be
   moved out of the infinite loop entirely.) */

enum infwait_states
{
  infwait_normal_state,
  infwait_thread_hop_state,
  infwait_nullified_state,
  infwait_nonstep_watch_state
};

/* Why did the inferior stop? Used to print the appropriate messages
   to the interface from within handle_inferior_event(). */
enum inferior_stop_reason
{
  /* We don't know why. */
  STOP_UNKNOWN,
  /* Step, next, nexti, stepi finished. */
  END_STEPPING_RANGE,
  /* Found breakpoint. */
  BREAKPOINT_HIT,
  /* Inferior terminated by signal. */
  SIGNAL_EXITED,
  /* Inferior exited. */
  EXITED,
  /* Inferior received signal, and user asked to be notified. */
  SIGNAL_RECEIVED
};

/* This structure contains what used to be local variables in
   wait_for_inferior.  Probably many of them can return to being
   locals in handle_inferior_event.  */

struct execution_control_state
{
  struct target_waitstatus ws;
  struct target_waitstatus *wp;
  int another_trap;
  int random_signal;
  CORE_ADDR stop_func_start;
  CORE_ADDR stop_func_end;
  char *stop_func_name;
  struct symtab_and_line sal;
  int remove_breakpoints_on_following_step;
  int current_line;
  struct symtab *current_symtab;
  int handling_longjmp;		/* FIXME */
  ptid_t ptid;
  ptid_t saved_inferior_ptid;
  int update_step_sp;
  int stepping_through_solib_after_catch;
  bpstat stepping_through_solib_catchpoints;
  int enable_hw_watchpoints_after_wait;
  int stepping_through_sigtramp;
  int new_thread_event;
  struct target_waitstatus tmpstatus;
  enum infwait_states infwait_state;
  ptid_t waiton_ptid;
  int wait_some_more;
};

void init_execution_control_state (struct execution_control_state *ecs);

static void handle_step_into_function (struct execution_control_state *ecs);
void handle_inferior_event (struct execution_control_state *ecs);

static void check_sigtramp2 (struct execution_control_state *ecs);
static void step_into_function (struct execution_control_state *ecs);
static void step_over_function (struct execution_control_state *ecs);
static void stop_stepping (struct execution_control_state *ecs);
static void prepare_to_wait (struct execution_control_state *ecs);
static void keep_going (struct execution_control_state *ecs);
static void print_stop_reason (enum inferior_stop_reason stop_reason,
			       int stop_info);

/* Wait for control to return from inferior to debugger.
   If inferior gets a signal, we may decide to start it up again
   instead of returning.  That is why there is a loop in this function.
   When this function actually returns it means the inferior
   should be left stopped and GDB should read more commands.  */

void
wait_for_inferior (void)
{
  struct cleanup *old_cleanups;
  struct execution_control_state ecss;
  struct execution_control_state *ecs;

  old_cleanups = make_cleanup (delete_step_resume_breakpoint,
			       &step_resume_breakpoint);
  make_cleanup (delete_breakpoint_current_contents,
		&through_sigtramp_breakpoint);

  /* wfi still stays in a loop, so it's OK just to take the address of
     a local to get the ecs pointer.  */
  ecs = &ecss;

  /* Fill in with reasonable starting values.  */
  init_execution_control_state (ecs);

  /* We'll update this if & when we switch to a new thread. */
  previous_inferior_ptid = inferior_ptid;

  overlay_cache_invalid = 1;

  /* We have to invalidate the registers BEFORE calling target_wait
     because they can be loaded from the target while in target_wait.
     This makes remote debugging a bit more efficient for those
     targets that provide critical registers as part of their normal
     status mechanism. */

  registers_changed ();

  while (1)
    {
      if (target_wait_hook)
	ecs->ptid = target_wait_hook (ecs->waiton_ptid, ecs->wp);
      else
	ecs->ptid = target_wait (ecs->waiton_ptid, ecs->wp);

      /* Now figure out what to do with the result of the result.  */
      handle_inferior_event (ecs);

      if (!ecs->wait_some_more)
	break;
    }
  do_cleanups (old_cleanups);
}

/* Asynchronous version of wait_for_inferior. It is called by the
   event loop whenever a change of state is detected on the file
   descriptor corresponding to the target. It can be called more than
   once to complete a single execution command. In such cases we need
   to keep the state in a global variable ASYNC_ECSS. If it is the
   last time that this function is called for a single execution
   command, then report to the user that the inferior has stopped, and
   do the necessary cleanups. */

struct execution_control_state async_ecss;
struct execution_control_state *async_ecs;

void
fetch_inferior_event (void *client_data)
{
  static struct cleanup *old_cleanups;

  async_ecs = &async_ecss;

  if (!async_ecs->wait_some_more)
    {
      old_cleanups = make_exec_cleanup (delete_step_resume_breakpoint,
					&step_resume_breakpoint);
      make_exec_cleanup (delete_breakpoint_current_contents,
			 &through_sigtramp_breakpoint);

      /* Fill in with reasonable starting values.  */
      init_execution_control_state (async_ecs);

      /* We'll update this if & when we switch to a new thread. */
      previous_inferior_ptid = inferior_ptid;

      overlay_cache_invalid = 1;

      /* We have to invalidate the registers BEFORE calling target_wait
         because they can be loaded from the target while in target_wait.
         This makes remote debugging a bit more efficient for those
         targets that provide critical registers as part of their normal
         status mechanism. */

      registers_changed ();
    }

  if (target_wait_hook)
    async_ecs->ptid =
      target_wait_hook (async_ecs->waiton_ptid, async_ecs->wp);
  else
    async_ecs->ptid = target_wait (async_ecs->waiton_ptid, async_ecs->wp);

  /* Now figure out what to do with the result of the result.  */
  handle_inferior_event (async_ecs);

  if (!async_ecs->wait_some_more)
    {
      /* Do only the cleanups that have been added by this
         function. Let the continuations for the commands do the rest,
         if there are any. */
      do_exec_cleanups (old_cleanups);
      normal_stop ();
      if (step_multi && stop_step)
	inferior_event_handler (INF_EXEC_CONTINUE, NULL);
      else
	inferior_event_handler (INF_EXEC_COMPLETE, NULL);
    }
}

/* Prepare an execution control state for looping through a
   wait_for_inferior-type loop.  */

void
init_execution_control_state (struct execution_control_state *ecs)
{
  /* ecs->another_trap? */
  ecs->random_signal = 0;
  ecs->remove_breakpoints_on_following_step = 0;
  ecs->handling_longjmp = 0;	/* FIXME */
  ecs->update_step_sp = 0;
  ecs->stepping_through_solib_after_catch = 0;
  ecs->stepping_through_solib_catchpoints = NULL;
  ecs->enable_hw_watchpoints_after_wait = 0;
  ecs->stepping_through_sigtramp = 0;
  ecs->sal = find_pc_line (prev_pc, 0);
  ecs->current_line = ecs->sal.line;
  ecs->current_symtab = ecs->sal.symtab;
  ecs->infwait_state = infwait_normal_state;
  ecs->waiton_ptid = pid_to_ptid (-1);
  ecs->wp = &(ecs->ws);
}

/* Call this function before setting step_resume_breakpoint, as a
   sanity check.  There should never be more than one step-resume
   breakpoint per thread, so we should never be setting a new
   step_resume_breakpoint when one is already active.  */
static void
check_for_old_step_resume_breakpoint (void)
{
  if (step_resume_breakpoint)
    warning
      ("GDB bug: infrun.c (wait_for_inferior): dropping old step_resume breakpoint");
}

/* Return the cached copy of the last pid/waitstatus returned by
   target_wait()/target_wait_hook().  The data is actually cached by
   handle_inferior_event(), which gets called immediately after
   target_wait()/target_wait_hook().  */

void
get_last_target_status (ptid_t *ptidp, struct target_waitstatus *status)
{
  *ptidp = target_last_wait_ptid;
  *status = target_last_waitstatus;
}

/* Switch thread contexts, maintaining "infrun state". */

static void
context_switch (struct execution_control_state *ecs)
{
  /* Caution: it may happen that the new thread (or the old one!)
     is not in the thread list.  In this case we must not attempt
     to "switch context", or we run the risk that our context may
     be lost.  This may happen as a result of the target module
     mishandling thread creation.  */

  if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid))
    {				/* Perform infrun state context switch: */
      /* Save infrun state for the old thread.  */
      save_infrun_state (inferior_ptid, prev_pc,
			 trap_expected, step_resume_breakpoint,
			 through_sigtramp_breakpoint, step_range_start,
			 step_range_end, &step_frame_id,
			 ecs->handling_longjmp, ecs->another_trap,
			 ecs->stepping_through_solib_after_catch,
			 ecs->stepping_through_solib_catchpoints,
			 ecs->stepping_through_sigtramp,
			 ecs->current_line, ecs->current_symtab, step_sp);

      /* Load infrun state for the new thread.  */
      load_infrun_state (ecs->ptid, &prev_pc,
			 &trap_expected, &step_resume_breakpoint,
			 &through_sigtramp_breakpoint, &step_range_start,
			 &step_range_end, &step_frame_id,
			 &ecs->handling_longjmp, &ecs->another_trap,
			 &ecs->stepping_through_solib_after_catch,
			 &ecs->stepping_through_solib_catchpoints,
			 &ecs->stepping_through_sigtramp,
			 &ecs->current_line, &ecs->current_symtab, &step_sp);
    }
  inferior_ptid = ecs->ptid;
}

/* Wrapper for DEPRECATED_PC_IN_SIGTRAMP that takes care of the need
   to find the function's name.

   In a classic example of "left hand VS right hand", "infrun.c" was
   trying to improve GDB's performance by caching the result of calls
   to calls to find_pc_partial_funtion, while at the same time
   find_pc_partial_function was also trying to ramp up performance by
   caching its most recent return value.  The below makes the the
   function find_pc_partial_function solely responsibile for
   performance issues (the local cache that relied on a global
   variable - arrrggg - deleted).

   Using the testsuite and gcov, it was found that dropping the local
   "infrun.c" cache and instead relying on find_pc_partial_function
   increased the number of calls to 12000 (from 10000), but the number
   of times find_pc_partial_function's cache missed (this is what
   matters) was only increased by only 4 (to 3569).  (A quick back of
   envelope caculation suggests that the extra 2000 function calls
   @1000 extra instructions per call make the 1 MIP VAX testsuite run
   take two extra seconds, oops :-)

   Long term, this function can be eliminated, replaced by the code:
   get_frame_type(current_frame()) == SIGTRAMP_FRAME (for new
   architectures this is very cheap).  */

static int
pc_in_sigtramp (CORE_ADDR pc)
{
  char *name;
  find_pc_partial_function (pc, &name, NULL, NULL);
  return DEPRECATED_PC_IN_SIGTRAMP (pc, name);
}

/* Handle the inferior event in the cases when we just stepped
   into a function.  */

static void
handle_step_into_function (struct execution_control_state *ecs)
{
  CORE_ADDR real_stop_pc;

  if ((step_over_calls == STEP_OVER_NONE)
      || ((step_range_end == 1)
          && in_prologue (prev_pc, ecs->stop_func_start)))
    {
      /* I presume that step_over_calls is only 0 when we're
         supposed to be stepping at the assembly language level
         ("stepi").  Just stop.  */
      /* Also, maybe we just did a "nexti" inside a prolog,
         so we thought it was a subroutine call but it was not.
         Stop as well.  FENN */
      stop_step = 1;
      print_stop_reason (END_STEPPING_RANGE, 0);
      stop_stepping (ecs);
      return;
    }

  if (step_over_calls == STEP_OVER_ALL || IGNORE_HELPER_CALL (stop_pc))
    {
      /* We're doing a "next".  */

      if (legacy_frame_p (current_gdbarch)
	  && pc_in_sigtramp (stop_pc)
          && frame_id_inner (step_frame_id,
                             frame_id_build (read_sp (), 0)))
	/* NOTE: cagney/2004-03-15: This is only needed for legacy
	   systems.  On non-legacy systems step_over_function doesn't
	   use STEP_FRAME_ID and hence the below update "hack" isn't
	   needed.  */
        /* We stepped out of a signal handler, and into its calling
           trampoline.  This is misdetected as a subroutine call, but
           stepping over the signal trampoline isn't such a bad idea.
           In order to do that, we have to ignore the value in
           step_frame_id, since that doesn't represent the frame
           that'll reach when we return from the signal trampoline.
           Otherwise we'll probably continue to the end of the
           program.  */
        step_frame_id = null_frame_id;

      step_over_function (ecs);
      keep_going (ecs);
      return;
    }

  /* If we are in a function call trampoline (a stub between
     the calling routine and the real function), locate the real
     function.  That's what tells us (a) whether we want to step
     into it at all, and (b) what prologue we want to run to
     the end of, if we do step into it.  */
  real_stop_pc = skip_language_trampoline (stop_pc);
  if (real_stop_pc == 0)
    real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);
  if (real_stop_pc != 0)
    ecs->stop_func_start = real_stop_pc;

  /* If we have line number information for the function we
     are thinking of stepping into, step into it.

     If there are several symtabs at that PC (e.g. with include
     files), just want to know whether *any* of them have line
     numbers.  find_pc_line handles this.  */
  {
    struct symtab_and_line tmp_sal;

    tmp_sal = find_pc_line (ecs->stop_func_start, 0);
    if (tmp_sal.line != 0)
      {
        step_into_function (ecs);
        return;
      }
  }

  /* If we have no line number and the step-stop-if-no-debug
     is set, we stop the step so that the user has a chance to
     switch in assembly mode.  */
  if (step_over_calls == STEP_OVER_UNDEBUGGABLE && step_stop_if_no_debug)
    {
      stop_step = 1;
      print_stop_reason (END_STEPPING_RANGE, 0);
      stop_stepping (ecs);
      return;
    }

  step_over_function (ecs);
  keep_going (ecs);
  return;
}

static void
adjust_pc_after_break (struct execution_control_state *ecs)
{
  CORE_ADDR stop_pc;

  /* If this target does not decrement the PC after breakpoints, then
     we have nothing to do.  */
  if (DECR_PC_AFTER_BREAK == 0)
    return;

  /* If we've hit a breakpoint, we'll normally be stopped with SIGTRAP.  If
     we aren't, just return.

     We assume that waitkinds other than TARGET_WAITKIND_STOPPED are not
     affected by DECR_PC_AFTER_BREAK.  Other waitkinds which are implemented
     by software breakpoints should be handled through the normal breakpoint
     layer.
     
     NOTE drow/2004-01-31: On some targets, breakpoints may generate
     different signals (SIGILL or SIGEMT for instance), but it is less
     clear where the PC is pointing afterwards.  It may not match
     DECR_PC_AFTER_BREAK.  I don't know any specific target that generates
     these signals at breakpoints (the code has been in GDB since at least
     1992) so I can not guess how to handle them here.
     
     In earlier versions of GDB, a target with HAVE_NONSTEPPABLE_WATCHPOINTS
     would have the PC after hitting a watchpoint affected by
     DECR_PC_AFTER_BREAK.  I haven't found any target with both of these set
     in GDB history, and it seems unlikely to be correct, so
     HAVE_NONSTEPPABLE_WATCHPOINTS is not checked here.  */

  if (ecs->ws.kind != TARGET_WAITKIND_STOPPED)
    return;

  if (ecs->ws.value.sig != TARGET_SIGNAL_TRAP)
    return;

  /* Find the location where (if we've hit a breakpoint) the breakpoint would
     be.  */
  stop_pc = read_pc_pid (ecs->ptid) - DECR_PC_AFTER_BREAK;

  /* If we're software-single-stepping, then assume this is a breakpoint.
     NOTE drow/2004-01-17: This doesn't check that the PC matches, or that
     we're even in the right thread.  The software-single-step code needs
     some modernization.

     If we're not software-single-stepping, then we first check that there
     is an enabled software breakpoint at this address.  If there is, and
     we weren't using hardware-single-step, then we've hit the breakpoint.

     If we were using hardware-single-step, we check prev_pc; if we just
     stepped over an inserted software breakpoint, then we should decrement
     the PC and eventually report hitting the breakpoint.  The prev_pc check
     prevents us from decrementing the PC if we just stepped over a jump
     instruction and landed on the instruction after a breakpoint.

     The last bit checks that we didn't hit a breakpoint in a signal handler
     without an intervening stop in sigtramp, which is detected by a new
     stack pointer value below any usual function calling stack adjustments.

     NOTE drow/2004-01-17: I'm not sure that this is necessary.  The check
     predates checking for software single step at the same time.  Also,
     if we've moved into a signal handler we should have seen the
     signal.  */

  if ((SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
      || (software_breakpoint_inserted_here_p (stop_pc)
	  && !(currently_stepping (ecs)
	       && prev_pc != stop_pc
	       && !(step_range_end && INNER_THAN (read_sp (), (step_sp - 16))))))
    write_pc_pid (stop_pc, ecs->ptid);
}

/* Given an execution control state that has been freshly filled in
   by an event from the inferior, figure out what it means and take
   appropriate action.  */

void
handle_inferior_event (struct execution_control_state *ecs)
{
  /* NOTE: cagney/2003-03-28: If you're looking at this code and
     thinking that the variable stepped_after_stopped_by_watchpoint
     isn't used, then you're wrong!  The macro STOPPED_BY_WATCHPOINT,
     defined in the file "config/pa/nm-hppah.h", accesses the variable
     indirectly.  Mutter something rude about the HP merge.  */
  int stepped_after_stopped_by_watchpoint;
  int sw_single_step_trap_p = 0;

  /* Cache the last pid/waitstatus. */
  target_last_wait_ptid = ecs->ptid;
  target_last_waitstatus = *ecs->wp;

  adjust_pc_after_break (ecs);

  switch (ecs->infwait_state)
    {
    case infwait_thread_hop_state:
      /* Cancel the waiton_ptid. */
      ecs->waiton_ptid = pid_to_ptid (-1);
      /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event
         is serviced in this loop, below. */
      if (ecs->enable_hw_watchpoints_after_wait)
	{
	  TARGET_ENABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
	  ecs->enable_hw_watchpoints_after_wait = 0;
	}
      stepped_after_stopped_by_watchpoint = 0;
      break;

    case infwait_normal_state:
      /* See comments where a TARGET_WAITKIND_SYSCALL_RETURN event
         is serviced in this loop, below. */
      if (ecs->enable_hw_watchpoints_after_wait)
	{
	  TARGET_ENABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
	  ecs->enable_hw_watchpoints_after_wait = 0;
	}
      stepped_after_stopped_by_watchpoint = 0;
      break;

    case infwait_nullified_state:
      stepped_after_stopped_by_watchpoint = 0;
      break;

    case infwait_nonstep_watch_state:
      insert_breakpoints ();

      /* FIXME-maybe: is this cleaner than setting a flag?  Does it
         handle things like signals arriving and other things happening
         in combination correctly?  */
      stepped_after_stopped_by_watchpoint = 1;
      break;

    default:
      internal_error (__FILE__, __LINE__, "bad switch");
    }
  ecs->infwait_state = infwait_normal_state;

  flush_cached_frames ();

  /* If it's a new process, add it to the thread database */

  ecs->new_thread_event = (!ptid_equal (ecs->ptid, inferior_ptid)
			   && !in_thread_list (ecs->ptid));

  if (ecs->ws.kind != TARGET_WAITKIND_EXITED
      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event)
    {
      add_thread (ecs->ptid);

      ui_out_text (uiout, "[New ");
      ui_out_text (uiout, target_pid_or_tid_to_str (ecs->ptid));
      ui_out_text (uiout, "]\n");

#if 0
      /* NOTE: This block is ONLY meant to be invoked in case of a
         "thread creation event"!  If it is invoked for any other
         sort of event (such as a new thread landing on a breakpoint),
         the event will be discarded, which is almost certainly
         a bad thing!

         To avoid this, the low-level module (eg. target_wait)
         should call in_thread_list and add_thread, so that the
         new thread is known by the time we get here.  */

      /* We may want to consider not doing a resume here in order
         to give the user a chance to play with the new thread.
         It might be good to make that a user-settable option.  */

      /* At this point, all threads are stopped (happens
         automatically in either the OS or the native code).
         Therefore we need to continue all threads in order to
         make progress.  */

      target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
      prepare_to_wait (ecs);
      return;
#endif
    }

  switch (ecs->ws.kind)
    {
    case TARGET_WAITKIND_LOADED:
      /* Ignore gracefully during startup of the inferior, as it
         might be the shell which has just loaded some objects,
         otherwise add the symbols for the newly loaded objects.  */
#ifdef SOLIB_ADD
      if (stop_soon == NO_STOP_QUIETLY)
	{
	  /* Remove breakpoints, SOLIB_ADD might adjust
	     breakpoint addresses via breakpoint_re_set.  */
	  if (breakpoints_inserted)
	    remove_breakpoints ();

	  /* Check for any newly added shared libraries if we're
	     supposed to be adding them automatically.  Switch
	     terminal for any messages produced by
	     breakpoint_re_set.  */
	  target_terminal_ours_for_output ();
	  /* NOTE: cagney/2003-11-25: Make certain that the target
             stack's section table is kept up-to-date.  Architectures,
             (e.g., PPC64), use the section table to perform
             operations such as address => section name and hence
             require the table to contain all sections (including
             those found in shared libraries).  */
	  /* NOTE: cagney/2003-11-25: Pass current_target and not
             exec_ops to SOLIB_ADD.  This is because current GDB is
             only tooled to propagate section_table changes out from
             the "current_target" (see target_resize_to_sections), and
             not up from the exec stratum.  This, of course, isn't
             right.  "infrun.c" should only interact with the
             exec/process stratum, instead relying on the target stack
             to propagate relevant changes (stop, section table
             changed, ...) up to other layers.  */
	  SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
	  target_terminal_inferior ();

	  /* Reinsert breakpoints and continue.  */
	  if (breakpoints_inserted)
	    insert_breakpoints ();
	}
#endif
      resume (0, TARGET_SIGNAL_0);
      prepare_to_wait (ecs);
      return;

    case TARGET_WAITKIND_SPURIOUS:
      resume (0, TARGET_SIGNAL_0);
      prepare_to_wait (ecs);
      return;

    case TARGET_WAITKIND_EXITED:
      target_terminal_ours ();	/* Must do this before mourn anyway */
      print_stop_reason (EXITED, ecs->ws.value.integer);

      /* Record the exit code in the convenience variable $_exitcode, so
         that the user can inspect this again later.  */
      set_internalvar (lookup_internalvar ("_exitcode"),
		       value_from_longest (builtin_type_int,
					   (LONGEST) ecs->ws.value.integer));
      gdb_flush (gdb_stdout);
      target_mourn_inferior ();
      singlestep_breakpoints_inserted_p = 0;	/*SOFTWARE_SINGLE_STEP_P() */
      stop_print_frame = 0;
      stop_stepping (ecs);
      return;

    case TARGET_WAITKIND_SIGNALLED:
      stop_print_frame = 0;
      stop_signal = ecs->ws.value.sig;
      target_terminal_ours ();	/* Must do this before mourn anyway */

      /* Note: By definition of TARGET_WAITKIND_SIGNALLED, we shouldn't
         reach here unless the inferior is dead.  However, for years
         target_kill() was called here, which hints that fatal signals aren't
         really fatal on some systems.  If that's true, then some changes
         may be needed. */
      target_mourn_inferior ();

      print_stop_reason (SIGNAL_EXITED, stop_signal);
      singlestep_breakpoints_inserted_p = 0;	/*SOFTWARE_SINGLE_STEP_P() */
      stop_stepping (ecs);
      return;

      /* The following are the only cases in which we keep going;
         the above cases end in a continue or goto. */
    case TARGET_WAITKIND_FORKED:
    case TARGET_WAITKIND_VFORKED:
      stop_signal = TARGET_SIGNAL_TRAP;
      pending_follow.kind = ecs->ws.kind;

      pending_follow.fork_event.parent_pid = PIDGET (ecs->ptid);
      pending_follow.fork_event.child_pid = ecs->ws.value.related_pid;

      stop_pc = read_pc ();

      stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);

      ecs->random_signal = !bpstat_explains_signal (stop_bpstat);

      /* If no catchpoint triggered for this, then keep going.  */
      if (ecs->random_signal)
	{
	  stop_signal = TARGET_SIGNAL_0;
	  keep_going (ecs);
	  return;
	}
      goto process_event_stop_test;

    case TARGET_WAITKIND_EXECD:
      stop_signal = TARGET_SIGNAL_TRAP;

      /* NOTE drow/2002-12-05: This code should be pushed down into the
	 target_wait function.  Until then following vfork on HP/UX 10.20
	 is probably broken by this.  Of course, it's broken anyway.  */
      /* Is this a target which reports multiple exec events per actual
         call to exec()?  (HP-UX using ptrace does, for example.)  If so,
         ignore all but the last one.  Just resume the exec'r, and wait
         for the next exec event. */
      if (inferior_ignoring_leading_exec_events)
	{
	  inferior_ignoring_leading_exec_events--;
	  if (pending_follow.kind == TARGET_WAITKIND_VFORKED)
	    ENSURE_VFORKING_PARENT_REMAINS_STOPPED (pending_follow.fork_event.
						    parent_pid);
	  target_resume (ecs->ptid, 0, TARGET_SIGNAL_0);
	  prepare_to_wait (ecs);
	  return;
	}
      inferior_ignoring_leading_exec_events =
	target_reported_exec_events_per_exec_call () - 1;

      pending_follow.execd_pathname =
	savestring (ecs->ws.value.execd_pathname,
		    strlen (ecs->ws.value.execd_pathname));

      /* This causes the eventpoints and symbol table to be reset.  Must
         do this now, before trying to determine whether to stop. */
      follow_exec (PIDGET (inferior_ptid), pending_follow.execd_pathname);
      xfree (pending_follow.execd_pathname);

      stop_pc = read_pc_pid (ecs->ptid);
      ecs->saved_inferior_ptid = inferior_ptid;
      inferior_ptid = ecs->ptid;

      stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);

      ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
      inferior_ptid = ecs->saved_inferior_ptid;

      /* If no catchpoint triggered for this, then keep going.  */
      if (ecs->random_signal)
	{
	  stop_signal = TARGET_SIGNAL_0;
	  keep_going (ecs);
	  return;
	}
      goto process_event_stop_test;

      /* These syscall events are returned on HP-UX, as part of its
         implementation of page-protection-based "hardware" watchpoints.
         HP-UX has unfortunate interactions between page-protections and
         some system calls.  Our solution is to disable hardware watches
         when a system call is entered, and reenable them when the syscall
         completes.  The downside of this is that we may miss the precise
         point at which a watched piece of memory is modified.  "Oh well."

         Note that we may have multiple threads running, which may each
         enter syscalls at roughly the same time.  Since we don't have a
         good notion currently of whether a watched piece of memory is
         thread-private, we'd best not have any page-protections active
         when any thread is in a syscall.  Thus, we only want to reenable
         hardware watches when no threads are in a syscall.

         Also, be careful not to try to gather much state about a thread
         that's in a syscall.  It's frequently a losing proposition. */
    case TARGET_WAITKIND_SYSCALL_ENTRY:
      number_of_threads_in_syscalls++;
      if (number_of_threads_in_syscalls == 1)
	{
	  TARGET_DISABLE_HW_WATCHPOINTS (PIDGET (inferior_ptid));
	}
      resume (0, TARGET_SIGNAL_0);
      prepare_to_wait (ecs);
      return;

      /* Before examining the threads further, step this thread to
         get it entirely out of the syscall.  (We get notice of the
         event when the thread is just on the verge of exiting a
         syscall.  Stepping one instruction seems to get it back
         into user code.)

         Note that although the logical place to reenable h/w watches
         is here, we cannot.  We cannot reenable them before stepping
         the thread (this causes the next wait on the thread to hang).

         Nor can we enable them after stepping until we've done a wait.
         Thus, we simply set the flag ecs->enable_hw_watchpoints_after_wait
         here, which will be serviced immediately after the target
         is waited on. */
    case TARGET_WAITKIND_SYSCALL_RETURN:
      target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);

      if (number_of_threads_in_syscalls > 0)
	{
	  number_of_threads_in_syscalls--;
	  ecs->enable_hw_watchpoints_after_wait =
	    (number_of_threads_in_syscalls == 0);
	}
      prepare_to_wait (ecs);
      return;

    case TARGET_WAITKIND_STOPPED:
      stop_signal = ecs->ws.value.sig;
      break;

      /* We had an event in the inferior, but we are not interested
         in handling it at this level. The lower layers have already
         done what needs to be done, if anything.
	 
	 One of the possible circumstances for this is when the
	 inferior produces output for the console. The inferior has
	 not stopped, and we are ignoring the event.  Another possible
	 circumstance is any event which the lower level knows will be
	 reported multiple times without an intervening resume.  */
    case TARGET_WAITKIND_IGNORE:
      prepare_to_wait (ecs);
      return;
    }

  /* We may want to consider not doing a resume here in order to give
     the user a chance to play with the new thread.  It might be good
     to make that a user-settable option.  */

  /* At this point, all threads are stopped (happens automatically in
     either the OS or the native code).  Therefore we need to continue
     all threads in order to make progress.  */
  if (ecs->new_thread_event)
    {
      target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
      prepare_to_wait (ecs);
      return;
    }

  stop_pc = read_pc_pid (ecs->ptid);

  if (stepping_past_singlestep_breakpoint)
    {
      gdb_assert (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p);
      gdb_assert (ptid_equal (singlestep_ptid, ecs->ptid));
      gdb_assert (!ptid_equal (singlestep_ptid, saved_singlestep_ptid));

      stepping_past_singlestep_breakpoint = 0;

      /* We've either finished single-stepping past the single-step
	 breakpoint, or stopped for some other reason.  It would be nice if
	 we could tell, but we can't reliably.  */
      if (stop_signal == TARGET_SIGNAL_TRAP)
        {
	  /* Pull the single step breakpoints out of the target.  */
	  SOFTWARE_SINGLE_STEP (0, 0);
	  singlestep_breakpoints_inserted_p = 0;

	  ecs->random_signal = 0;

	  ecs->ptid = saved_singlestep_ptid;
	  context_switch (ecs);
	  if (context_hook)
	    context_hook (pid_to_thread_id (ecs->ptid));

	  resume (1, TARGET_SIGNAL_0);
	  prepare_to_wait (ecs);
	  return;
	}
    }

  stepping_past_singlestep_breakpoint = 0;

  /* See if a thread hit a thread-specific breakpoint that was meant for
     another thread.  If so, then step that thread past the breakpoint,
     and continue it.  */

  if (stop_signal == TARGET_SIGNAL_TRAP)
    {
      int thread_hop_needed = 0;

      /* Check if a regular breakpoint has been hit before checking
         for a potential single step breakpoint. Otherwise, GDB will
         not see this breakpoint hit when stepping onto breakpoints.  */
      if (breakpoints_inserted && breakpoint_here_p (stop_pc))
	{
	  ecs->random_signal = 0;
	  if (!breakpoint_thread_match (stop_pc, ecs->ptid))
	    thread_hop_needed = 1;
	}
      else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
	{
	  ecs->random_signal = 0;
	  /* The call to in_thread_list is necessary because PTIDs sometimes
	     change when we go from single-threaded to multi-threaded.  If
	     the singlestep_ptid is still in the list, assume that it is
	     really different from ecs->ptid.  */
	  if (!ptid_equal (singlestep_ptid, ecs->ptid)
	      && in_thread_list (singlestep_ptid))
	    {
	      thread_hop_needed = 1;
	      stepping_past_singlestep_breakpoint = 1;
	      saved_singlestep_ptid = singlestep_ptid;
	    }
	}

      if (thread_hop_needed)
	    {
	      int remove_status;

	      /* Saw a breakpoint, but it was hit by the wrong thread.
	         Just continue. */

	      if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
		{
		  /* Pull the single step breakpoints out of the target. */
		  SOFTWARE_SINGLE_STEP (0, 0);
		  singlestep_breakpoints_inserted_p = 0;
		}

	      remove_status = remove_breakpoints ();
	      /* Did we fail to remove breakpoints?  If so, try
	         to set the PC past the bp.  (There's at least
	         one situation in which we can fail to remove
	         the bp's: On HP-UX's that use ttrace, we can't
	         change the address space of a vforking child
	         process until the child exits (well, okay, not
	         then either :-) or execs. */
	      if (remove_status != 0)
		{
		  /* FIXME!  This is obviously non-portable! */
		  write_pc_pid (stop_pc + 4, ecs->ptid);
		  /* We need to restart all the threads now,
		   * unles we're running in scheduler-locked mode. 
		   * Use currently_stepping to determine whether to 
		   * step or continue.
		   */
		  /* FIXME MVS: is there any reason not to call resume()? */
		  if (scheduler_mode == schedlock_on)
		    target_resume (ecs->ptid,
				   currently_stepping (ecs), TARGET_SIGNAL_0);
		  else
		    target_resume (RESUME_ALL,
				   currently_stepping (ecs), TARGET_SIGNAL_0);
		  prepare_to_wait (ecs);
		  return;
		}
	      else
		{		/* Single step */
		  breakpoints_inserted = 0;
		  if (!ptid_equal (inferior_ptid, ecs->ptid))
		    context_switch (ecs);
		  ecs->waiton_ptid = ecs->ptid;
		  ecs->wp = &(ecs->ws);
		  ecs->another_trap = 1;

		  ecs->infwait_state = infwait_thread_hop_state;
		  keep_going (ecs);
		  registers_changed ();
		  return;
		}
	}
      else if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
        {
          sw_single_step_trap_p = 1;
          ecs->random_signal = 0;
        }
    }
  else
    ecs->random_signal = 1;

  /* See if something interesting happened to the non-current thread.  If
     so, then switch to that thread.  */
  if (!ptid_equal (ecs->ptid, inferior_ptid))
    {
      context_switch (ecs);

      if (context_hook)
	context_hook (pid_to_thread_id (ecs->ptid));

      flush_cached_frames ();
    }

  if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)
    {
      /* Pull the single step breakpoints out of the target. */
      SOFTWARE_SINGLE_STEP (0, 0);
      singlestep_breakpoints_inserted_p = 0;
    }

  /* If PC is pointing at a nullified instruction, then step beyond
     it so that the user won't be confused when GDB appears to be ready
     to execute it. */

  /*      if (INSTRUCTION_NULLIFIED && currently_stepping (ecs)) */
  if (INSTRUCTION_NULLIFIED)
    {
      registers_changed ();
      target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);

      /* We may have received a signal that we want to pass to
         the inferior; therefore, we must not clobber the waitstatus
         in WS. */

      ecs->infwait_state = infwait_nullified_state;
      ecs->waiton_ptid = ecs->ptid;
      ecs->wp = &(ecs->tmpstatus);
      prepare_to_wait (ecs);
      return;
    }

  /* It may not be necessary to disable the watchpoint to stop over
     it.  For example, the PA can (with some kernel cooperation)
     single step over a watchpoint without disabling the watchpoint.  */
  if (HAVE_STEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws))
    {
      resume (1, 0);
      prepare_to_wait (ecs);
      return;
    }

  /* It is far more common to need to disable a watchpoint to step
     the inferior over it.  FIXME.  What else might a debug
     register or page protection watchpoint scheme need here?  */
  if (HAVE_NONSTEPPABLE_WATCHPOINT && STOPPED_BY_WATCHPOINT (ecs->ws))
    {
      /* At this point, we are stopped at an instruction which has
         attempted to write to a piece of memory under control of
         a watchpoint.  The instruction hasn't actually executed
         yet.  If we were to evaluate the watchpoint expression
         now, we would get the old value, and therefore no change
         would seem to have occurred.

         In order to make watchpoints work `right', we really need
         to complete the memory write, and then evaluate the
         watchpoint expression.  The following code does that by
         removing the watchpoint (actually, all watchpoints and
         breakpoints), single-stepping the target, re-inserting
         watchpoints, and then falling through to let normal
         single-step processing handle proceed.  Since this
         includes evaluating watchpoints, things will come to a
         stop in the correct manner.  */

      remove_breakpoints ();
      registers_changed ();
      target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);	/* Single step */

      ecs->waiton_ptid = ecs->ptid;
      ecs->wp = &(ecs->ws);
      ecs->infwait_state = infwait_nonstep_watch_state;
      prepare_to_wait (ecs);
      return;
    }

  /* It may be possible to simply continue after a watchpoint.  */
  if (HAVE_CONTINUABLE_WATCHPOINT)
    STOPPED_BY_WATCHPOINT (ecs->ws);

  ecs->stop_func_start = 0;
  ecs->stop_func_end = 0;
  ecs->stop_func_name = 0;
  /* Don't care about return value; stop_func_start and stop_func_name
     will both be 0 if it doesn't work.  */
  find_pc_partial_function (stop_pc, &ecs->stop_func_name,
			    &ecs->stop_func_start, &ecs->stop_func_end);
  ecs->stop_func_start += FUNCTION_START_OFFSET;
  ecs->another_trap = 0;
  bpstat_clear (&stop_bpstat);
  stop_step = 0;
  stop_stack_dummy = 0;
  stop_print_frame = 1;
  ecs->random_signal = 0;
  stopped_by_random_signal = 0;
  breakpoints_failed = 0;

  /* Look at the cause of the stop, and decide what to do.
     The alternatives are:
     1) break; to really stop and return to the debugger,
     2) drop through to start up again
     (set ecs->another_trap to 1 to single step once)
     3) set ecs->random_signal to 1, and the decision between 1 and 2
     will be made according to the signal handling tables.  */

  /* First, distinguish signals caused by the debugger from signals
     that have to do with the program's own actions.  Note that
     breakpoint insns may cause SIGTRAP or SIGILL or SIGEMT, depending
     on the operating system version.  Here we detect when a SIGILL or
     SIGEMT is really a breakpoint and change it to SIGTRAP.  We do
     something similar for SIGSEGV, since a SIGSEGV will be generated
     when we're trying to execute a breakpoint instruction on a
     non-executable stack.  This happens for call dummy breakpoints
     for architectures like SPARC that place call dummies on the
     stack.  */

  if (stop_signal == TARGET_SIGNAL_TRAP
      || (breakpoints_inserted &&
	  (stop_signal == TARGET_SIGNAL_ILL
	   || stop_signal == TARGET_SIGNAL_SEGV
	   || stop_signal == TARGET_SIGNAL_EMT))
      || stop_soon == STOP_QUIETLY
      || stop_soon == STOP_QUIETLY_NO_SIGSTOP)
    {
      if (stop_signal == TARGET_SIGNAL_TRAP && stop_after_trap)
	{
	  stop_print_frame = 0;
	  stop_stepping (ecs);
	  return;
	}

      /* This is originated from start_remote(), start_inferior() and
         shared libraries hook functions.  */
      if (stop_soon == STOP_QUIETLY)
	{
	  stop_stepping (ecs);
	  return;
	}

      /* This originates from attach_command().  We need to overwrite
         the stop_signal here, because some kernels don't ignore a
         SIGSTOP in a subsequent ptrace(PTRACE_SONT,SOGSTOP) call.
         See more comments in inferior.h.  */
      if (stop_soon == STOP_QUIETLY_NO_SIGSTOP)
	{
	  stop_stepping (ecs);
	  if (stop_signal == TARGET_SIGNAL_STOP)
	    stop_signal = TARGET_SIGNAL_0;
	  return;
	}

      /* Don't even think about breakpoints
         if just proceeded over a breakpoint.

         However, if we are trying to proceed over a breakpoint
         and end up in sigtramp, then through_sigtramp_breakpoint
         will be set and we should check whether we've hit the
         step breakpoint.  */
      if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected
	  && through_sigtramp_breakpoint == NULL)
	bpstat_clear (&stop_bpstat);
      else
	{
	  /* See if there is a breakpoint at the current PC.  */
	  stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);

	  /* Following in case break condition called a
	     function.  */
	  stop_print_frame = 1;
	}

      /* NOTE: cagney/2003-03-29: These two checks for a random signal
	 at one stage in the past included checks for an inferior
	 function call's call dummy's return breakpoint.  The original
	 comment, that went with the test, read:

	 ``End of a stack dummy.  Some systems (e.g. Sony news) give
	 another signal besides SIGTRAP, so check here as well as
	 above.''

         If someone ever tries to get get call dummys on a
         non-executable stack to work (where the target would stop
         with something like a SIGSEGV), then those tests might need
         to be re-instated.  Given, however, that the tests were only
         enabled when momentary breakpoints were not being used, I
         suspect that it won't be the case.

	 NOTE: kettenis/2004-02-05: Indeed such checks don't seem to
	 be necessary for call dummies on a non-executable stack on
	 SPARC.  */

      if (stop_signal == TARGET_SIGNAL_TRAP)
	ecs->random_signal
	  = !(bpstat_explains_signal (stop_bpstat)
	      || trap_expected
	      || (step_range_end && step_resume_breakpoint == NULL));
      else
	{
	  ecs->random_signal = !bpstat_explains_signal (stop_bpstat);
	  if (!ecs->random_signal)
	    stop_signal = TARGET_SIGNAL_TRAP;
	}
    }

  /* When we reach this point, we've pretty much decided
     that the reason for stopping must've been a random
     (unexpected) signal. */

  else
    ecs->random_signal = 1;

process_event_stop_test:
  /* For the program's own signals, act according to
     the signal handling tables.  */

  if (ecs->random_signal)
    {
      /* Signal not for debugging purposes.  */
      int printed = 0;

      stopped_by_random_signal = 1;

      if (signal_print[stop_signal])
	{
	  printed = 1;
	  target_terminal_ours_for_output ();
	  print_stop_reason (SIGNAL_RECEIVED, stop_signal);
	}
      if (signal_stop[stop_signal])
	{
	  stop_stepping (ecs);
	  return;
	}
      /* If not going to stop, give terminal back
         if we took it away.  */
      else if (printed)
	target_terminal_inferior ();

      /* Clear the signal if it should not be passed.  */
      if (signal_program[stop_signal] == 0)
	stop_signal = TARGET_SIGNAL_0;

      /* I'm not sure whether this needs to be check_sigtramp2 or
         whether it could/should be keep_going.

         This used to jump to step_over_function if we are stepping,
         which is wrong.

         Suppose the user does a `next' over a function call, and while
         that call is in progress, the inferior receives a signal for
         which GDB does not stop (i.e., signal_stop[SIG] is false).  In
         that case, when we reach this point, there is already a
         step-resume breakpoint established, right where it should be:
         immediately after the function call the user is "next"-ing
         over.  If we call step_over_function now, two bad things
         happen:

         - we'll create a new breakpoint, at wherever the current
         frame's return address happens to be.  That could be
         anywhere, depending on what function call happens to be on
         the top of the stack at that point.  Point is, it's probably
         not where we need it.

         - the existing step-resume breakpoint (which is at the correct
         address) will get orphaned: step_resume_breakpoint will point
         to the new breakpoint, and the old step-resume breakpoint
         will never be cleaned up.

         The old behavior was meant to help HP-UX single-step out of
         sigtramps.  It would place the new breakpoint at prev_pc, which
         was certainly wrong.  I don't know the details there, so fixing
         this probably breaks that.  As with anything else, it's up to
         the HP-UX maintainer to furnish a fix that doesn't break other
         platforms.  --JimB, 20 May 1999 */
      check_sigtramp2 (ecs);
      keep_going (ecs);
      return;
    }

  /* Handle cases caused by hitting a breakpoint.  */
  {
    CORE_ADDR jmp_buf_pc;
    struct bpstat_what what;

    what = bpstat_what (stop_bpstat);

    if (what.call_dummy)
      {
	stop_stack_dummy = 1;
#ifdef HP_OS_BUG
	trap_expected_after_continue = 1;
#endif
      }

    switch (what.main_action)
      {
      case BPSTAT_WHAT_SET_LONGJMP_RESUME:
	/* If we hit the breakpoint at longjmp, disable it for the
	   duration of this command.  Then, install a temporary
	   breakpoint at the target of the jmp_buf. */
	disable_longjmp_breakpoint ();
	remove_breakpoints ();
	breakpoints_inserted = 0;
	if (!GET_LONGJMP_TARGET_P () || !GET_LONGJMP_TARGET (&jmp_buf_pc))
	  {
	    keep_going (ecs);
	    return;
	  }

	/* Need to blow away step-resume breakpoint, as it
	   interferes with us */
	if (step_resume_breakpoint != NULL)
	  {
	    delete_step_resume_breakpoint (&step_resume_breakpoint);
	  }
	/* Not sure whether we need to blow this away too, but probably
	   it is like the step-resume breakpoint.  */
	if (through_sigtramp_breakpoint != NULL)
	  {
	    delete_breakpoint (through_sigtramp_breakpoint);
	    through_sigtramp_breakpoint = NULL;
	  }

#if 0
	/* FIXME - Need to implement nested temporary breakpoints */
	if (step_over_calls > 0)
	  set_longjmp_resume_breakpoint (jmp_buf_pc, get_current_frame ());
	else
#endif /* 0 */
	  set_longjmp_resume_breakpoint (jmp_buf_pc, null_frame_id);
	ecs->handling_longjmp = 1;	/* FIXME */
	keep_going (ecs);
	return;

      case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
      case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE:
	remove_breakpoints ();
	breakpoints_inserted = 0;
#if 0
	/* FIXME - Need to implement nested temporary breakpoints */
	if (step_over_calls
	    && (frame_id_inner (get_frame_id (get_current_frame ()),
				step_frame_id)))
	  {
	    ecs->another_trap = 1;
	    keep_going (ecs);
	    return;
	  }
#endif /* 0 */
	disable_longjmp_breakpoint ();
	ecs->handling_longjmp = 0;	/* FIXME */
	if (what.main_action == BPSTAT_WHAT_CLEAR_LONGJMP_RESUME)
	  break;
	/* else fallthrough */

      case BPSTAT_WHAT_SINGLE:
	if (breakpoints_inserted)
	  {
	    remove_breakpoints ();
	  }
	breakpoints_inserted = 0;
	ecs->another_trap = 1;
	/* Still need to check other stuff, at least the case
	   where we are stepping and step out of the right range.  */
	break;

      case BPSTAT_WHAT_STOP_NOISY:
	stop_print_frame = 1;

	/* We are about to nuke the step_resume_breakpoint and
	   through_sigtramp_breakpoint via the cleanup chain, so
	   no need to worry about it here.  */

	stop_stepping (ecs);
	return;

      case BPSTAT_WHAT_STOP_SILENT:
	stop_print_frame = 0;

	/* We are about to nuke the step_resume_breakpoint and
	   through_sigtramp_breakpoint via the cleanup chain, so
	   no need to worry about it here.  */

	stop_stepping (ecs);
	return;

      case BPSTAT_WHAT_STEP_RESUME:
	/* This proably demands a more elegant solution, but, yeah
	   right...

	   This function's use of the simple variable
	   step_resume_breakpoint doesn't seem to accomodate
	   simultaneously active step-resume bp's, although the
	   breakpoint list certainly can.

	   If we reach here and step_resume_breakpoint is already
	   NULL, then apparently we have multiple active
	   step-resume bp's.  We'll just delete the breakpoint we
	   stopped at, and carry on.  

	   Correction: what the code currently does is delete a
	   step-resume bp, but it makes no effort to ensure that
	   the one deleted is the one currently stopped at.  MVS  */

	if (step_resume_breakpoint == NULL)
	  {
	    step_resume_breakpoint =
	      bpstat_find_step_resume_breakpoint (stop_bpstat);
	  }
	delete_step_resume_breakpoint (&step_resume_breakpoint);
	break;

      case BPSTAT_WHAT_THROUGH_SIGTRAMP:
	if (through_sigtramp_breakpoint)
	  delete_breakpoint (through_sigtramp_breakpoint);
	through_sigtramp_breakpoint = NULL;

	/* If were waiting for a trap, hitting the step_resume_break
	   doesn't count as getting it.  */
	if (trap_expected)
	  ecs->another_trap = 1;
	break;

      case BPSTAT_WHAT_CHECK_SHLIBS:
      case BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK:
#ifdef SOLIB_ADD
	{
	  /* Remove breakpoints, we eventually want to step over the
	     shlib event breakpoint, and SOLIB_ADD might adjust
	     breakpoint addresses via breakpoint_re_set.  */
	  if (breakpoints_inserted)
	    remove_breakpoints ();
	  breakpoints_inserted = 0;

	  /* Check for any newly added shared libraries if we're
	     supposed to be adding them automatically.  Switch
	     terminal for any messages produced by
	     breakpoint_re_set.  */
	  target_terminal_ours_for_output ();
	  /* NOTE: cagney/2003-11-25: Make certain that the target
             stack's section table is kept up-to-date.  Architectures,
             (e.g., PPC64), use the section table to perform
             operations such as address => section name and hence
             require the table to contain all sections (including
             those found in shared libraries).  */
	  /* NOTE: cagney/2003-11-25: Pass current_target and not
             exec_ops to SOLIB_ADD.  This is because current GDB is
             only tooled to propagate section_table changes out from
             the "current_target" (see target_resize_to_sections), and
             not up from the exec stratum.  This, of course, isn't
             right.  "infrun.c" should only interact with the
             exec/process stratum, instead relying on the target stack
             to propagate relevant changes (stop, section table
             changed, ...) up to other layers.  */
	  SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
	  target_terminal_inferior ();

	  /* Try to reenable shared library breakpoints, additional
	     code segments in shared libraries might be mapped in now. */
	  re_enable_breakpoints_in_shlibs ();

	  /* If requested, stop when the dynamic linker notifies
	     gdb of events.  This allows the user to get control
	     and place breakpoints in initializer routines for
	     dynamically loaded objects (among other things).  */
	  if (stop_on_solib_events || stop_stack_dummy)
	    {
	      stop_stepping (ecs);
	      return;
	    }

	  /* If we stopped due to an explicit catchpoint, then the
	     (see above) call to SOLIB_ADD pulled in any symbols
	     from a newly-loaded library, if appropriate.

	     We do want the inferior to stop, but not where it is
	     now, which is in the dynamic linker callback.  Rather,
	     we would like it stop in the user's program, just after
	     the call that caused this catchpoint to trigger.  That
	     gives the user a more useful vantage from which to
	     examine their program's state. */
	  else if (what.main_action ==
		   BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK)
	    {
	      /* ??rehrauer: If I could figure out how to get the
	         right return PC from here, we could just set a temp
	         breakpoint and resume.  I'm not sure we can without
	         cracking open the dld's shared libraries and sniffing
	         their unwind tables and text/data ranges, and that's
	         not a terribly portable notion.

	         Until that time, we must step the inferior out of the
	         dld callback, and also out of the dld itself (and any
	         code or stubs in libdld.sl, such as "shl_load" and
	         friends) until we reach non-dld code.  At that point,
	         we can stop stepping. */
	      bpstat_get_triggered_catchpoints (stop_bpstat,
						&ecs->
						stepping_through_solib_catchpoints);
	      ecs->stepping_through_solib_after_catch = 1;

	      /* Be sure to lift all breakpoints, so the inferior does
	         actually step past this point... */
	      ecs->another_trap = 1;
	      break;
	    }
	  else
	    {
	      /* We want to step over this breakpoint, then keep going.  */
	      ecs->another_trap = 1;
	      break;
	    }
	}
#endif
	break;

      case BPSTAT_WHAT_LAST:
	/* Not a real code, but listed here to shut up gcc -Wall.  */

      case BPSTAT_WHAT_KEEP_CHECKING:
	break;
      }
  }

  /* We come here if we hit a breakpoint but should not
     stop for it.  Possibly we also were stepping
     and should stop for that.  So fall through and
     test for stepping.  But, if not stepping,
     do not stop.  */

  /* Are we stepping to get the inferior out of the dynamic
     linker's hook (and possibly the dld itself) after catching
     a shlib event? */
  if (ecs->stepping_through_solib_after_catch)
    {
#if defined(SOLIB_ADD)
      /* Have we reached our destination?  If not, keep going. */
      if (SOLIB_IN_DYNAMIC_LINKER (PIDGET (ecs->ptid), stop_pc))
	{
	  ecs->another_trap = 1;
	  keep_going (ecs);
	  return;
	}
#endif
      /* Else, stop and report the catchpoint(s) whose triggering
         caused us to begin stepping. */
      ecs->stepping_through_solib_after_catch = 0;
      bpstat_clear (&stop_bpstat);
      stop_bpstat = bpstat_copy (ecs->stepping_through_solib_catchpoints);
      bpstat_clear (&ecs->stepping_through_solib_catchpoints);
      stop_print_frame = 1;
      stop_stepping (ecs);
      return;
    }

  if (step_resume_breakpoint)
    {
      /* Having a step-resume breakpoint overrides anything
         else having to do with stepping commands until
         that breakpoint is reached.  */
      /* I'm not sure whether this needs to be check_sigtramp2 or
         whether it could/should be keep_going.  */
      check_sigtramp2 (ecs);
      keep_going (ecs);
      return;
    }

  if (step_range_end == 0)
    {
      /* Likewise if we aren't even stepping.  */
      /* I'm not sure whether this needs to be check_sigtramp2 or
         whether it could/should be keep_going.  */
      check_sigtramp2 (ecs);
      keep_going (ecs);
      return;
    }

  /* If stepping through a line, keep going if still within it.

     Note that step_range_end is the address of the first instruction
     beyond the step range, and NOT the address of the last instruction
     within it! */
  if (stop_pc >= step_range_start && stop_pc < step_range_end)
    {
      /* We might be doing a BPSTAT_WHAT_SINGLE and getting a signal.
         So definately need to check for sigtramp here.  */
      check_sigtramp2 (ecs);
      keep_going (ecs);
      return;
    }

  /* We stepped out of the stepping range.  */

  /* If we are stepping at the source level and entered the runtime
     loader dynamic symbol resolution code, we keep on single stepping
     until we exit the run time loader code and reach the callee's
     address.  */
  if (step_over_calls == STEP_OVER_UNDEBUGGABLE
      && IN_SOLIB_DYNSYM_RESOLVE_CODE (stop_pc))
    {
      CORE_ADDR pc_after_resolver =
	gdbarch_skip_solib_resolver (current_gdbarch, stop_pc);

      if (pc_after_resolver)
	{
	  /* Set up a step-resume breakpoint at the address
	     indicated by SKIP_SOLIB_RESOLVER.  */
	  struct symtab_and_line sr_sal;
	  init_sal (&sr_sal);
	  sr_sal.pc = pc_after_resolver;

	  check_for_old_step_resume_breakpoint ();
	  step_resume_breakpoint =
	    set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
	  if (breakpoints_inserted)
	    insert_breakpoints ();
	}

      keep_going (ecs);
      return;
    }

  /* We can't update step_sp every time through the loop, because
     reading the stack pointer would slow down stepping too much.
     But we can update it every time we leave the step range.  */
  ecs->update_step_sp = 1;

  /* Did we just step into a singal trampoline (either by stepping out
     of a handler, or by taking a signal)?  */
  /* NOTE: cagney/2004-03-16: Replaced (except for legacy) a check for
     "pc_in_sigtramp(stop_pc) != pc_in_sigtramp(step_pc)" with
     frame_type == SIGTRAMP && !frame_id_eq.  The latter is far more
     robust as it will correctly handle nested signal trampolines.  */
  if (legacy_frame_p (current_gdbarch)
      ? (pc_in_sigtramp (stop_pc)
	 && !pc_in_sigtramp (prev_pc)
	 && INNER_THAN (read_sp (), step_sp))
      : (get_frame_type (get_current_frame ()) == SIGTRAMP_FRAME
	 && !frame_id_eq (get_frame_id (get_current_frame ()), step_frame_id)))
    {
      {
	struct frame_id current_frame = get_frame_id (get_current_frame ());

	if (frame_id_inner (current_frame, step_frame_id))
	  {
	    /* We have just taken a signal; go until we are back to
	       the point where we took it and one more.  */

	    /* This code is needed at least in the following case:
	       The user types "next" and then a signal arrives (before
	       the "next" is done).  */

	    /* Note that if we are stopped at a breakpoint, then we need
	       the step_resume breakpoint to override any breakpoints at
	       the same location, so that we will still step over the
	       breakpoint even though the signal happened.  */
	    struct symtab_and_line sr_sal;

	    init_sal (&sr_sal);
	    sr_sal.symtab = NULL;
	    sr_sal.line = 0;
	    sr_sal.pc = prev_pc;
	    /* We could probably be setting the frame to
	       step_frame_id; I don't think anyone thought to try it.  */
	    check_for_old_step_resume_breakpoint ();
	    step_resume_breakpoint =
	      set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
	    if (breakpoints_inserted)
	      insert_breakpoints ();
	  }
	else
	  {
	    /* We just stepped out of a signal handler and into
	       its calling trampoline.

	       Normally, we'd call step_over_function from
	       here, but for some reason GDB can't unwind the
	       stack correctly to find the real PC for the point
	       user code where the signal trampoline will return
	       -- FRAME_SAVED_PC fails, at least on HP-UX 10.20.
	       But signal trampolines are pretty small stubs of
	       code, anyway, so it's OK instead to just
	       single-step out.  Note: assuming such trampolines
	       don't exhibit recursion on any platform... */
	    find_pc_partial_function (stop_pc, &ecs->stop_func_name,
				      &ecs->stop_func_start,
				      &ecs->stop_func_end);
	    /* Readjust stepping range */
	    step_range_start = ecs->stop_func_start;
	    step_range_end = ecs->stop_func_end;
	    ecs->stepping_through_sigtramp = 1;
	  }
      }


      /* If this is stepi or nexti, make sure that the stepping range
         gets us past that instruction.  */
      if (step_range_end == 1)
	/* FIXME: Does this run afoul of the code below which, if
	   we step into the middle of a line, resets the stepping
	   range?  */
	step_range_end = (step_range_start = prev_pc) + 1;

      ecs->remove_breakpoints_on_following_step = 1;
      keep_going (ecs);
      return;
    }

  if (((stop_pc == ecs->stop_func_start	/* Quick test */
	|| in_prologue (stop_pc, ecs->stop_func_start))
       && !IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name))
      || IN_SOLIB_CALL_TRAMPOLINE (stop_pc, ecs->stop_func_name)
      || ecs->stop_func_name == 0)
    {
      /* It's a subroutine call.  */
      handle_step_into_function (ecs);
      return;
    }

  /* We've wandered out of the step range.  */

  ecs->sal = find_pc_line (stop_pc, 0);

  if (step_range_end == 1)
    {
      /* It is stepi or nexti.  We always want to stop stepping after
         one instruction.  */
      stop_step = 1;
      print_stop_reason (END_STEPPING_RANGE, 0);
      stop_stepping (ecs);
      return;
    }

  /* If we're in the return path from a shared library trampoline,
     we want to proceed through the trampoline when stepping.  */
  if (IN_SOLIB_RETURN_TRAMPOLINE (stop_pc, ecs->stop_func_name))
    {
      /* Determine where this trampoline returns.  */
      CORE_ADDR real_stop_pc = SKIP_TRAMPOLINE_CODE (stop_pc);

      /* Only proceed through if we know where it's going.  */
      if (real_stop_pc)
	{
	  /* And put the step-breakpoint there and go until there. */
	  struct symtab_and_line sr_sal;

	  init_sal (&sr_sal);	/* initialize to zeroes */
	  sr_sal.pc = real_stop_pc;
	  sr_sal.section = find_pc_overlay (sr_sal.pc);
	  /* Do not specify what the fp should be when we stop
	     since on some machines the prologue
	     is where the new fp value is established.  */
	  check_for_old_step_resume_breakpoint ();
	  step_resume_breakpoint =
	    set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
	  if (breakpoints_inserted)
	    insert_breakpoints ();

	  /* Restart without fiddling with the step ranges or
	     other state.  */
	  keep_going (ecs);
	  return;
	}
    }

  if (ecs->sal.line == 0)
    {
      /* We have no line number information.  That means to stop
         stepping (does this always happen right after one instruction,
         when we do "s" in a function with no line numbers,
         or can this happen as a result of a return or longjmp?).  */
      stop_step = 1;
      print_stop_reason (END_STEPPING_RANGE, 0);
      stop_stepping (ecs);
      return;
    }

  if ((stop_pc == ecs->sal.pc)
      && (ecs->current_line != ecs->sal.line
	  || ecs->current_symtab != ecs->sal.symtab))
    {
      /* We are at the start of a different line.  So stop.  Note that
         we don't stop if we step into the middle of a different line.
         That is said to make things like for (;;) statements work
         better.  */
      stop_step = 1;
      print_stop_reason (END_STEPPING_RANGE, 0);
      stop_stepping (ecs);
      return;
    }

  /* We aren't done stepping.

     Optimize by setting the stepping range to the line.
     (We might not be in the original line, but if we entered a
     new line in mid-statement, we continue stepping.  This makes
     things like for(;;) statements work better.)  */

  if (ecs->stop_func_end && ecs->sal.end >= ecs->stop_func_end)
    {
      /* If this is the last line of the function, don't keep stepping
         (it would probably step us out of the function).
         This is particularly necessary for a one-line function,
         in which after skipping the prologue we better stop even though
         we will be in mid-line.  */
      stop_step = 1;
      print_stop_reason (END_STEPPING_RANGE, 0);
      stop_stepping (ecs);
      return;
    }
  step_range_start = ecs->sal.pc;
  step_range_end = ecs->sal.end;
  step_frame_id = get_frame_id (get_current_frame ());
  ecs->current_line = ecs->sal.line;
  ecs->current_symtab = ecs->sal.symtab;

  /* In the case where we just stepped out of a function into the
     middle of a line of the caller, continue stepping, but
     step_frame_id must be modified to current frame */
#if 0
  /* NOTE: cagney/2003-10-16: I think this frame ID inner test is too
     generous.  It will trigger on things like a step into a frameless
     stackless leaf function.  I think the logic should instead look
     at the unwound frame ID has that should give a more robust
     indication of what happened.  */
     if (step-ID == current-ID)
       still stepping in same function;
     else if (step-ID == unwind (current-ID))
       stepped into a function;
     else
       stepped out of a function;
     /* Of course this assumes that the frame ID unwind code is robust
        and we're willing to introduce frame unwind logic into this
        function.  Fortunately, those days are nearly upon us.  */
#endif
  {
    struct frame_id current_frame = get_frame_id (get_current_frame ());
    if (!(frame_id_inner (current_frame, step_frame_id)))
      step_frame_id = current_frame;
  }

  keep_going (ecs);
}

/* Are we in the middle of stepping?  */

static int
currently_stepping (struct execution_control_state *ecs)
{
  return ((through_sigtramp_breakpoint == NULL
	   && !ecs->handling_longjmp
	   && ((step_range_end && step_resume_breakpoint == NULL)
	       || trap_expected))
	  || ecs->stepping_through_solib_after_catch
	  || bpstat_should_step ());
}

static void
check_sigtramp2 (struct execution_control_state *ecs)
{
  if (trap_expected
      && pc_in_sigtramp (stop_pc)
      && !pc_in_sigtramp (prev_pc)
      && INNER_THAN (read_sp (), step_sp))
    {
      /* What has happened here is that we have just stepped the
         inferior with a signal (because it is a signal which
         shouldn't make us stop), thus stepping into sigtramp.

         So we need to set a step_resume_break_address breakpoint and
         continue until we hit it, and then step.  FIXME: This should
         be more enduring than a step_resume breakpoint; we should
         know that we will later need to keep going rather than
         re-hitting the breakpoint here (see the testsuite,
         gdb.base/signals.exp where it says "exceedingly difficult").  */

      struct symtab_and_line sr_sal;

      init_sal (&sr_sal);	/* initialize to zeroes */
      sr_sal.pc = prev_pc;
      sr_sal.section = find_pc_overlay (sr_sal.pc);
      /* We perhaps could set the frame if we kept track of what the
         frame corresponding to prev_pc was.  But we don't, so don't.  */
      through_sigtramp_breakpoint =
	set_momentary_breakpoint (sr_sal, null_frame_id, bp_through_sigtramp);
      if (breakpoints_inserted)
	insert_breakpoints ();

      ecs->remove_breakpoints_on_following_step = 1;
      ecs->another_trap = 1;
    }
}

/* Subroutine call with source code we should not step over.  Do step
   to the first line of code in it.  */

static void
step_into_function (struct execution_control_state *ecs)
{
  struct symtab *s;
  struct symtab_and_line sr_sal;

  s = find_pc_symtab (stop_pc);
  if (s && s->language != language_asm)
    ecs->stop_func_start = SKIP_PROLOGUE (ecs->stop_func_start);

  ecs->sal = find_pc_line (ecs->stop_func_start, 0);
  /* Use the step_resume_break to step until the end of the prologue,
     even if that involves jumps (as it seems to on the vax under
     4.2).  */
  /* If the prologue ends in the middle of a source line, continue to
     the end of that source line (if it is still within the function).
     Otherwise, just go to end of prologue.  */
  if (ecs->sal.end
      && ecs->sal.pc != ecs->stop_func_start
      && ecs->sal.end < ecs->stop_func_end)
    ecs->stop_func_start = ecs->sal.end;

  /* Architectures which require breakpoint adjustment might not be able
     to place a breakpoint at the computed address.  If so, the test
     ``ecs->stop_func_start == stop_pc'' will never succeed.  Adjust
     ecs->stop_func_start to an address at which a breakpoint may be
     legitimately placed.
     
     Note:  kevinb/2004-01-19:  On FR-V, if this adjustment is not
     made, GDB will enter an infinite loop when stepping through
     optimized code consisting of VLIW instructions which contain
     subinstructions corresponding to different source lines.  On
     FR-V, it's not permitted to place a breakpoint on any but the
     first subinstruction of a VLIW instruction.  When a breakpoint is
     set, GDB will adjust the breakpoint address to the beginning of
     the VLIW instruction.  Thus, we need to make the corresponding
     adjustment here when computing the stop address.  */
     
  if (gdbarch_adjust_breakpoint_address_p (current_gdbarch))
    {
      ecs->stop_func_start
	= gdbarch_adjust_breakpoint_address (current_gdbarch,
	                                     ecs->stop_func_start);
    }

  if (ecs->stop_func_start == stop_pc)
    {
      /* We are already there: stop now.  */
      stop_step = 1;
      print_stop_reason (END_STEPPING_RANGE, 0);
      stop_stepping (ecs);
      return;
    }
  else
    {
      /* Put the step-breakpoint there and go until there.  */
      init_sal (&sr_sal);	/* initialize to zeroes */
      sr_sal.pc = ecs->stop_func_start;
      sr_sal.section = find_pc_overlay (ecs->stop_func_start);
      /* Do not specify what the fp should be when we stop since on
         some machines the prologue is where the new fp value is
         established.  */
      check_for_old_step_resume_breakpoint ();
      step_resume_breakpoint =
	set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
      if (breakpoints_inserted)
	insert_breakpoints ();

      /* And make sure stepping stops right away then.  */
      step_range_end = step_range_start;
    }
  keep_going (ecs);
}

/* We've just entered a callee, and we wish to resume until it returns
   to the caller.  Setting a step_resume breakpoint on the return
   address will catch a return from the callee.
     
   However, if the callee is recursing, we want to be careful not to
   catch returns of those recursive calls, but only of THIS instance
   of the caller.

   To do this, we set the step_resume bp's frame to our current
   caller's frame (obtained by doing a frame ID unwind).  */

static void
step_over_function (struct execution_control_state *ecs)
{
  struct symtab_and_line sr_sal;
  struct frame_id sr_id;

  init_sal (&sr_sal);		/* initialize to zeros */

  /* NOTE: cagney/2003-04-06:

     At this point the equality get_frame_pc() == get_frame_func()
     should hold.  This may make it possible for this code to tell the
     frame where it's function is, instead of the reverse.  This would
     avoid the need to search for the frame's function, which can get
     very messy when there is no debug info available (look at the
     heuristic find pc start code found in targets like the MIPS).  */

  /* NOTE: cagney/2003-04-06:

     The intent of DEPRECATED_SAVED_PC_AFTER_CALL was to:

     - provide a very light weight equivalent to frame_unwind_pc()
     (nee FRAME_SAVED_PC) that avoids the prologue analyzer

     - avoid handling the case where the PC hasn't been saved in the
     prologue analyzer

     Unfortunately, not five lines further down, is a call to
     get_frame_id() and that is guarenteed to trigger the prologue
     analyzer.
     
     The `correct fix' is for the prologe analyzer to handle the case
     where the prologue is incomplete (PC in prologue) and,
     consequently, the return pc has not yet been saved.  It should be
     noted that the prologue analyzer needs to handle this case
     anyway: frameless leaf functions that don't save the return PC;
     single stepping through a prologue.

     The d10v handles all this by bailing out of the prologue analsis
     when it reaches the current instruction.  */

  if (DEPRECATED_SAVED_PC_AFTER_CALL_P ())
    sr_sal.pc = ADDR_BITS_REMOVE (DEPRECATED_SAVED_PC_AFTER_CALL (get_current_frame ()));
  else
    sr_sal.pc = ADDR_BITS_REMOVE (frame_pc_unwind (get_current_frame ()));
  sr_sal.section = find_pc_overlay (sr_sal.pc);

  check_for_old_step_resume_breakpoint ();

  /* NOTE: cagney/2004-03-15: Code using the current value of
     "step_frame_id", instead of unwinding that frame ID, removed (at
     least for non-legacy platforms).  On s390 GNU/Linux, after taking
     a signal, the program is directly resumed at the signal handler
     and, consequently, the PC would point at at the first instruction
     of that signal handler but STEP_FRAME_ID would [incorrectly] at
     the interrupted code when it should point at the signal
     trampoline.  By always and locally doing a frame ID unwind, it's
     possible to assert that the code is always using the correct
     ID.  */
  if (legacy_frame_p (current_gdbarch))
    {
      if (frame_id_p (step_frame_id)
	  && !IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
	/* NOTE: cagney/2004-02-27: Use the global state's idea of the
	   stepping frame ID.  I suspect this is done as it is lighter
	   weight than a call to get_prev_frame.  */
	/* NOTE: cagney/2004-03-15: See comment above about how this
	   is also broken.  */
	sr_id = step_frame_id;
      else
	/* NOTE: cagney/2004-03-15: This is the way it was 'cos this
	   is the way it always was.  It should be using the unwound
	   (or caller's) ID, and not this (or the callee's) ID.  It
	   appeared to work because: legacy architectures used the
	   wrong end of the frame for the ID.stack (inner-most rather
	   than outer-most) so that the callee's id.stack (un
	   adjusted) matched the caller's id.stack giving the
	   "correct" id; more often than not
	   !IN_SOLIB_DYNSYM_RESOLVE_CODE and hence the code above (it
	   was originally later in the function) fixed the ID by using
	   global state.  */
	sr_id = get_frame_id (get_current_frame ());
    }
  else
    sr_id = get_frame_id (get_prev_frame (get_current_frame ()));

  step_resume_breakpoint = set_momentary_breakpoint (sr_sal, sr_id, bp_step_resume);

  if (breakpoints_inserted)
    insert_breakpoints ();
}

static void
stop_stepping (struct execution_control_state *ecs)
{
  /* Let callers know we don't want to wait for the inferior anymore.  */
  ecs->wait_some_more = 0;
}

/* This function handles various cases where we need to continue
   waiting for the inferior.  */
/* (Used to be the keep_going: label in the old wait_for_inferior) */

static void
keep_going (struct execution_control_state *ecs)
{
  /* Save the pc before execution, to compare with pc after stop.  */
  prev_pc = read_pc ();		/* Might have been DECR_AFTER_BREAK */

  if (ecs->update_step_sp)
    step_sp = read_sp ();
  ecs->update_step_sp = 0;

  /* If we did not do break;, it means we should keep running the
     inferior and not return to debugger.  */

  if (trap_expected && stop_signal != TARGET_SIGNAL_TRAP)
    {
      /* We took a signal (which we are supposed to pass through to
         the inferior, else we'd have done a break above) and we
         haven't yet gotten our trap.  Simply continue.  */
      resume (currently_stepping (ecs), stop_signal);
    }
  else
    {
      /* Either the trap was not expected, but we are continuing
         anyway (the user asked that this signal be passed to the
         child)
         -- or --
         The signal was SIGTRAP, e.g. it was our signal, but we
         decided we should resume from it.

         We're going to run this baby now!

         Insert breakpoints now, unless we are trying to one-proceed
         past a breakpoint.  */
      /* If we've just finished a special step resume and we don't
         want to hit a breakpoint, pull em out.  */
      if (step_resume_breakpoint == NULL
	  && through_sigtramp_breakpoint == NULL
	  && ecs->remove_breakpoints_on_following_step)
	{
	  ecs->remove_breakpoints_on_following_step = 0;
	  remove_breakpoints ();
	  breakpoints_inserted = 0;
	}
      else if (!breakpoints_inserted &&
	       (through_sigtramp_breakpoint != NULL || !ecs->another_trap))
	{
	  breakpoints_failed = insert_breakpoints ();
	  if (breakpoints_failed)
	    {
	      stop_stepping (ecs);
	      return;
	    }
	  breakpoints_inserted = 1;
	}

      trap_expected = ecs->another_trap;

      /* Do not deliver SIGNAL_TRAP (except when the user explicitly
         specifies that such a signal should be delivered to the
         target program).

         Typically, this would occure when a user is debugging a
         target monitor on a simulator: the target monitor sets a
         breakpoint; the simulator encounters this break-point and
         halts the simulation handing control to GDB; GDB, noteing
         that the break-point isn't valid, returns control back to the
         simulator; the simulator then delivers the hardware
         equivalent of a SIGNAL_TRAP to the program being debugged. */

      if (stop_signal == TARGET_SIGNAL_TRAP && !signal_program[stop_signal])
	stop_signal = TARGET_SIGNAL_0;


      resume (currently_stepping (ecs), stop_signal);
    }

  prepare_to_wait (ecs);
}

/* This function normally comes after a resume, before
   handle_inferior_event exits.  It takes care of any last bits of
   housekeeping, and sets the all-important wait_some_more flag.  */

static void
prepare_to_wait (struct execution_control_state *ecs)
{
  if (ecs->infwait_state == infwait_normal_state)
    {
      overlay_cache_invalid = 1;

      /* We have to invalidate the registers BEFORE calling
         target_wait because they can be loaded from the target while
         in target_wait.  This makes remote debugging a bit more
         efficient for those targets that provide critical registers
         as part of their normal status mechanism. */

      registers_changed ();
      ecs->waiton_ptid = pid_to_ptid (-1);
      ecs->wp = &(ecs->ws);
    }
  /* This is the old end of the while loop.  Let everybody know we
     want to wait for the inferior some more and get called again
     soon.  */
  ecs->wait_some_more = 1;
}

/* Print why the inferior has stopped. We always print something when
   the inferior exits, or receives a signal. The rest of the cases are
   dealt with later on in normal_stop() and print_it_typical().  Ideally
   there should be a call to this function from handle_inferior_event()
   each time stop_stepping() is called.*/
static void
print_stop_reason (enum inferior_stop_reason stop_reason, int stop_info)
{
  switch (stop_reason)
    {
    case STOP_UNKNOWN:
      /* We don't deal with these cases from handle_inferior_event()
         yet. */
      break;
    case END_STEPPING_RANGE:
      /* We are done with a step/next/si/ni command. */
      /* For now print nothing. */
      /* Print a message only if not in the middle of doing a "step n"
         operation for n > 1 */
      if (!step_multi || !stop_step)
	if (ui_out_is_mi_like_p (uiout))
	  ui_out_field_string (uiout, "reason", "end-stepping-range");
      break;
    case BREAKPOINT_HIT:
      /* We found a breakpoint. */
      /* For now print nothing. */
      break;
    case SIGNAL_EXITED:
      /* The inferior was terminated by a signal. */
      annotate_signalled ();
      if (ui_out_is_mi_like_p (uiout))
	ui_out_field_string (uiout, "reason", "exited-signalled");
      ui_out_text (uiout, "\nProgram terminated with signal ");
      annotate_signal_name ();
      ui_out_field_string (uiout, "signal-name",
			   target_signal_to_name (stop_info));
      annotate_signal_name_end ();
      ui_out_text (uiout, ", ");
      annotate_signal_string ();
      ui_out_field_string (uiout, "signal-meaning",
			   target_signal_to_string (stop_info));
      annotate_signal_string_end ();
      ui_out_text (uiout, ".\n");
      ui_out_text (uiout, "The program no longer exists.\n");
      break;
    case EXITED:
      /* The inferior program is finished. */
      annotate_exited (stop_info);
      if (stop_info)
	{
	  if (ui_out_is_mi_like_p (uiout))
	    ui_out_field_string (uiout, "reason", "exited");
	  ui_out_text (uiout, "\nProgram exited with code ");
	  ui_out_field_fmt (uiout, "exit-code", "0%o",
			    (unsigned int) stop_info);
	  ui_out_text (uiout, ".\n");
	}
      else
	{
	  if (ui_out_is_mi_like_p (uiout))
	    ui_out_field_string (uiout, "reason", "exited-normally");
	  ui_out_text (uiout, "\nProgram exited normally.\n");
	}
      break;
    case SIGNAL_RECEIVED:
      /* Signal received. The signal table tells us to print about
         it. */
      annotate_signal ();
      ui_out_text (uiout, "\nProgram received signal ");
      annotate_signal_name ();
      if (ui_out_is_mi_like_p (uiout))
	ui_out_field_string (uiout, "reason", "signal-received");
      ui_out_field_string (uiout, "signal-name",
			   target_signal_to_name (stop_info));
      annotate_signal_name_end ();
      ui_out_text (uiout, ", ");
      annotate_signal_string ();
      ui_out_field_string (uiout, "signal-meaning",
			   target_signal_to_string (stop_info));
      annotate_signal_string_end ();
      ui_out_text (uiout, ".\n");
      break;
    default:
      internal_error (__FILE__, __LINE__,
		      "print_stop_reason: unrecognized enum value");
      break;
    }
}


/* Here to return control to GDB when the inferior stops for real.
   Print appropriate messages, remove breakpoints, give terminal our modes.

   STOP_PRINT_FRAME nonzero means print the executing frame
   (pc, function, args, file, line number and line text).
   BREAKPOINTS_FAILED nonzero means stop was due to error
   attempting to insert breakpoints.  */

void
normal_stop (void)
{
  struct target_waitstatus last;
  ptid_t last_ptid;

  get_last_target_status (&last_ptid, &last);

  /* As with the notification of thread events, we want to delay
     notifying the user that we've switched thread context until
     the inferior actually stops.

     There's no point in saying anything if the inferior has exited.
     Note that SIGNALLED here means "exited with a signal", not
     "received a signal".  */
  if (!ptid_equal (previous_inferior_ptid, inferior_ptid)
      && target_has_execution
      && last.kind != TARGET_WAITKIND_SIGNALLED
      && last.kind != TARGET_WAITKIND_EXITED)
    {
      target_terminal_ours_for_output ();
      printf_filtered ("[Switching to %s]\n",
		       target_pid_or_tid_to_str (inferior_ptid));
      previous_inferior_ptid = inferior_ptid;
    }

  /* NOTE drow/2004-01-17: Is this still necessary?  */
  /* Make sure that the current_frame's pc is correct.  This
     is a correction for setting up the frame info before doing
     DECR_PC_AFTER_BREAK */
  if (target_has_execution)
    /* FIXME: cagney/2002-12-06: Has the PC changed?  Thanks to
       DECR_PC_AFTER_BREAK, the program counter can change.  Ask the
       frame code to check for this and sort out any resultant mess.
       DECR_PC_AFTER_BREAK needs to just go away.  */
    deprecated_update_frame_pc_hack (get_current_frame (), read_pc ());

  if (target_has_execution && breakpoints_inserted)
    {
      if (remove_breakpoints ())
	{
	  target_terminal_ours_for_output ();
	  printf_filtered ("Cannot remove breakpoints because ");
	  printf_filtered ("program is no longer writable.\n");
	  printf_filtered ("It might be running in another process.\n");
	  printf_filtered ("Further execution is probably impossible.\n");
	}
    }
  breakpoints_inserted = 0;

  /* Delete the breakpoint we stopped at, if it wants to be deleted.
     Delete any breakpoint that is to be deleted at the next stop.  */

  breakpoint_auto_delete (stop_bpstat);

  /* If an auto-display called a function and that got a signal,
     delete that auto-display to avoid an infinite recursion.  */

  if (stopped_by_random_signal)
    disable_current_display ();

  /* Don't print a message if in the middle of doing a "step n"
     operation for n > 1 */
  if (step_multi && stop_step)
    goto done;

  target_terminal_ours ();

  /* Look up the hook_stop and run it (CLI internally handles problem
     of stop_command's pre-hook not existing).  */
  if (stop_command)
    catch_errors (hook_stop_stub, stop_command,
		  "Error while running hook_stop:\n", RETURN_MASK_ALL);

  if (!target_has_stack)
    {

      goto done;
    }

  /* Select innermost stack frame - i.e., current frame is frame 0,
     and current location is based on that.
     Don't do this on return from a stack dummy routine,
     or if the program has exited. */

  if (!stop_stack_dummy)
    {
      select_frame (get_current_frame ());

      /* Print current location without a level number, if
         we have changed functions or hit a breakpoint.
         Print source line if we have one.
         bpstat_print() contains the logic deciding in detail
         what to print, based on the event(s) that just occurred. */

      if (stop_print_frame && deprecated_selected_frame)
	{
	  int bpstat_ret;
	  int source_flag;
	  int do_frame_printing = 1;

	  bpstat_ret = bpstat_print (stop_bpstat);
	  switch (bpstat_ret)
	    {
	    case PRINT_UNKNOWN:
	      /* FIXME: cagney/2002-12-01: Given that a frame ID does
		 (or should) carry around the function and does (or
		 should) use that when doing a frame comparison.  */
	      if (stop_step
		  && frame_id_eq (step_frame_id,
				  get_frame_id (get_current_frame ()))
		  && step_start_function == find_pc_function (stop_pc))
		source_flag = SRC_LINE;	/* finished step, just print source line */
	      else
		source_flag = SRC_AND_LOC;	/* print location and source line */
	      break;
	    case PRINT_SRC_AND_LOC:
	      source_flag = SRC_AND_LOC;	/* print location and source line */
	      break;
	    case PRINT_SRC_ONLY:
	      source_flag = SRC_LINE;
	      break;
	    case PRINT_NOTHING:
	      source_flag = SRC_LINE;	/* something bogus */
	      do_frame_printing = 0;
	      break;
	    default:
	      internal_error (__FILE__, __LINE__, "Unknown value.");
	    }
	  /* For mi, have the same behavior every time we stop:
	     print everything but the source line. */
	  if (ui_out_is_mi_like_p (uiout))
	    source_flag = LOC_AND_ADDRESS;

	  if (ui_out_is_mi_like_p (uiout))
	    ui_out_field_int (uiout, "thread-id",
			      pid_to_thread_id (inferior_ptid));
	  /* The behavior of this routine with respect to the source
	     flag is:
	     SRC_LINE: Print only source line
	     LOCATION: Print only location
	     SRC_AND_LOC: Print location and source line */
	  if (do_frame_printing)
	    print_stack_frame (deprecated_selected_frame, -1, source_flag);

	  /* Display the auto-display expressions.  */
	  do_displays ();
	}
    }

  /* Save the function value return registers, if we care.
     We might be about to restore their previous contents.  */
  if (proceed_to_finish)
    /* NB: The copy goes through to the target picking up the value of
       all the registers.  */
    regcache_cpy (stop_registers, current_regcache);

  if (stop_stack_dummy)
    {
      /* Pop the empty frame that contains the stack dummy.  POP_FRAME
         ends with a setting of the current frame, so we can use that
         next. */
      frame_pop (get_current_frame ());
      /* Set stop_pc to what it was before we called the function.
         Can't rely on restore_inferior_status because that only gets
         called if we don't stop in the called function.  */
      stop_pc = read_pc ();
      select_frame (get_current_frame ());
    }

done:
  annotate_stopped ();
  observer_notify_normal_stop ();
}

static int
hook_stop_stub (void *cmd)
{
  execute_cmd_pre_hook ((struct cmd_list_element *) cmd);
  return (0);
}

int
signal_stop_state (int signo)
{
  return signal_stop[signo];
}

int
signal_print_state (int signo)
{
  return signal_print[signo];
}

int
signal_pass_state (int signo)
{
  return signal_program[signo];
}

int
signal_stop_update (int signo, int state)
{
  int ret = signal_stop[signo];
  signal_stop[signo] = state;
  return ret;
}

int
signal_print_update (int signo, int state)
{
  int ret = signal_print[signo];
  signal_print[signo] = state;
  return ret;
}

int
signal_pass_update (int signo, int state)
{
  int ret = signal_program[signo];
  signal_program[signo] = state;
  return ret;
}

static void
sig_print_header (void)
{
  printf_filtered ("\
Signal        Stop\tPrint\tPass to program\tDescription\n");
}

static void
sig_print_info (enum target_signal oursig)
{
  char *name = target_signal_to_name (oursig);
  int name_padding = 13 - strlen (name);

  if (name_padding <= 0)
    name_padding = 0;

  printf_filtered ("%s", name);
  printf_filtered ("%*.*s ", name_padding, name_padding, "                 ");
  printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No");
  printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No");
  printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No");
  printf_filtered ("%s\n", target_signal_to_string (oursig));
}

/* Specify how various signals in the inferior should be handled.  */

static void
handle_command (char *args, int from_tty)
{
  char **argv;
  int digits, wordlen;
  int sigfirst, signum, siglast;
  enum target_signal oursig;
  int allsigs;
  int nsigs;
  unsigned char *sigs;
  struct cleanup *old_chain;

  if (args == NULL)
    {
      error_no_arg ("signal to handle");
    }

  /* Allocate and zero an array of flags for which signals to handle. */

  nsigs = (int) TARGET_SIGNAL_LAST;
  sigs = (unsigned char *) alloca (nsigs);
  memset (sigs, 0, nsigs);

  /* Break the command line up into args. */

  argv = buildargv (args);
  if (argv == NULL)
    {
      nomem (0);
    }
  old_chain = make_cleanup_freeargv (argv);

  /* Walk through the args, looking for signal oursigs, signal names, and
     actions.  Signal numbers and signal names may be interspersed with
     actions, with the actions being performed for all signals cumulatively
     specified.  Signal ranges can be specified as <LOW>-<HIGH>. */

  while (*argv != NULL)
    {
      wordlen = strlen (*argv);
      for (digits = 0; isdigit ((*argv)[digits]); digits++)
	{;
	}
      allsigs = 0;
      sigfirst = siglast = -1;

      if (wordlen >= 1 && !strncmp (*argv, "all", wordlen))
	{
	  /* Apply action to all signals except those used by the
	     debugger.  Silently skip those. */
	  allsigs = 1;
	  sigfirst = 0;
	  siglast = nsigs - 1;
	}
      else if (wordlen >= 1 && !strncmp (*argv, "stop", wordlen))
	{
	  SET_SIGS (nsigs, sigs, signal_stop);
	  SET_SIGS (nsigs, sigs, signal_print);
	}
      else if (wordlen >= 1 && !strncmp (*argv, "ignore", wordlen))
	{
	  UNSET_SIGS (nsigs, sigs, signal_program);
	}
      else if (wordlen >= 2 && !strncmp (*argv, "print", wordlen))
	{
	  SET_SIGS (nsigs, sigs, signal_print);
	}
      else if (wordlen >= 2 && !strncmp (*argv, "pass", wordlen))
	{
	  SET_SIGS (nsigs, sigs, signal_program);
	}
      else if (wordlen >= 3 && !strncmp (*argv, "nostop", wordlen))
	{
	  UNSET_SIGS (nsigs, sigs, signal_stop);
	}
      else if (wordlen >= 3 && !strncmp (*argv, "noignore", wordlen))
	{
	  SET_SIGS (nsigs, sigs, signal_program);
	}
      else if (wordlen >= 4 && !strncmp (*argv, "noprint", wordlen))
	{
	  UNSET_SIGS (nsigs, sigs, signal_print);
	  UNSET_SIGS (nsigs, sigs, signal_stop);
	}
      else if (wordlen >= 4 && !strncmp (*argv, "nopass", wordlen))
	{
	  UNSET_SIGS (nsigs, sigs, signal_program);
	}
      else if (digits > 0)
	{
	  /* It is numeric.  The numeric signal refers to our own
	     internal signal numbering from target.h, not to host/target
	     signal  number.  This is a feature; users really should be
	     using symbolic names anyway, and the common ones like
	     SIGHUP, SIGINT, SIGALRM, etc. will work right anyway.  */

	  sigfirst = siglast = (int)
	    target_signal_from_command (atoi (*argv));
	  if ((*argv)[digits] == '-')
	    {
	      siglast = (int)
		target_signal_from_command (atoi ((*argv) + digits + 1));
	    }
	  if (sigfirst > siglast)
	    {
	      /* Bet he didn't figure we'd think of this case... */
	      signum = sigfirst;
	      sigfirst = siglast;
	      siglast = signum;
	    }
	}
      else
	{
	  oursig = target_signal_from_name (*argv);
	  if (oursig != TARGET_SIGNAL_UNKNOWN)
	    {
	      sigfirst = siglast = (int) oursig;
	    }
	  else
	    {
	      /* Not a number and not a recognized flag word => complain.  */
	      error ("Unrecognized or ambiguous flag word: \"%s\".", *argv);
	    }
	}

      /* If any signal numbers or symbol names were found, set flags for
         which signals to apply actions to. */

      for (signum = sigfirst; signum >= 0 && signum <= siglast; signum++)
	{
	  switch ((enum target_signal) signum)
	    {
	    case TARGET_SIGNAL_TRAP:
	    case TARGET_SIGNAL_INT:
	      if (!allsigs && !sigs[signum])
		{
		  if (query ("%s is used by the debugger.\n\
Are you sure you want to change it? ", target_signal_to_name ((enum target_signal) signum)))
		    {
		      sigs[signum] = 1;
		    }
		  else
		    {
		      printf_unfiltered ("Not confirmed, unchanged.\n");
		      gdb_flush (gdb_stdout);
		    }
		}
	      break;
	    case TARGET_SIGNAL_0:
	    case TARGET_SIGNAL_DEFAULT:
	    case TARGET_SIGNAL_UNKNOWN:
	      /* Make sure that "all" doesn't print these.  */
	      break;
	    default:
	      sigs[signum] = 1;
	      break;
	    }
	}

      argv++;
    }

  target_notice_signals (inferior_ptid);

  if (from_tty)
    {
      /* Show the results.  */
      sig_print_header ();
      for (signum = 0; signum < nsigs; signum++)
	{
	  if (sigs[signum])
	    {
	      sig_print_info (signum);
	    }
	}
    }

  do_cleanups (old_chain);
}

static void
xdb_handle_command (char *args, int from_tty)
{
  char **argv;
  struct cleanup *old_chain;

  /* Break the command line up into args. */

  argv = buildargv (args);
  if (argv == NULL)
    {
      nomem (0);
    }
  old_chain = make_cleanup_freeargv (argv);
  if (argv[1] != (char *) NULL)
    {
      char *argBuf;
      int bufLen;

      bufLen = strlen (argv[0]) + 20;
      argBuf = (char *) xmalloc (bufLen);
      if (argBuf)
	{
	  int validFlag = 1;
	  enum target_signal oursig;

	  oursig = target_signal_from_name (argv[0]);
	  memset (argBuf, 0, bufLen);
	  if (strcmp (argv[1], "Q") == 0)
	    sprintf (argBuf, "%s %s", argv[0], "noprint");
	  else
	    {
	      if (strcmp (argv[1], "s") == 0)
		{
		  if (!signal_stop[oursig])
		    sprintf (argBuf, "%s %s", argv[0], "stop");
		  else
		    sprintf (argBuf, "%s %s", argv[0], "nostop");
		}
	      else if (strcmp (argv[1], "i") == 0)
		{
		  if (!signal_program[oursig])
		    sprintf (argBuf, "%s %s", argv[0], "pass");
		  else
		    sprintf (argBuf, "%s %s", argv[0], "nopass");
		}
	      else if (strcmp (argv[1], "r") == 0)
		{
		  if (!signal_print[oursig])
		    sprintf (argBuf, "%s %s", argv[0], "print");
		  else
		    sprintf (argBuf, "%s %s", argv[0], "noprint");
		}
	      else
		validFlag = 0;
	    }
	  if (validFlag)
	    handle_command (argBuf, from_tty);
	  else
	    printf_filtered ("Invalid signal handling flag.\n");
	  if (argBuf)
	    xfree (argBuf);
	}
    }
  do_cleanups (old_chain);
}

/* Print current contents of the tables set by the handle command.
   It is possible we should just be printing signals actually used
   by the current target (but for things to work right when switching
   targets, all signals should be in the signal tables).  */

static void
signals_info (char *signum_exp, int from_tty)
{
  enum target_signal oursig;
  sig_print_header ();

  if (signum_exp)
    {
      /* First see if this is a symbol name.  */
      oursig = target_signal_from_name (signum_exp);
      if (oursig == TARGET_SIGNAL_UNKNOWN)
	{
	  /* No, try numeric.  */
	  oursig =
	    target_signal_from_command (parse_and_eval_long (signum_exp));
	}
      sig_print_info (oursig);
      return;
    }

  printf_filtered ("\n");
  /* These ugly casts brought to you by the native VAX compiler.  */
  for (oursig = TARGET_SIGNAL_FIRST;
       (int) oursig < (int) TARGET_SIGNAL_LAST;
       oursig = (enum target_signal) ((int) oursig + 1))
    {
      QUIT;

      if (oursig != TARGET_SIGNAL_UNKNOWN
	  && oursig != TARGET_SIGNAL_DEFAULT && oursig != TARGET_SIGNAL_0)
	sig_print_info (oursig);
    }

  printf_filtered ("\nUse the \"handle\" command to change these tables.\n");
}

struct inferior_status
{
  enum target_signal stop_signal;
  CORE_ADDR stop_pc;
  bpstat stop_bpstat;
  int stop_step;
  int stop_stack_dummy;
  int stopped_by_random_signal;
  int trap_expected;
  CORE_ADDR step_range_start;
  CORE_ADDR step_range_end;
  struct frame_id step_frame_id;
  enum step_over_calls_kind step_over_calls;
  CORE_ADDR step_resume_break_address;
  int stop_after_trap;
  int stop_soon;
  struct regcache *stop_registers;

  /* These are here because if call_function_by_hand has written some
     registers and then decides to call error(), we better not have changed
     any registers.  */
  struct regcache *registers;

  /* A frame unique identifier.  */
  struct frame_id selected_frame_id;

  int breakpoint_proceeded;
  int restore_stack_info;
  int proceed_to_finish;
};

void
write_inferior_status_register (struct inferior_status *inf_status, int regno,
				LONGEST val)
{
  int size = DEPRECATED_REGISTER_RAW_SIZE (regno);
  void *buf = alloca (size);
  store_signed_integer (buf, size, val);
  regcache_raw_write (inf_status->registers, regno, buf);
}

/* Save all of the information associated with the inferior<==>gdb
   connection.  INF_STATUS is a pointer to a "struct inferior_status"
   (defined in inferior.h).  */

struct inferior_status *
save_inferior_status (int restore_stack_info)
{
  struct inferior_status *inf_status = XMALLOC (struct inferior_status);

  inf_status->stop_signal = stop_signal;
  inf_status->stop_pc = stop_pc;
  inf_status->stop_step = stop_step;
  inf_status->stop_stack_dummy = stop_stack_dummy;
  inf_status->stopped_by_random_signal = stopped_by_random_signal;
  inf_status->trap_expected = trap_expected;
  inf_status->step_range_start = step_range_start;
  inf_status->step_range_end = step_range_end;
  inf_status->step_frame_id = step_frame_id;
  inf_status->step_over_calls = step_over_calls;
  inf_status->stop_after_trap = stop_after_trap;
  inf_status->stop_soon = stop_soon;
  /* Save original bpstat chain here; replace it with copy of chain.
     If caller's caller is walking the chain, they'll be happier if we
     hand them back the original chain when restore_inferior_status is
     called.  */
  inf_status->stop_bpstat = stop_bpstat;
  stop_bpstat = bpstat_copy (stop_bpstat);
  inf_status->breakpoint_proceeded = breakpoint_proceeded;
  inf_status->restore_stack_info = restore_stack_info;
  inf_status->proceed_to_finish = proceed_to_finish;

  inf_status->stop_registers = regcache_dup_no_passthrough (stop_registers);

  inf_status->registers = regcache_dup (current_regcache);

  inf_status->selected_frame_id = get_frame_id (deprecated_selected_frame);
  return inf_status;
}

static int
restore_selected_frame (void *args)
{
  struct frame_id *fid = (struct frame_id *) args;
  struct frame_info *frame;

  frame = frame_find_by_id (*fid);

  /* If inf_status->selected_frame_id is NULL, there was no previously
     selected frame.  */
  if (frame == NULL)
    {
      warning ("Unable to restore previously selected frame.\n");
      return 0;
    }

  select_frame (frame);

  return (1);
}

void
restore_inferior_status (struct inferior_status *inf_status)
{
  stop_signal = inf_status->stop_signal;
  stop_pc = inf_status->stop_pc;
  stop_step = inf_status->stop_step;
  stop_stack_dummy = inf_status->stop_stack_dummy;
  stopped_by_random_signal = inf_status->stopped_by_random_signal;
  trap_expected = inf_status->trap_expected;
  step_range_start = inf_status->step_range_start;
  step_range_end = inf_status->step_range_end;
  step_frame_id = inf_status->step_frame_id;
  step_over_calls = inf_status->step_over_calls;
  stop_after_trap = inf_status->stop_after_trap;
  stop_soon = inf_status->stop_soon;
  bpstat_clear (&stop_bpstat);
  stop_bpstat = inf_status->stop_bpstat;
  breakpoint_proceeded = inf_status->breakpoint_proceeded;
  proceed_to_finish = inf_status->proceed_to_finish;

  /* FIXME: Is the restore of stop_registers always needed. */
  regcache_xfree (stop_registers);
  stop_registers = inf_status->stop_registers;

  /* The inferior can be gone if the user types "print exit(0)"
     (and perhaps other times).  */
  if (target_has_execution)
    /* NB: The register write goes through to the target.  */
    regcache_cpy (current_regcache, inf_status->registers);
  regcache_xfree (inf_status->registers);

  /* FIXME: If we are being called after stopping in a function which
     is called from gdb, we should not be trying to restore the
     selected frame; it just prints a spurious error message (The
     message is useful, however, in detecting bugs in gdb (like if gdb
     clobbers the stack)).  In fact, should we be restoring the
     inferior status at all in that case?  .  */

  if (target_has_stack && inf_status->restore_stack_info)
    {
      /* The point of catch_errors is that if the stack is clobbered,
         walking the stack might encounter a garbage pointer and
         error() trying to dereference it.  */
      if (catch_errors
	  (restore_selected_frame, &inf_status->selected_frame_id,
	   "Unable to restore previously selected frame:\n",
	   RETURN_MASK_ERROR) == 0)
	/* Error in restoring the selected frame.  Select the innermost
	   frame.  */
	select_frame (get_current_frame ());

    }

  xfree (inf_status);
}

static void
do_restore_inferior_status_cleanup (void *sts)
{
  restore_inferior_status (sts);
}

struct cleanup *
make_cleanup_restore_inferior_status (struct inferior_status *inf_status)
{
  return make_cleanup (do_restore_inferior_status_cleanup, inf_status);
}

void
discard_inferior_status (struct inferior_status *inf_status)
{
  /* See save_inferior_status for info on stop_bpstat. */
  bpstat_clear (&inf_status->stop_bpstat);
  regcache_xfree (inf_status->registers);
  regcache_xfree (inf_status->stop_registers);
  xfree (inf_status);
}

int
inferior_has_forked (int pid, int *child_pid)
{
  struct target_waitstatus last;
  ptid_t last_ptid;

  get_last_target_status (&last_ptid, &last);

  if (last.kind != TARGET_WAITKIND_FORKED)
    return 0;

  if (ptid_get_pid (last_ptid) != pid)
    return 0;

  *child_pid = last.value.related_pid;
  return 1;
}

int
inferior_has_vforked (int pid, int *child_pid)
{
  struct target_waitstatus last;
  ptid_t last_ptid;

  get_last_target_status (&last_ptid, &last);

  if (last.kind != TARGET_WAITKIND_VFORKED)
    return 0;

  if (ptid_get_pid (last_ptid) != pid)
    return 0;

  *child_pid = last.value.related_pid;
  return 1;
}

int
inferior_has_execd (int pid, char **execd_pathname)
{
  struct target_waitstatus last;
  ptid_t last_ptid;

  get_last_target_status (&last_ptid, &last);

  if (last.kind != TARGET_WAITKIND_EXECD)
    return 0;

  if (ptid_get_pid (last_ptid) != pid)
    return 0;

  *execd_pathname = xstrdup (last.value.execd_pathname);
  return 1;
}

/* Oft used ptids */
ptid_t null_ptid;
ptid_t minus_one_ptid;

/* Create a ptid given the necessary PID, LWP, and TID components.  */

ptid_t
ptid_build (int pid, long lwp, long tid)
{
  ptid_t ptid;

  ptid.pid = pid;
  ptid.lwp = lwp;
  ptid.tid = tid;
  return ptid;
}

/* Create a ptid from just a pid.  */

ptid_t
pid_to_ptid (int pid)
{
  return ptid_build (pid, 0, 0);
}

/* Fetch the pid (process id) component from a ptid.  */

int
ptid_get_pid (ptid_t ptid)
{
  return ptid.pid;
}

/* Fetch the lwp (lightweight process) component from a ptid.  */

long
ptid_get_lwp (ptid_t ptid)
{
  return ptid.lwp;
}

/* Fetch the tid (thread id) component from a ptid.  */

long
ptid_get_tid (ptid_t ptid)
{
  return ptid.tid;
}

/* ptid_equal() is used to test equality of two ptids.  */

int
ptid_equal (ptid_t ptid1, ptid_t ptid2)
{
  return (ptid1.pid == ptid2.pid && ptid1.lwp == ptid2.lwp
	  && ptid1.tid == ptid2.tid);
}

/* restore_inferior_ptid() will be used by the cleanup machinery
   to restore the inferior_ptid value saved in a call to
   save_inferior_ptid().  */

static void
restore_inferior_ptid (void *arg)
{
  ptid_t *saved_ptid_ptr = arg;
  inferior_ptid = *saved_ptid_ptr;
  xfree (arg);
}

/* Save the value of inferior_ptid so that it may be restored by a
   later call to do_cleanups().  Returns the struct cleanup pointer
   needed for later doing the cleanup.  */

struct cleanup *
save_inferior_ptid (void)
{
  ptid_t *saved_ptid_ptr;

  saved_ptid_ptr = xmalloc (sizeof (ptid_t));
  *saved_ptid_ptr = inferior_ptid;
  return make_cleanup (restore_inferior_ptid, saved_ptid_ptr);
}


static void
build_infrun (void)
{
  stop_registers = regcache_xmalloc (current_gdbarch);
}

void
_initialize_infrun (void)
{
  int i;
  int numsigs;
  struct cmd_list_element *c;

  DEPRECATED_REGISTER_GDBARCH_SWAP (stop_registers);
  deprecated_register_gdbarch_swap (NULL, 0, build_infrun);

  add_info ("signals", signals_info,
	    "What debugger does when program gets various signals.\n\
Specify a signal as argument to print info on that signal only.");
  add_info_alias ("handle", "signals", 0);

  add_com ("handle", class_run, handle_command,
	   concat ("Specify how to handle a signal.\n\
Args are signals and actions to apply to those signals.\n\
Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
from 1-15 are allowed for compatibility with old versions of GDB.\n\
Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
The special arg \"all\" is recognized to mean all signals except those\n\
used by the debugger, typically SIGTRAP and SIGINT.\n", "Recognized actions include \"stop\", \"nostop\", \"print\", \"noprint\",\n\
\"pass\", \"nopass\", \"ignore\", or \"noignore\".\n\
Stop means reenter debugger if this signal happens (implies print).\n\
Print means print a message if this signal happens.\n\
Pass means let program see this signal; otherwise program doesn't know.\n\
Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
Pass and Stop may be combined.", NULL));
  if (xdb_commands)
    {
      add_com ("lz", class_info, signals_info,
	       "What debugger does when program gets various signals.\n\
Specify a signal as argument to print info on that signal only.");
      add_com ("z", class_run, xdb_handle_command,
	       concat ("Specify how to handle a signal.\n\
Args are signals and actions to apply to those signals.\n\
Symbolic signals (e.g. SIGSEGV) are recommended but numeric signals\n\
from 1-15 are allowed for compatibility with old versions of GDB.\n\
Numeric ranges may be specified with the form LOW-HIGH (e.g. 1-5).\n\
The special arg \"all\" is recognized to mean all signals except those\n\
used by the debugger, typically SIGTRAP and SIGINT.\n", "Recognized actions include \"s\" (toggles between stop and nostop), \n\
\"r\" (toggles between print and noprint), \"i\" (toggles between pass and \
nopass), \"Q\" (noprint)\n\
Stop means reenter debugger if this signal happens (implies print).\n\
Print means print a message if this signal happens.\n\
Pass means let program see this signal; otherwise program doesn't know.\n\
Ignore is a synonym for nopass and noignore is a synonym for pass.\n\
Pass and Stop may be combined.", NULL));
    }

  if (!dbx_commands)
    stop_command =
      add_cmd ("stop", class_obscure, not_just_help_class_command, "There is no `stop' command, but you can set a hook on `stop'.\n\
This allows you to set a list of commands to be run each time execution\n\
of the program stops.", &cmdlist);

  numsigs = (int) TARGET_SIGNAL_LAST;
  signal_stop = (unsigned char *) xmalloc (sizeof (signal_stop[0]) * numsigs);
  signal_print = (unsigned char *)
    xmalloc (sizeof (signal_print[0]) * numsigs);
  signal_program = (unsigned char *)
    xmalloc (sizeof (signal_program[0]) * numsigs);
  for (i = 0; i < numsigs; i++)
    {
      signal_stop[i] = 1;
      signal_print[i] = 1;
      signal_program[i] = 1;
    }

  /* Signals caused by debugger's own actions
     should not be given to the program afterwards.  */
  signal_program[TARGET_SIGNAL_TRAP] = 0;
  signal_program[TARGET_SIGNAL_INT] = 0;

  /* Signals that are not errors should not normally enter the debugger.  */
  signal_stop[TARGET_SIGNAL_ALRM] = 0;
  signal_print[TARGET_SIGNAL_ALRM] = 0;
  signal_stop[TARGET_SIGNAL_VTALRM] = 0;
  signal_print[TARGET_SIGNAL_VTALRM] = 0;
  signal_stop[TARGET_SIGNAL_PROF] = 0;
  signal_print[TARGET_SIGNAL_PROF] = 0;
  signal_stop[TARGET_SIGNAL_CHLD] = 0;
  signal_print[TARGET_SIGNAL_CHLD] = 0;
  signal_stop[TARGET_SIGNAL_IO] = 0;
  signal_print[TARGET_SIGNAL_IO] = 0;
  signal_stop[TARGET_SIGNAL_POLL] = 0;
  signal_print[TARGET_SIGNAL_POLL] = 0;
  signal_stop[TARGET_SIGNAL_URG] = 0;
  signal_print[TARGET_SIGNAL_URG] = 0;
  signal_stop[TARGET_SIGNAL_WINCH] = 0;
  signal_print[TARGET_SIGNAL_WINCH] = 0;

  /* These signals are used internally by user-level thread
     implementations.  (See signal(5) on Solaris.)  Like the above
     signals, a healthy program receives and handles them as part of
     its normal operation.  */
  signal_stop[TARGET_SIGNAL_LWP] = 0;
  signal_print[TARGET_SIGNAL_LWP] = 0;
  signal_stop[TARGET_SIGNAL_WAITING] = 0;
  signal_print[TARGET_SIGNAL_WAITING] = 0;
  signal_stop[TARGET_SIGNAL_CANCEL] = 0;
  signal_print[TARGET_SIGNAL_CANCEL] = 0;

#ifdef SOLIB_ADD
  add_show_from_set
    (add_set_cmd ("stop-on-solib-events", class_support, var_zinteger,
		  (char *) &stop_on_solib_events,
		  "Set stopping for shared library events.\n\
If nonzero, gdb will give control to the user when the dynamic linker\n\
notifies gdb of shared library events.  The most common event of interest\n\
to the user would be loading/unloading of a new library.\n", &setlist), &showlist);
#endif

  c = add_set_enum_cmd ("follow-fork-mode",
			class_run,
			follow_fork_mode_kind_names, &follow_fork_mode_string,
			"Set debugger response to a program call of fork \
or vfork.\n\
A fork or vfork creates a new process.  follow-fork-mode can be:\n\
  parent  - the original process is debugged after a fork\n\
  child   - the new process is debugged after a fork\n\
The unfollowed process will continue to run.\n\
By default, the debugger will follow the parent process.", &setlist);
  add_show_from_set (c, &showlist);

  c = add_set_enum_cmd ("scheduler-locking", class_run, scheduler_enums,	/* array of string names */
			&scheduler_mode,	/* current mode  */
			"Set mode for locking scheduler during execution.\n\
off  == no locking (threads may preempt at any time)\n\
on   == full locking (no thread except the current thread may run)\n\
step == scheduler locked during every single-step operation.\n\
	In this mode, no other thread may run during a step command.\n\
	Other threads may run while stepping over a function call ('next').", &setlist);

  set_cmd_sfunc (c, set_schedlock_func);	/* traps on target vector */
  add_show_from_set (c, &showlist);

  c = add_set_cmd ("step-mode", class_run,
		   var_boolean, (char *) &step_stop_if_no_debug,
		   "Set mode of the step operation. When set, doing a step over a\n\
function without debug line information will stop at the first\n\
instruction of that function. Otherwise, the function is skipped and\n\
the step command stops at a different source line.", &setlist);
  add_show_from_set (c, &showlist);

  /* ptid initializations */
  null_ptid = ptid_build (0, 0, 0);
  minus_one_ptid = ptid_build (-1, 0, 0);
  inferior_ptid = null_ptid;
  target_last_wait_ptid = minus_one_ptid;
}
