gdb/testsuite:
[deliverable/binutils-gdb.git] / gdb / infrun.c
index e0d808ae255ec0bfd61e071270cc49480c1fc567..ab518061f9d77c1b584777e3405a8cca06c2b3bf 100644 (file)
@@ -1,9 +1,7 @@
 /* Target-struct-independent code to start (run) and stop an inferior
    process.
 
-   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 1986-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "jit.h"
 #include "tracepoint.h"
 #include "continuations.h"
+#include "interps.h"
+#include "skip.h"
+#include "probe.h"
+#include "objfiles.h"
 
 /* Prototypes for local functions */
 
@@ -146,6 +148,37 @@ show_debug_infrun (struct ui_file *file, int from_tty,
   fprintf_filtered (file, _("Inferior debugging is %s.\n"), value);
 }
 
+
+/* Support for disabling address space randomization.  */
+
+int disable_randomization = 1;
+
+static void
+show_disable_randomization (struct ui_file *file, int from_tty,
+                           struct cmd_list_element *c, const char *value)
+{
+  if (target_supports_disable_randomization ())
+    fprintf_filtered (file,
+                     _("Disabling randomization of debuggee's "
+                       "virtual address space is %s.\n"),
+                     value);
+  else
+    fputs_filtered (_("Disabling randomization of debuggee's "
+                     "virtual address space is unsupported on\n"
+                     "this platform.\n"), file);
+}
+
+static void
+set_disable_randomization (char *args, int from_tty,
+                          struct cmd_list_element *c)
+{
+  if (!target_supports_disable_randomization ())
+    error (_("Disabling randomization of debuggee's "
+            "virtual address space is unsupported on\n"
+            "this platform."));
+}
+
+
 /* 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
@@ -304,6 +337,15 @@ static unsigned char *signal_pass;
        (flags)[signum] = 0; \
   } while (0)
 
+/* Update the target's copy of SIGNAL_PROGRAM.  The sole purpose of
+   this function is to avoid exporting `signal_program'.  */
+
+void
+update_signals_program_target (void)
+{
+  target_program_signals ((int) TARGET_SIGNAL_LAST, signal_program);
+}
+
 /* Value to pass to target_resume() to cause all threads to resume.  */
 
 #define RESUME_ALL minus_one_ptid
@@ -358,7 +400,7 @@ void init_infwait_state (void);
 static const char follow_fork_mode_child[] = "child";
 static const char follow_fork_mode_parent[] = "parent";
 
-static const char *follow_fork_mode_kind_names[] = {
+static const char *const follow_fork_mode_kind_names[] = {
   follow_fork_mode_child,
   follow_fork_mode_parent,
   NULL
@@ -708,6 +750,7 @@ handle_vfork_child_exec_or_exit (int exec)
          pspace = add_program_space (maybe_new_address_space ());
          set_current_program_space (pspace);
          inf->removable = 1;
+         inf->symfile_flags = SYMFILE_NO_READ;
          clone_program_space (pspace, inf->vfork_parent->pspace);
          inf->pspace = pspace;
          inf->aspace = pspace->aspace;
@@ -747,7 +790,7 @@ handle_vfork_child_exec_or_exit (int exec)
 
 static const char follow_exec_mode_new[] = "new";
 static const char follow_exec_mode_same[] = "same";
-static const char *follow_exec_mode_names[] =
+static const char *const follow_exec_mode_names[] =
 {
   follow_exec_mode_new,
   follow_exec_mode_same,
@@ -869,10 +912,13 @@ follow_exec (ptid_t pid, char *execd_pathname)
      solib_create_inferior_hook below.  breakpoint_re_set would fail to insert
      the breakpoints with the zero displacement.  */
 
-  symbol_file_add (execd_pathname, SYMFILE_MAINLINE | SYMFILE_DEFER_BP_RESET,
+  symbol_file_add (execd_pathname,
+                  (inf->symfile_flags
+                   | SYMFILE_MAINLINE | SYMFILE_DEFER_BP_RESET),
                   NULL, 0);
 
-  set_initial_language ();
+  if ((inf->symfile_flags & SYMFILE_NO_READ) == 0)
+    set_initial_language ();
 
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
   SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
@@ -1144,7 +1190,7 @@ infrun_inferior_exit (struct inferior *inf)
 static const char can_use_displaced_stepping_auto[] = "auto";
 static const char can_use_displaced_stepping_on[] = "on";
 static const char can_use_displaced_stepping_off[] = "off";
-static const char *can_use_displaced_stepping_enum[] =
+static const char *const can_use_displaced_stepping_enum[] =
 {
   can_use_displaced_stepping_auto,
   can_use_displaced_stepping_on,
@@ -1252,6 +1298,7 @@ displaced_step_prepare (ptid_t ptid)
   ULONGEST len;
   struct displaced_step_closure *closure;
   struct displaced_step_inferior_state *displaced;
+  int status;
 
   /* We should never reach this function if the architecture does not
      support displaced stepping.  */
@@ -1312,7 +1359,12 @@ displaced_step_prepare (ptid_t ptid)
   displaced->step_saved_copy = xmalloc (len);
   ignore_cleanups = make_cleanup (free_current_contents,
                                  &displaced->step_saved_copy);
-  read_memory (copy, displaced->step_saved_copy, len);
+  status = target_read_memory (copy, displaced->step_saved_copy, len);
+  if (status != 0)
+    throw_error (MEMORY_ERROR,
+                _("Error accessing memory address %s (%s) for "
+                  "displaced-stepping scratch space."),
+                paddress (gdbarch, copy), safe_strerror (status));
   if (debug_displaced)
     {
       fprintf_unfiltered (gdb_stdlog, "displaced: saved %s: ",
@@ -1363,6 +1415,23 @@ write_memory_ptid (ptid_t ptid, CORE_ADDR memaddr,
   do_cleanups (ptid_cleanup);
 }
 
+/* Restore the contents of the copy area for thread PTID.  */
+
+static void
+displaced_step_restore (struct displaced_step_inferior_state *displaced,
+                       ptid_t ptid)
+{
+  ULONGEST len = gdbarch_max_insn_length (displaced->step_gdbarch);
+
+  write_memory_ptid (ptid, displaced->step_copy,
+                    displaced->step_saved_copy, len);
+  if (debug_displaced)
+    fprintf_unfiltered (gdb_stdlog, "displaced: restored %s %s\n",
+                       target_pid_to_str (ptid),
+                       paddress (displaced->step_gdbarch,
+                                 displaced->step_copy));
+}
+
 static void
 displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
 {
@@ -1381,17 +1450,7 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
 
   old_cleanups = make_cleanup (displaced_step_clear_cleanup, displaced);
 
-  /* Restore the contents of the copy area.  */
-  {
-    ULONGEST len = gdbarch_max_insn_length (displaced->step_gdbarch);
-
-    write_memory_ptid (displaced->step_ptid, displaced->step_copy,
-                      displaced->step_saved_copy, len);
-    if (debug_displaced)
-      fprintf_unfiltered (gdb_stdlog, "displaced: restored %s\n",
-                          paddress (displaced->step_gdbarch,
-                                   displaced->step_copy));
-  }
+  displaced_step_restore (displaced, displaced->step_ptid);
 
   /* Did the instruction complete successfully?  */
   if (signal == TARGET_SIGNAL_TRAP)
@@ -1541,7 +1600,7 @@ resume_cleanups (void *ignore)
 static const char schedlock_off[] = "off";
 static const char schedlock_on[] = "on";
 static const char schedlock_step[] = "step";
-static const char *scheduler_enums[] = {
+static const char *const scheduler_enums[] = {
   schedlock_off,
   schedlock_on,
   schedlock_step,
@@ -1732,6 +1791,10 @@ a command like `return' or `jump' to continue execution."));
          return;
        }
 
+      /* Update pc to reflect the new address from which we will execute
+        instructions due to displaced stepping.  */
+      pc = regcache_read_pc (get_thread_regcache (inferior_ptid));
+
       displaced = get_displaced_stepping_state (ptid_get_pid (inferior_ptid));
       step = gdbarch_displaced_step_hw_singlestep (gdbarch,
                                                   displaced->step_closure);
@@ -2246,7 +2309,6 @@ start_remote (int from_tty)
 {
   struct inferior *inferior;
 
-  init_wait_for_inferior ();
   inferior = current_inferior ();
   inferior->control.stop_soon = STOP_QUIETLY_REMOTE;
 
@@ -2327,9 +2389,10 @@ struct execution_control_state
 
   struct target_waitstatus ws;
   int random_signal;
+  int stop_func_filled_in;
   CORE_ADDR stop_func_start;
   CORE_ADDR stop_func_end;
-  char *stop_func_name;
+  const char *stop_func_name;
   int new_thread_event;
   int wait_some_more;
 };
@@ -2341,7 +2404,7 @@ static void handle_step_into_function (struct gdbarch *gdbarch,
 static void handle_step_into_function_backward (struct gdbarch *gdbarch,
                                                struct execution_control_state *ecs);
 static void check_exception_resume (struct execution_control_state *,
-                                   struct frame_info *, struct symbol *);
+                                   struct frame_info *);
 
 static void stop_stepping (struct execution_control_state *ecs);
 static void prepare_to_wait (struct execution_control_state *ecs);
@@ -2579,14 +2642,6 @@ prepare_for_detach (void)
 
       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 (deprecated_target_wait_hook)
        ecs->ptid = deprecated_target_wait_hook (pid_ptid, &ecs->ws, 0);
       else
@@ -2656,14 +2711,7 @@ wait_for_inferior (void)
     {
       struct cleanup *old_chain;
 
-      /* 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.  */
-
       overlay_cache_invalid = 1;
-      registers_changed ();
 
       if (deprecated_target_wait_hook)
        ecs->ptid = deprecated_target_wait_hook (waiton_ptid, &ecs->ws, 0);
@@ -2678,10 +2726,6 @@ wait_for_inferior (void)
         state.  */
       old_chain = make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
 
-      if (ecs->ws.kind == TARGET_WAITKIND_SYSCALL_ENTRY
-          || ecs->ws.kind == TARGET_WAITKIND_SYSCALL_RETURN)
-        ecs->ws.value.syscall_number = UNKNOWN_SYSCALL;
-
       /* Now figure out what to do with the result of the result.  */
       handle_inferior_event (ecs);
 
@@ -2712,6 +2756,7 @@ fetch_inferior_event (void *client_data)
   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
   struct cleanup *ts_old_chain;
   int was_sync = sync_execution;
+  int cmd_done = 0;
 
   memset (ecs, 0, sizeof (*ecs));
 
@@ -2732,14 +2777,7 @@ fetch_inferior_event (void *client_data)
        running any breakpoint commands.  */
     make_cleanup_restore_current_thread ();
 
-  /* 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.  */
-
   overlay_cache_invalid = 1;
-  registers_changed ();
 
   make_cleanup_restore_integer (&execution_direction);
   execution_direction = target_execution_direction ();
@@ -2755,6 +2793,7 @@ fetch_inferior_event (void *client_data)
 
   if (non_stop
       && ecs->ws.kind != TARGET_WAITKIND_IGNORE
+      && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED
       && ecs->ws.kind != TARGET_WAITKIND_EXITED
       && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
     /* In non-stop mode, each thread is handled individually.  Switch
@@ -2770,6 +2809,10 @@ fetch_inferior_event (void *client_data)
   else
     ts_old_chain = make_cleanup (finish_thread_state_cleanup, &ecs->ptid);
 
+  /* Get executed before make_cleanup_restore_current_thread above to apply
+     still for the thread which has thrown the exception.  */
+  make_bpstat_clear_actions_cleanup ();
+
   /* Now figure out what to do with the result of the result.  */
   handle_inferior_event (ecs);
 
@@ -2784,13 +2827,17 @@ fetch_inferior_event (void *client_data)
        normal_stop ();
 
       if (target_has_execution
+         && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED
          && ecs->ws.kind != TARGET_WAITKIND_EXITED
          && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
          && ecs->event_thread->step_multi
          && ecs->event_thread->control.stop_step)
        inferior_event_handler (INF_EXEC_CONTINUE, NULL);
       else
-       inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+       {
+         inferior_event_handler (INF_EXEC_COMPLETE, NULL);
+         cmd_done = 1;
+       }
     }
 
   /* No error, don't finish the thread states yet.  */
@@ -2800,9 +2847,17 @@ fetch_inferior_event (void *client_data)
   do_cleanups (old_chain);
 
   /* If the inferior was in sync execution mode, and now isn't,
-     restore the prompt.  */
-  if (was_sync && !sync_execution)
+     restore the prompt (a synchronous execution command has finished,
+     and we're ready for input).  */
+  if (interpreter_async && was_sync && !sync_execution)
     display_gdb_prompt (0);
+
+  if (cmd_done
+      && !was_sync
+      && exec_done_display_p
+      && (ptid_equal (inferior_ptid, null_ptid)
+         || !is_running (inferior_ptid)))
+    printf_unfiltered (_("completed.\n"));
 }
 
 /* Record the frame and location we're currently stepping through.  */
@@ -2825,8 +2880,6 @@ init_thread_stepping_state (struct thread_info *tss)
 {
   tss->stepping_over_breakpoint = 0;
   tss->step_after_step_resume_breakpoint = 0;
-  tss->stepping_through_solib_after_catch = 0;
-  tss->stepping_through_solib_catchpoints = NULL;
 }
 
 /* Return the cached copy of the last pid/waitstatus returned by
@@ -2852,7 +2905,7 @@ nullify_last_target_wait_ptid (void)
 static void
 context_switch (ptid_t ptid)
 {
-  if (debug_infrun)
+  if (debug_infrun && !ptid_equal (ptid, inferior_ptid))
     {
       fprintf_unfiltered (gdb_stdlog, "infrun: Switching context from %s ",
                          target_pid_to_str (inferior_ptid));
@@ -3040,11 +3093,9 @@ handle_syscall_event (struct execution_control_state *ecs)
 
   regcache = get_thread_regcache (ecs->ptid);
   gdbarch = get_regcache_arch (regcache);
-  syscall_number = gdbarch_get_syscall_number (gdbarch, ecs->ptid);
+  syscall_number = ecs->ws.value.syscall_number;
   stop_pc = regcache_read_pc (regcache);
 
-  target_last_waitstatus.value.syscall_number = syscall_number;
-
   if (catch_syscall_enabled () > 0
       && catching_syscall_number (syscall_number) > 0)
     {
@@ -3054,7 +3105,7 @@ handle_syscall_event (struct execution_control_state *ecs)
 
       ecs->event_thread->control.stop_bpstat
        = bpstat_stop_status (get_regcache_aspace (regcache),
-                             stop_pc, ecs->ptid);
+                             stop_pc, ecs->ptid, &ecs->ws);
       ecs->random_signal
        = !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
 
@@ -3072,6 +3123,36 @@ handle_syscall_event (struct execution_control_state *ecs)
   return 1;
 }
 
+/* Clear the supplied execution_control_state's stop_func_* fields.  */
+
+static void
+clear_stop_func (struct execution_control_state *ecs)
+{
+  ecs->stop_func_filled_in = 0;
+  ecs->stop_func_start = 0;
+  ecs->stop_func_end = 0;
+  ecs->stop_func_name = NULL;
+}
+
+/* Lazily fill in the execution_control_state's stop_func_* fields.  */
+
+static void
+fill_in_stop_func (struct gdbarch *gdbarch,
+                  struct execution_control_state *ecs)
+{
+  if (!ecs->stop_func_filled_in)
+    {
+      /* 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
+       += gdbarch_deprecated_function_start_offset (gdbarch);
+
+      ecs->stop_func_filled_in = 1;
+    }
+}
+
 /* 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.  */
@@ -3081,7 +3162,6 @@ handle_inferior_event (struct execution_control_state *ecs)
 {
   struct frame_info *frame;
   struct gdbarch *gdbarch;
-  int sw_single_step_trap_p = 0;
   int stopped_by_watchpoint;
   int stepped_after_stopped_by_watchpoint = 0;
   struct symtab_and_line stop_pc_sal;
@@ -3104,8 +3184,24 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
     }
 
+  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED
+      && target_can_async_p () && !sync_execution)
+    {
+      /* There were no unwaited-for children left in the target, but,
+        we're not synchronously waiting for events either.  Just
+        ignore.  Otherwise, if we were running a synchronous
+        execution command, we need to cancel it and give the user
+        back the terminal.  */
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog,
+                           "infrun: TARGET_WAITKIND_NO_RESUMED (ignoring)\n");
+      prepare_to_wait (ecs);
+      return;
+    }
+
   if (ecs->ws.kind != TARGET_WAITKIND_EXITED
-      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
+      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
+      && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED)
     {
       struct inferior *inf = find_inferior_pid (ptid_get_pid (ecs->ptid));
 
@@ -3122,6 +3218,18 @@ handle_inferior_event (struct execution_control_state *ecs)
   /* Always clear state belonging to the previous time we stopped.  */
   stop_stack_dummy = STOP_NONE;
 
+  if (ecs->ws.kind == TARGET_WAITKIND_NO_RESUMED)
+    {
+      /* No unwaited-for children left.  IOW, all resumed children
+        have exited.  */
+      if (debug_infrun)
+       fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_RESUMED\n");
+
+      stop_print_frame = 0;
+      stop_stepping (ecs);
+      return;
+    }
+
   /* If it's a new process, add it to the thread database.  */
 
   ecs->new_thread_event = (!ptid_equal (ecs->ptid, inferior_ptid)
@@ -3179,7 +3287,7 @@ handle_inferior_event (struct execution_control_state *ecs)
     set_executing (minus_one_ptid, 0);
   else if (ecs->ws.kind != TARGET_WAITKIND_SIGNALLED
           && ecs->ws.kind != TARGET_WAITKIND_EXITED)
-    set_executing (inferior_ptid, 0);
+    set_executing (ecs->ptid, 0);
 
   switch (infwait_state)
     {
@@ -3233,28 +3341,32 @@ handle_inferior_event (struct execution_control_state *ecs)
          established.  */
       if (stop_soon == NO_STOP_QUIETLY)
        {
-         /* 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).  */
-#ifdef SOLIB_ADD
-         SOLIB_ADD (NULL, 0, &current_target, auto_solib_add);
-#else
-         solib_add (NULL, 0, &current_target, auto_solib_add);
-#endif
-         target_terminal_inferior ();
+         struct regcache *regcache;
+
+         if (!ptid_equal (ecs->ptid, inferior_ptid))
+           context_switch (ecs->ptid);
+         regcache = get_thread_regcache (ecs->ptid);
+
+         handle_solib_event ();
+
+         ecs->event_thread->control.stop_bpstat
+           = bpstat_stop_status (get_regcache_aspace (regcache),
+                                 stop_pc, ecs->ptid, &ecs->ws);
+         ecs->random_signal
+           = !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
+
+         if (!ecs->random_signal)
+           {
+             /* A catchpoint triggered.  */
+             ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_TRAP;
+             goto process_event_stop_test;
+           }
 
          /* 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).  */
+         ecs->event_thread->suspend.stop_signal = TARGET_SIGNAL_0;
          if (stop_on_solib_events)
            {
              /* Make sure we print "Stopped due to solib-event" in
@@ -3264,9 +3376,6 @@ handle_inferior_event (struct execution_control_state *ecs)
              stop_stepping (ecs);
              return;
            }
-
-         /* NOTE drow/2007-05-11: This might be a good place to check
-            for "catch load".  */
        }
 
       /* If we are skipping through a shell, or through shared library
@@ -3308,6 +3417,11 @@ handle_inferior_event (struct execution_control_state *ecs)
          that the user can inspect this again later.  */
       set_internalvar_integer (lookup_internalvar ("_exitcode"),
                               (LONGEST) ecs->ws.value.integer);
+
+      /* Also record this in the inferior itself.  */
+      current_inferior ()->has_exit_code = 1;
+      current_inferior ()->exit_code = (LONGEST) ecs->ws.value.integer;
+
       gdb_flush (gdb_stdout);
       target_mourn_inferior ();
       singlestep_breakpoints_inserted_p = 0;
@@ -3346,6 +3460,60 @@ handle_inferior_event (struct execution_control_state *ecs)
       if (debug_infrun)
         fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_FORKED\n");
 
+      /* Check whether the inferior is displaced stepping.  */
+      {
+       struct regcache *regcache = get_thread_regcache (ecs->ptid);
+       struct gdbarch *gdbarch = get_regcache_arch (regcache);
+       struct displaced_step_inferior_state *displaced
+         = get_displaced_stepping_state (ptid_get_pid (ecs->ptid));
+
+       /* If checking displaced stepping is supported, and thread
+          ecs->ptid is displaced stepping.  */
+       if (displaced && ptid_equal (displaced->step_ptid, ecs->ptid))
+         {
+           struct inferior *parent_inf
+             = find_inferior_pid (ptid_get_pid (ecs->ptid));
+           struct regcache *child_regcache;
+           CORE_ADDR parent_pc;
+
+           /* GDB has got TARGET_WAITKIND_FORKED or TARGET_WAITKIND_VFORKED,
+              indicating that the displaced stepping of syscall instruction
+              has been done.  Perform cleanup for parent process here.  Note
+              that this operation also cleans up the child process for vfork,
+              because their pages are shared.  */
+           displaced_step_fixup (ecs->ptid, TARGET_SIGNAL_TRAP);
+
+           if (ecs->ws.kind == TARGET_WAITKIND_FORKED)
+             {
+               /* Restore scratch pad for child process.  */
+               displaced_step_restore (displaced, ecs->ws.value.related_pid);
+             }
+
+           /* Since the vfork/fork syscall instruction was executed in the scratchpad,
+              the child's PC is also within the scratchpad.  Set the child's PC
+              to the parent's PC value, which has already been fixed up.
+              FIXME: we use the parent's aspace here, although we're touching
+              the child, because the child hasn't been added to the inferior
+              list yet at this point.  */
+
+           child_regcache
+             = get_thread_arch_aspace_regcache (ecs->ws.value.related_pid,
+                                                gdbarch,
+                                                parent_inf->aspace);
+           /* Read PC value of parent process.  */
+           parent_pc = regcache_read_pc (regcache);
+
+           if (debug_displaced)
+             fprintf_unfiltered (gdb_stdlog,
+                                 "displaced: write child pc from %s to %s\n",
+                                 paddress (gdbarch,
+                                           regcache_read_pc (child_regcache)),
+                                 paddress (gdbarch, parent_pc));
+
+           regcache_write_pc (child_regcache, parent_pc);
+         }
+      }
+
       if (!ptid_equal (ecs->ptid, inferior_ptid))
        {
          context_switch (ecs->ptid);
@@ -3389,7 +3557,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       ecs->event_thread->control.stop_bpstat
        = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
-                             stop_pc, ecs->ptid);
+                             stop_pc, ecs->ptid, &ecs->ws);
 
       /* Note that we're interested in knowing the bpstat actually
         causes a stop, not just if it may explain the signal.
@@ -3487,7 +3655,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
       ecs->event_thread->control.stop_bpstat
        = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
-                             stop_pc, ecs->ptid);
+                             stop_pc, ecs->ptid, &ecs->ws);
       ecs->random_signal
        = !bpstat_explains_signal (ecs->event_thread->control.stop_bpstat);
 
@@ -3537,6 +3705,8 @@ handle_inferior_event (struct execution_control_state *ecs)
       break;
 
     case TARGET_WAITKIND_NO_HISTORY:
+      if (debug_infrun)
+        fprintf_unfiltered (gdb_stdlog, "infrun: TARGET_WAITKIND_NO_HISTORY\n");
       /* Reverse execution: target ran out of history info.  */
       stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
       print_no_history_reason ();
@@ -3831,7 +4001,6 @@ handle_inferior_event (struct execution_control_state *ecs)
        }
       else if (singlestep_breakpoints_inserted_p)
        {
-         sw_single_step_trap_p = 1;
          ecs->random_signal = 0;
        }
     }
@@ -3914,15 +4083,7 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
     }
 
-  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
-    += gdbarch_deprecated_function_start_offset (gdbarch);
+  clear_stop_func (ecs);
   ecs->event_thread->stepping_over_breakpoint = 0;
   bpstat_clear (&ecs->event_thread->control.stop_bpstat);
   ecs->event_thread->control.stop_step = 0;
@@ -3934,7 +4095,33 @@ handle_inferior_event (struct execution_control_state *ecs)
      nexti.  After stepi and nexti, always show the innermost frame (not any
      inline function call sites).  */
   if (ecs->event_thread->control.step_range_end != 1)
-    skip_inline_frames (ecs->ptid);
+    {
+      struct address_space *aspace = 
+       get_regcache_aspace (get_thread_regcache (ecs->ptid));
+
+      /* skip_inline_frames is expensive, so we avoid it if we can
+        determine that the address is one where functions cannot have
+        been inlined.  This improves performance with inferiors that
+        load a lot of shared libraries, because the solib event
+        breakpoint is defined as the address of a function (i.e. not
+        inline).  Note that we have to check the previous PC as well
+        as the current one to catch cases when we have just
+        single-stepped off a breakpoint prior to reinstating it.
+        Note that we're assuming that the code we single-step to is
+        not inline, but that's not definitive: there's nothing
+        preventing the event breakpoint function from containing
+        inlined code, and the single-step ending up there.  If the
+        user had set a breakpoint on that inlined code, the missing
+        skip_inline_frames call would break things.  Fortunately
+        that's an extremely unlikely scenario.  */
+      if (!pc_at_non_inline_function (aspace, stop_pc, &ecs->ws)
+          && !(ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
+               && ecs->event_thread->control.trap_expected
+               && pc_at_non_inline_function (aspace,
+                                             ecs->event_thread->prev_pc,
+                                            &ecs->ws)))
+       skip_inline_frames (ecs->ptid);
+    }
 
   if (ecs->event_thread->suspend.stop_signal == TARGET_SIGNAL_TRAP
       && ecs->event_thread->control.trap_expected
@@ -4034,10 +4221,11 @@ handle_inferior_event (struct execution_control_state *ecs)
          return;
        }
 
-      /* See if there is a breakpoint at the current PC.  */
+      /* See if there is a breakpoint/watchpoint/catchpoint/etc. that
+        handles this event.  */
       ecs->event_thread->control.stop_bpstat
        = bpstat_stop_status (get_regcache_aspace (get_current_regcache ()),
-                             stop_pc, ecs->ptid);
+                             stop_pc, ecs->ptid, &ecs->ws);
 
       /* Following in case break condition called a
         function.  */
@@ -4251,9 +4439,17 @@ process_event_stop_test:
 
        if (what.is_longjmp)
          {
-           if (!gdbarch_get_longjmp_target_p (gdbarch)
-               || !gdbarch_get_longjmp_target (gdbarch,
-                                               frame, &jmp_buf_pc))
+           struct value *arg_value;
+
+           /* If we set the longjmp breakpoint via a SystemTap probe,
+              then use it to extract the arguments.  The destination
+              PC is the third argument to the probe.  */
+           arg_value = probe_safe_evaluate_at_pc (frame, 2);
+           if (arg_value)
+             jmp_buf_pc = value_as_address (arg_value);
+           else if (!gdbarch_get_longjmp_target_p (gdbarch)
+                    || !gdbarch_get_longjmp_target (gdbarch,
+                                                    frame, &jmp_buf_pc))
              {
                if (debug_infrun)
                  fprintf_unfiltered (gdb_stdlog,
@@ -4271,12 +4467,7 @@ process_event_stop_test:
            insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
          }
        else
-         {
-           struct symbol *func = get_frame_function (frame);
-
-           if (func)
-             check_exception_resume (ecs, frame, func);
-         }
+         check_exception_resume (ecs, frame);
        keep_going (ecs);
        return;
 
@@ -4366,6 +4557,7 @@ process_event_stop_test:
            keep_going (ecs);
            return;
          }
+       fill_in_stop_func (gdbarch, ecs);
        if (stop_pc == ecs->stop_func_start
            && execution_direction == EXEC_REVERSE)
          {
@@ -4499,37 +4691,6 @@ process_event_stop_test:
        }
     }
 
-  /* 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->event_thread->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))
-       {
-          if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: stepping in dynamic linker\n");
-         ecs->event_thread->stepping_over_breakpoint = 1;
-         keep_going (ecs);
-         return;
-       }
-#endif
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog, "infrun: step past dynamic linker\n");
-      /* Else, stop and report the catchpoint(s) whose triggering
-         caused us to begin stepping.  */
-      ecs->event_thread->stepping_through_solib_after_catch = 0;
-      bpstat_clear (&ecs->event_thread->control.stop_bpstat);
-      ecs->event_thread->control.stop_bpstat
-       = bpstat_copy (ecs->event_thread->stepping_through_solib_catchpoints);
-      bpstat_clear (&ecs->event_thread->stepping_through_solib_catchpoints);
-      stop_print_frame = 1;
-      stop_stepping (ecs);
-      return;
-    }
-
   if (ecs->event_thread->control.step_resume_breakpoint)
     {
       if (debug_infrun)
@@ -4557,6 +4718,7 @@ process_event_stop_test:
      a dangling pointer.  */
   frame = get_current_frame ();
   gdbarch = get_frame_arch (frame);
+  fill_in_stop_func (gdbarch, ecs);
 
   /* If stepping through a line, keep going if still within it.
 
@@ -4657,6 +4819,48 @@ process_event_stop_test:
       return;
     }
 
+  /* If we're in the return path from a shared library trampoline,
+     we want to proceed through the trampoline when stepping.  */
+  /* macro/2012-04-25: This needs to come before the subroutine
+     call check below as on some targets return trampolines look
+     like subroutine calls (MIPS16 return thunks).  */
+  if (gdbarch_in_solib_return_trampoline (gdbarch,
+                                         stop_pc, ecs->stop_func_name)
+      && ecs->event_thread->control.step_over_calls != STEP_OVER_NONE)
+    {
+      /* Determine where this trampoline returns.  */
+      CORE_ADDR real_stop_pc;
+
+      real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
+
+      if (debug_infrun)
+        fprintf_unfiltered (gdb_stdlog,
+                            "infrun: stepped into solib return tramp\n");
+
+      /* 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);
+         sr_sal.pspace = get_frame_program_space (frame);
+
+         /* 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.  */
+         insert_step_resume_breakpoint_at_sal (gdbarch,
+                                               sr_sal, null_frame_id);
+
+         /* Restart without fiddling with the step ranges or
+            other state.  */
+         keep_going (ecs);
+         return;
+       }
+    }
+
   /* Check for subroutine calls.  The check for the current frame
      equalling the step ID is not necessary - the check of the
      previous frame's ID is sufficient - but it is a common case and
@@ -4779,7 +4983,8 @@ process_event_stop_test:
        }
 
       /* If we have line number information for the function we are
-         thinking of stepping into, step into it.
+        thinking of stepping into and the function isn't on the skip
+        list, 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
@@ -4788,7 +4993,8 @@ process_event_stop_test:
        struct symtab_and_line tmp_sal;
 
        tmp_sal = find_pc_line (ecs->stop_func_start, 0);
-       if (tmp_sal.line != 0)
+       if (tmp_sal.line != 0
+           && !function_pc_is_marked_for_skip (ecs->stop_func_start))
          {
            if (execution_direction == EXEC_REVERSE)
              handle_step_into_function_backward (gdbarch, ecs);
@@ -4865,44 +5071,6 @@ process_event_stop_test:
        }
     }
 
-  /* If we're in the return path from a shared library trampoline,
-     we want to proceed through the trampoline when stepping.  */
-  if (gdbarch_in_solib_return_trampoline (gdbarch,
-                                         stop_pc, ecs->stop_func_name))
-    {
-      /* Determine where this trampoline returns.  */
-      CORE_ADDR real_stop_pc;
-
-      real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
-
-      if (debug_infrun)
-        fprintf_unfiltered (gdb_stdlog,
-                            "infrun: stepped into solib return tramp\n");
-
-      /* 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);
-         sr_sal.pspace = get_frame_program_space (frame);
-
-         /* 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.  */
-         insert_step_resume_breakpoint_at_sal (gdbarch,
-                                               sr_sal, null_frame_id);
-
-         /* Restart without fiddling with the step ranges or
-            other state.  */
-         keep_going (ecs);
-         return;
-       }
-    }
-
   stop_pc_sal = find_pc_line (stop_pc, 0);
 
   /* NOTE: tausq/2004-05-24: This if block used to be done before all
@@ -5088,7 +5256,6 @@ currently_stepping (struct thread_info *tp)
   return ((tp->control.step_range_end
           && tp->control.step_resume_breakpoint == NULL)
          || tp->control.trap_expected
-         || tp->stepping_through_solib_after_catch
          || bpstat_should_step ());
 }
 
@@ -5102,8 +5269,7 @@ currently_stepping_or_nexting_callback (struct thread_info *tp, void *data)
     return 0;
 
   return (tp->control.step_range_end
-         || tp->control.trap_expected
-         || tp->stepping_through_solib_after_catch);
+         || tp->control.trap_expected);
 }
 
 /* Inferior has stepped into a subroutine call with source code that
@@ -5117,6 +5283,8 @@ handle_step_into_function (struct gdbarch *gdbarch,
   struct symtab *s;
   struct symtab_and_line stop_func_sal, sr_sal;
 
+  fill_in_stop_func (gdbarch, ecs);
+
   s = find_pc_symtab (stop_pc);
   if (s && s->language != language_asm)
     ecs->stop_func_start = gdbarch_skip_prologue (gdbarch,
@@ -5196,6 +5364,8 @@ handle_step_into_function_backward (struct gdbarch *gdbarch,
   struct symtab *s;
   struct symtab_and_line stop_func_sal;
 
+  fill_in_stop_func (gdbarch, ecs);
+
   s = find_pc_symtab (stop_pc);
   if (s && s->language != language_asm)
     ecs->stop_func_start = gdbarch_skip_prologue (gdbarch,
@@ -5353,7 +5523,7 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
                                    struct frame_info *frame,
                                    struct symbol *sym)
 {
-  struct gdb_exception e;
+  volatile struct gdb_exception e;
 
   /* We want to ignore errors here.  */
   TRY_CATCH (e, RETURN_MASK_ERROR)
@@ -5377,21 +5547,75 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
 
          bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame),
                                               handler, bp_exception_resume);
+
+         /* set_momentary_breakpoint_at_pc invalidates FRAME.  */
+         frame = NULL;
+
          bp->thread = tp->num;
          inferior_thread ()->control.exception_resume_breakpoint = bp;
        }
     }
 }
 
+/* A helper for check_exception_resume that sets an
+   exception-breakpoint based on a SystemTap probe.  */
+
+static void
+insert_exception_resume_from_probe (struct thread_info *tp,
+                                   const struct probe *probe,
+                                   struct objfile *objfile,
+                                   struct frame_info *frame)
+{
+  struct value *arg_value;
+  CORE_ADDR handler;
+  struct breakpoint *bp;
+
+  arg_value = probe_safe_evaluate_at_pc (frame, 1);
+  if (!arg_value)
+    return;
+
+  handler = value_as_address (arg_value);
+
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog,
+                       "infrun: exception resume at %s\n",
+                       paddress (get_objfile_arch (objfile),
+                                 handler));
+
+  bp = set_momentary_breakpoint_at_pc (get_frame_arch (frame),
+                                      handler, bp_exception_resume);
+  bp->thread = tp->num;
+  inferior_thread ()->control.exception_resume_breakpoint = bp;
+}
+
 /* This is called when an exception has been intercepted.  Check to
    see whether the exception's destination is of interest, and if so,
    set an exception resume breakpoint there.  */
 
 static void
 check_exception_resume (struct execution_control_state *ecs,
-                       struct frame_info *frame, struct symbol *func)
-{
-  struct gdb_exception e;
+                       struct frame_info *frame)
+{
+  volatile struct gdb_exception e;
+  struct objfile *objfile;
+  const struct probe *probe;
+  struct symbol *func;
+
+  /* First see if this exception unwinding breakpoint was set via a
+     SystemTap probe point.  If so, the probe has two arguments: the
+     CFA and the HANDLER.  We ignore the CFA, extract the handler, and
+     set a breakpoint there.  */
+  probe = find_probe_by_pc (get_frame_pc (frame), &objfile);
+  if (probe)
+    {
+      insert_exception_resume_from_probe (ecs->event_thread, probe,
+                                         objfile, frame);
+      return;
+    }
+
+  func = get_frame_function (frame);
+  if (!func)
+    return;
 
   TRY_CATCH (e, RETURN_MASK_ERROR)
     {
@@ -5498,7 +5722,7 @@ keep_going (struct execution_control_state *ecs)
        }
       else
        {
-         struct gdb_exception e;
+         volatile struct gdb_exception e;
 
          /* Stop stepping when inserting breakpoints
             has failed.  */
@@ -5574,8 +5798,8 @@ print_end_stepping_range_reason (void)
 {
   if ((!inferior_thread ()->step_multi
        || !inferior_thread ()->control.stop_step)
-      && ui_out_is_mi_like_p (uiout))
-    ui_out_field_string (uiout, "reason",
+      && ui_out_is_mi_like_p (current_uiout))
+    ui_out_field_string (current_uiout, "reason",
                          async_reason_lookup (EXEC_ASYNC_END_STEPPING_RANGE));
 }
 
@@ -5584,6 +5808,8 @@ print_end_stepping_range_reason (void)
 static void
 print_signal_exited_reason (enum target_signal siggnal)
 {
+  struct ui_out *uiout = current_uiout;
+
   annotate_signalled ();
   if (ui_out_is_mi_like_p (uiout))
     ui_out_field_string
@@ -5609,6 +5835,7 @@ print_exited_reason (int exitstatus)
 {
   struct inferior *inf = current_inferior ();
   const char *pidstr = target_pid_to_str (pid_to_ptid (inf->pid));
+  struct ui_out *uiout = current_uiout;
 
   annotate_exited (exitstatus);
   if (exitstatus)
@@ -5645,6 +5872,8 @@ print_exited_reason (int exitstatus)
 static void
 print_signal_received_reason (enum target_signal siggnal)
 {
+  struct ui_out *uiout = current_uiout;
+
   annotate_signal ();
 
   if (siggnal == TARGET_SIGNAL_0 && !ui_out_is_mi_like_p (uiout))
@@ -5682,7 +5911,7 @@ print_signal_received_reason (enum target_signal siggnal)
 static void
 print_no_history_reason (void)
 {
-  ui_out_text (uiout, "\nNo more reverse-execution history.\n");
+  ui_out_text (current_uiout, "\nNo more reverse-execution history.\n");
 }
 
 /* Here to return control to GDB when the inferior stops for real.
@@ -5709,7 +5938,8 @@ normal_stop (void)
   if (!non_stop)
     make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
   else if (last.kind != TARGET_WAITKIND_SIGNALLED
-          && last.kind != TARGET_WAITKIND_EXITED)
+          && last.kind != TARGET_WAITKIND_EXITED
+          && last.kind != TARGET_WAITKIND_NO_RESUMED)
     make_cleanup (finish_thread_state_cleanup, &inferior_ptid);
 
   /* In non-stop mode, we don't want GDB to switch threads behind the
@@ -5728,7 +5958,8 @@ normal_stop (void)
       && !ptid_equal (previous_inferior_ptid, inferior_ptid)
       && target_has_execution
       && last.kind != TARGET_WAITKIND_SIGNALLED
-      && last.kind != TARGET_WAITKIND_EXITED)
+      && last.kind != TARGET_WAITKIND_EXITED
+      && last.kind != TARGET_WAITKIND_NO_RESUMED)
     {
       target_terminal_ours_for_output ();
       printf_filtered (_("[Switching to %s]\n"),
@@ -5737,6 +5968,14 @@ normal_stop (void)
       previous_inferior_ptid = inferior_ptid;
     }
 
+  if (last.kind == TARGET_WAITKIND_NO_RESUMED)
+    {
+      gdb_assert (sync_execution || !target_can_async_p ());
+
+      target_terminal_ours_for_output ();
+      printf_filtered (_("No unwaited-for children left.\n"));
+    }
+
   if (!breakpoints_always_inserted_mode () && target_has_execution)
     {
       if (remove_breakpoints ())
@@ -5764,6 +6003,7 @@ normal_stop (void)
     goto done;
 
   target_terminal_ours ();
+  async_enable_stdin ();
 
   /* Set the current source location.  This will also happen if we
      display the frame below, but the current SAL will be incorrect
@@ -5812,22 +6052,10 @@ normal_stop (void)
          int do_frame_printing = 1;
          struct thread_info *tp = inferior_thread ();
 
-         bpstat_ret = bpstat_print (tp->control.stop_bpstat);
+         bpstat_ret = bpstat_print (tp->control.stop_bpstat, last.kind);
          switch (bpstat_ret)
            {
            case PRINT_UNKNOWN:
-             /* If we had hit a shared library event breakpoint,
-                bpstat_print would print out this message.  If we hit
-                an OS-level shared library event, do the same
-                thing.  */
-             if (last.kind == TARGET_WAITKIND_LOADED)
-               {
-                 printf_filtered (_("Stopped due to shared library event\n"));
-                 source_flag = SRC_LINE;       /* something bogus */
-                 do_frame_printing = 0;
-                 break;
-               }
-
              /* 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.  */
@@ -5922,7 +6150,9 @@ done:
   if (!target_has_execution
       || last.kind == TARGET_WAITKIND_SIGNALLED
       || last.kind == TARGET_WAITKIND_EXITED
-      || (!inferior_thread ()->step_multi
+      || last.kind == TARGET_WAITKIND_NO_RESUMED
+      || (!(inferior_thread ()->step_multi
+           && inferior_thread ()->control.stop_step)
          && !(inferior_thread ()->control.stop_bpstat
               && inferior_thread ()->control.proceed_to_finish)
          && !inferior_thread ()->control.in_infcall))
@@ -6210,6 +6440,7 @@ Are you sure you want to change it? "),
       {
        signal_cache_update (-1);
        target_pass_signals ((int) TARGET_SIGNAL_LAST, signal_pass);
+       target_program_signals ((int) TARGET_SIGNAL_LAST, signal_program);
 
        if (from_tty)
          {
@@ -6292,6 +6523,15 @@ xdb_handle_command (char *args, int from_tty)
   do_cleanups (old_chain);
 }
 
+enum target_signal
+target_signal_from_command (int num)
+{
+  if (num >= 1 && num <= 15)
+    return (enum target_signal) num;
+  error (_("Only signals 1-15 are valid as numeric signals.\n\
+Use \"info signals\" for a list of symbolic signals."));
+}
+
 /* 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
@@ -6335,6 +6575,25 @@ signals_info (char *signum_exp, int from_tty)
                     "to change these tables.\n"));
 }
 
+/* Check if it makes sense to read $_siginfo from the current thread
+   at this point.  If not, throw an error.  */
+
+static void
+validate_siginfo_access (void)
+{
+  /* No current inferior, no siginfo.  */
+  if (ptid_equal (inferior_ptid, null_ptid))
+    error (_("No thread selected."));
+
+  /* Don't try to read from a dead thread.  */
+  if (is_exited (inferior_ptid))
+    error (_("The current thread has terminated"));
+
+  /* ... or from a spinning thread.  */
+  if (is_running (inferior_ptid))
+    error (_("Selected thread is running."));
+}
+
 /* The $_siginfo convenience variable is a bit special.  We don't know
    for sure the type of the value until we actually have a chance to
    fetch the data.  The type can change depending on gdbarch, so it is
@@ -6353,6 +6612,8 @@ siginfo_value_read (struct value *v)
 {
   LONGEST transferred;
 
+  validate_siginfo_access ();
+
   transferred =
     target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO,
                 NULL,
@@ -6372,6 +6633,8 @@ siginfo_value_write (struct value *v, struct value *fromval)
 {
   LONGEST transferred;
 
+  validate_siginfo_access ();
+
   transferred = target_write (&current_target,
                              TARGET_OBJECT_SIGNAL_INFO,
                              NULL,
@@ -6383,7 +6646,7 @@ siginfo_value_write (struct value *v, struct value *fromval)
     error (_("Unable to write siginfo"));
 }
 
-static struct lval_funcs siginfo_value_funcs =
+static const struct lval_funcs siginfo_value_funcs =
   {
     siginfo_value_read,
     siginfo_value_write
@@ -6394,7 +6657,8 @@ static struct lval_funcs siginfo_value_funcs =
    if there's no object available.  */
 
 static struct value *
-siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var)
+siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var,
+                   void *ignore)
 {
   if (target_has_stack
       && !ptid_equal (inferior_ptid, null_ptid)
@@ -6690,150 +6954,6 @@ discard_infcall_control_state (struct infcall_control_state *inf_status)
   xfree (inf_status);
 }
 \f
-int
-inferior_has_forked (ptid_t pid, ptid_t *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_equal (last_ptid, pid))
-    return 0;
-
-  *child_pid = last.value.related_pid;
-  return 1;
-}
-
-int
-inferior_has_vforked (ptid_t pid, ptid_t *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_equal (last_ptid, pid))
-    return 0;
-
-  *child_pid = last.value.related_pid;
-  return 1;
-}
-
-int
-inferior_has_execd (ptid_t 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_equal (last_ptid, pid))
-    return 0;
-
-  *execd_pathname = xstrdup (last.value.execd_pathname);
-  return 1;
-}
-
-int
-inferior_has_called_syscall (ptid_t pid, int *syscall_number)
-{
-  struct target_waitstatus last;
-  ptid_t last_ptid;
-
-  get_last_target_status (&last_ptid, &last);
-
-  if (last.kind != TARGET_WAITKIND_SYSCALL_ENTRY &&
-      last.kind != TARGET_WAITKIND_SYSCALL_RETURN)
-    return 0;
-
-  if (!ptid_equal (last_ptid, pid))
-    return 0;
-
-  *syscall_number = last.value.syscall_number;
-  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);
-}
-
-/* Returns true if PTID represents a process.  */
-
-int
-ptid_is_pid (ptid_t ptid)
-{
-  if (ptid_equal (minus_one_ptid, ptid))
-    return 0;
-  if (ptid_equal (null_ptid, ptid))
-    return 0;
-
-  return (ptid_get_lwp (ptid) == 0 && ptid_get_tid (ptid) == 0);
-}
-
 int
 ptid_match (ptid_t ptid, ptid_t filter)
 {
@@ -6884,7 +7004,7 @@ int execution_direction = EXEC_FORWARD;
 static const char exec_forward[] = "forward";
 static const char exec_reverse[] = "reverse";
 static const char *exec_direction = exec_forward;
-static const char *exec_direction_names[] = {
+static const char *const exec_direction_names[] = {
   exec_forward,
   exec_reverse,
   NULL
@@ -6960,6 +7080,15 @@ show_schedule_multiple (struct ui_file *file, int from_tty,
                            "of all processes is %s.\n"), value);
 }
 
+/* Implementation of `siginfo' variable.  */
+
+static const struct internalvar_funcs siginfo_funcs =
+{
+  siginfo_make_value,
+  NULL,
+  NULL
+};
+
 void
 _initialize_infrun (void)
 {
@@ -7222,9 +7351,20 @@ Show whether gdb will detach the child of a fork."), _("\
 Tells gdb whether to detach the child of a fork."),
                           NULL, NULL, &setlist, &showlist);
 
+  /* Set/show disable address space randomization mode.  */
+
+  add_setshow_boolean_cmd ("disable-randomization", class_support,
+                          &disable_randomization, _("\
+Set disabling of debuggee's virtual address space randomization."), _("\
+Show disabling of debuggee's virtual address space randomization."), _("\
+When this mode is on (which is the default), randomization of the virtual\n\
+address space is disabled.  Standalone programs run with the randomization\n\
+enabled by default on some platforms."),
+                          &set_disable_randomization,
+                          &show_disable_randomization,
+                          &setlist, &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;
 
@@ -7237,7 +7377,7 @@ Tells gdb whether to detach the child of a fork."),
      value with a void typed value, and when we get here, gdbarch
      isn't initialized yet.  At this point, we're quite sure there
      isn't another convenience variable of the same name.  */
-  create_internalvar_type_lazy ("_siginfo", siginfo_make_value);
+  create_internalvar_type_lazy ("_siginfo", &siginfo_funcs, NULL);
 
   add_setshow_boolean_cmd ("observer", no_class,
                           &observer_mode_1, _("\
This page took 0.04271 seconds and 4 git commands to generate.