2011-01-08 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / linux-nat.c
index 81802489074547625af200f696c3c1bc6f131f62..c769010f99e250aaf9fa7e667307719d02601ae3 100644 (file)
@@ -1,7 +1,7 @@
 /* GNU/Linux native-dependent code common to multiple platforms.
 
 /* GNU/Linux native-dependent code common to multiple platforms.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
 #include "inf-ptrace.h"
 #include "auxv.h"
 #include <sys/param.h>         /* for MAXPATHLEN */
 #include "inf-ptrace.h"
 #include "auxv.h"
 #include <sys/param.h>         /* for MAXPATHLEN */
-#include <sys/procfs.h>                /* for elf_gregset etc. */
+#include <sys/procfs.h>                /* for elf_gregset etc.  */
 #include "elf-bfd.h"           /* for elfcore_write_* */
 #include "gregset.h"           /* for gregset */
 #include "gdbcore.h"           /* for get_exec_file */
 #include <ctype.h>             /* for isdigit */
 #include "elf-bfd.h"           /* for elfcore_write_* */
 #include "gregset.h"           /* for gregset */
 #include "gdbcore.h"           /* for get_exec_file */
 #include <ctype.h>             /* for isdigit */
-#include "gdbthread.h"         /* for struct thread_info etc. */
+#include "gdbthread.h"         /* for struct thread_info etc.  */
 #include "gdb_stat.h"          /* for struct stat */
 #include <fcntl.h>             /* for O_RDONLY */
 #include "inf-loop.h"
 #include "gdb_stat.h"          /* for struct stat */
 #include <fcntl.h>             /* for O_RDONLY */
 #include "inf-loop.h"
@@ -68,7 +68,7 @@
 # endif
 #endif /* HAVE_PERSONALITY */
 
 # endif
 #endif /* HAVE_PERSONALITY */
 
-/* This comment documents high-level logic of this file. 
+/* This comment documents high-level logic of this file.
 
 Waiting for events in sync mode
 ===============================
 
 Waiting for events in sync mode
 ===============================
@@ -76,20 +76,21 @@ Waiting for events in sync mode
 When waiting for an event in a specific thread, we just use waitpid, passing
 the specific pid, and not passing WNOHANG.
 
 When waiting for an event in a specific thread, we just use waitpid, passing
 the specific pid, and not passing WNOHANG.
 
-When waiting for an event in all threads, waitpid is not quite good. Prior to
+When waiting for an event in all threads, waitpid is not quite good.  Prior to
 version 2.4, Linux can either wait for event in main thread, or in secondary
 version 2.4, Linux can either wait for event in main thread, or in secondary
-threads. (2.4 has the __WALL flag).  So, if we use blocking waitpid, we might
+threads.  (2.4 has the __WALL flag).  So, if we use blocking waitpid, we might
 miss an event.  The solution is to use non-blocking waitpid, together with
 sigsuspend.  First, we use non-blocking waitpid to get an event in the main 
 miss an event.  The solution is to use non-blocking waitpid, together with
 sigsuspend.  First, we use non-blocking waitpid to get an event in the main 
-process, if any. Second, we use non-blocking waitpid with the __WCLONED
+process, if any.  Second, we use non-blocking waitpid with the __WCLONED
 flag to check for events in cloned processes.  If nothing is found, we use
 sigsuspend to wait for SIGCHLD.  When SIGCHLD arrives, it means something
 happened to a child process -- and SIGCHLD will be delivered both for events
 in main debugged process and in cloned processes.  As soon as we know there's
 flag to check for events in cloned processes.  If nothing is found, we use
 sigsuspend to wait for SIGCHLD.  When SIGCHLD arrives, it means something
 happened to a child process -- and SIGCHLD will be delivered both for events
 in main debugged process and in cloned processes.  As soon as we know there's
-an event, we get back to calling nonblocking waitpid with and without __WCLONED.
+an event, we get back to calling nonblocking waitpid with and without 
+__WCLONED.
 
 Note that SIGCHLD should be blocked between waitpid and sigsuspend calls,
 
 Note that SIGCHLD should be blocked between waitpid and sigsuspend calls,
-so that we don't miss a signal. If SIGCHLD arrives in between, when it's
+so that we don't miss a signal.  If SIGCHLD arrives in between, when it's
 blocked, the signal becomes pending and sigsuspend immediately
 notices it and returns.
 
 blocked, the signal becomes pending and sigsuspend immediately
 notices it and returns.
 
@@ -166,7 +167,7 @@ blocked.  */
 #define PTRACE_SETOPTIONS      0x4200
 #define PTRACE_GETEVENTMSG     0x4201
 
 #define PTRACE_SETOPTIONS      0x4200
 #define PTRACE_GETEVENTMSG     0x4201
 
-/* options set using PTRACE_SETOPTIONS */
+/* Options set using PTRACE_SETOPTIONS.  */
 #define PTRACE_O_TRACESYSGOOD  0x00000001
 #define PTRACE_O_TRACEFORK     0x00000002
 #define PTRACE_O_TRACEVFORK    0x00000004
 #define PTRACE_O_TRACESYSGOOD  0x00000001
 #define PTRACE_O_TRACEFORK     0x00000002
 #define PTRACE_O_TRACEVFORK    0x00000004
@@ -239,7 +240,8 @@ static void
 show_debug_linux_nat_async (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
 {
 show_debug_linux_nat_async (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Debugging of GNU/Linux async lwp module is %s.\n"),
+  fprintf_filtered (file,
+                   _("Debugging of GNU/Linux async lwp module is %s.\n"),
                    value);
 }
 
                    value);
 }
 
@@ -250,23 +252,25 @@ show_disable_randomization (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
 {
 #ifdef HAVE_PERSONALITY
                            struct cmd_list_element *c, const char *value)
 {
 #ifdef HAVE_PERSONALITY
-  fprintf_filtered (file, _("\
-Disabling randomization of debuggee's virtual address space is %s.\n"),
+  fprintf_filtered (file,
+                   _("Disabling randomization of debuggee's "
+                     "virtual address space is %s.\n"),
                    value);
 #else /* !HAVE_PERSONALITY */
                    value);
 #else /* !HAVE_PERSONALITY */
-  fputs_filtered (_("\
-Disabling randomization of debuggee's virtual address space is unsupported on\n\
-this platform.\n"), file);
+  fputs_filtered (_("Disabling randomization of debuggee's "
+                   "virtual address space is unsupported on\n"
+                   "this platform.\n"), file);
 #endif /* !HAVE_PERSONALITY */
 }
 
 static void
 #endif /* !HAVE_PERSONALITY */
 }
 
 static void
-set_disable_randomization (char *args, int from_tty, struct cmd_list_element *c)
+set_disable_randomization (char *args, int from_tty,
+                          struct cmd_list_element *c)
 {
 #ifndef HAVE_PERSONALITY
 {
 #ifndef HAVE_PERSONALITY
-  error (_("\
-Disabling randomization of debuggee's virtual address space is unsupported on\n\
-this platform."));
+  error (_("Disabling randomization of debuggee's "
+          "virtual address space is unsupported on\n"
+          "this platform."));
 #endif /* !HAVE_PERSONALITY */
 }
 
 #endif /* !HAVE_PERSONALITY */
 }
 
@@ -283,8 +287,8 @@ struct simple_pid_list *stopped_pids;
 
 static int linux_supports_tracefork_flag = -1;
 
 
 static int linux_supports_tracefork_flag = -1;
 
-/* This variable is a tri-state flag: -1 for unknown, 0 if PTRACE_O_TRACESYSGOOD
-   can not be used, 1 if it can.  */
+/* This variable is a tri-state flag: -1 for unknown, 0 if
+   PTRACE_O_TRACESYSGOOD can not be used, 1 if it can.  */
 
 static int linux_supports_tracesysgood_flag = -1;
 
 
 static int linux_supports_tracesysgood_flag = -1;
 
@@ -293,7 +297,7 @@ static int linux_supports_tracesysgood_flag = -1;
 
 static int linux_supports_tracevforkdone_flag = -1;
 
 
 static int linux_supports_tracevforkdone_flag = -1;
 
-/* Async mode support */
+/* Async mode support */
 
 /* Zero if the async mode, although enabled, is masked, which means
    linux_nat_wait should behave as if async mode was off.  */
 
 /* Zero if the async mode, although enabled, is masked, which means
    linux_nat_wait should behave as if async mode was off.  */
@@ -346,7 +350,8 @@ async_file_mark (void)
 }
 
 static void linux_nat_async (void (*callback)
 }
 
 static void linux_nat_async (void (*callback)
-                            (enum inferior_event_type event_type, void *context),
+                            (enum inferior_event_type event_type,
+                             void *context),
                             void *context);
 static int linux_nat_async_mask (int mask);
 static int kill_lwp (int lwpid, int signo);
                             void *context);
 static int linux_nat_async_mask (int mask);
 static int kill_lwp (int lwpid, int signo);
@@ -376,7 +381,7 @@ add_to_pid_list (struct simple_pid_list **listp, int pid, int status)
 }
 
 static int
 }
 
 static int
-pull_pid_from_list (struct simple_pid_list **listp, int pid, int *status)
+pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp)
 {
   struct simple_pid_list **p;
 
 {
   struct simple_pid_list **p;
 
@@ -385,7 +390,7 @@ pull_pid_from_list (struct simple_pid_list **listp, int pid, int *status)
       {
        struct simple_pid_list *next = (*p)->next;
 
       {
        struct simple_pid_list *next = (*p)->next;
 
-       *status = (*p)->status;
+       *statusp = (*p)->status;
        xfree (*p);
        *p = next;
        return 1;
        xfree (*p);
        *p = next;
        return 1;
@@ -414,13 +419,13 @@ linux_tracefork_child (void)
 /* Wrapper function for waitpid which handles EINTR.  */
 
 static int
 /* Wrapper function for waitpid which handles EINTR.  */
 
 static int
-my_waitpid (int pid, int *status, int flags)
+my_waitpid (int pid, int *statusp, int flags)
 {
   int ret;
 
   do
     {
 {
   int ret;
 
   do
     {
-      ret = waitpid (pid, status, flags);
+      ret = waitpid (pid, statusp, flags);
     }
   while (ret == -1 && errno == EINTR);
 
     }
   while (ret == -1 && errno == EINTR);
 
@@ -473,7 +478,8 @@ linux_test_for_tracefork (int original_pid)
   else if (ret != child_pid)
     error (_("linux_test_for_tracefork: waitpid: unexpected result %d."), ret);
   if (! WIFSTOPPED (status))
   else if (ret != child_pid)
     error (_("linux_test_for_tracefork: waitpid: unexpected result %d."), ret);
   if (! WIFSTOPPED (status))
-    error (_("linux_test_for_tracefork: waitpid: unexpected status %d."), status);
+    error (_("linux_test_for_tracefork: waitpid: unexpected status %d."),
+          status);
 
   ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK);
   if (ret != 0)
 
   ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK);
   if (ret != 0)
@@ -488,10 +494,11 @@ linux_test_for_tracefork (int original_pid)
 
       ret = my_waitpid (child_pid, &status, 0);
       if (ret != child_pid)
 
       ret = my_waitpid (child_pid, &status, 0);
       if (ret != child_pid)
-       warning (_("linux_test_for_tracefork: failed to wait for killed child"));
+       warning (_("linux_test_for_tracefork: failed "
+                  "to wait for killed child"));
       else if (!WIFSIGNALED (status))
       else if (!WIFSIGNALED (status))
-       warning (_("linux_test_for_tracefork: unexpected wait status 0x%x from "
-                "killed child"), status);
+       warning (_("linux_test_for_tracefork: unexpected "
+                  "wait status 0x%x from killed child"), status);
 
       restore_child_signals_mask (&prev_mask);
       return;
 
       restore_child_signals_mask (&prev_mask);
       return;
@@ -521,7 +528,8 @@ linux_test_for_tracefork (int original_pid)
          my_waitpid (second_pid, &second_status, 0);
          ret = ptrace (PTRACE_KILL, second_pid, 0, 0);
          if (ret != 0)
          my_waitpid (second_pid, &second_status, 0);
          ret = ptrace (PTRACE_KILL, second_pid, 0, 0);
          if (ret != 0)
-           warning (_("linux_test_for_tracefork: failed to kill second child"));
+           warning (_("linux_test_for_tracefork: "
+                      "failed to kill second child"));
          my_waitpid (second_pid, &status, 0);
        }
     }
          my_waitpid (second_pid, &status, 0);
        }
     }
@@ -679,9 +687,10 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child)
         in the foreground, the user will not be able to ctrl-c to get
         back the terminal, effectively hanging the debug session.  */
       fprintf_filtered (gdb_stderr, _("\
         in the foreground, the user will not be able to ctrl-c to get
         back the terminal, effectively hanging the debug session.  */
       fprintf_filtered (gdb_stderr, _("\
-Can not resume the parent process over vfork in the foreground while \n\
+Can not resume the parent process over vfork in the foreground while\n\
 holding the child stopped.  Try \"set detach-on-fork\" or \
 \"set schedule-multiple\".\n"));
 holding the child stopped.  Try \"set detach-on-fork\" or \
 \"set schedule-multiple\".\n"));
+      /* FIXME output string > 80 columns.  */
       return 1;
     }
 
       return 1;
     }
 
@@ -689,7 +698,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
     {
       struct lwp_info *child_lp = NULL;
 
     {
       struct lwp_info *child_lp = NULL;
 
-      /* We're already attached to the parent, by default. */
+      /* We're already attached to the parent, by default.  */
 
       /* Detach new forked process?  */
       if (detach_fork)
 
       /* Detach new forked process?  */
       if (detach_fork)
@@ -711,7 +720,8 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
            {
              target_terminal_ours ();
              fprintf_filtered (gdb_stdlog,
            {
              target_terminal_ours ();
              fprintf_filtered (gdb_stdlog,
-                               "Detaching after fork from child process %d.\n",
+                               "Detaching after fork from "
+                               "child process %d.\n",
                                child_pid);
            }
 
                                child_pid);
            }
 
@@ -843,7 +853,8 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 
              if (debug_linux_nat)
                fprintf_unfiltered (gdb_stdlog,
 
              if (debug_linux_nat)
                fprintf_unfiltered (gdb_stdlog,
-                                   "LCFF: no VFORK_DONE support, sleeping a bit\n");
+                                   "LCFF: no VFORK_DONE "
+                                   "support, sleeping a bit\n");
 
              usleep (10000);
 
 
              usleep (10000);
 
@@ -873,12 +884,14 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
        {
          target_terminal_ours ();
          if (has_vforked)
        {
          target_terminal_ours ();
          if (has_vforked)
-           fprintf_filtered (gdb_stdlog, _("\
-Attaching after process %d vfork to child process %d.\n"),
+           fprintf_filtered (gdb_stdlog,
+                             _("Attaching after process %d "
+                               "vfork to child process %d.\n"),
                              parent_pid, child_pid);
          else
                              parent_pid, child_pid);
          else
-           fprintf_filtered (gdb_stdlog, _("\
-Attaching after process %d fork to child process %d.\n"),
+           fprintf_filtered (gdb_stdlog,
+                             _("Attaching after process %d "
+                               "fork to child process %d.\n"),
                              parent_pid, child_pid);
        }
 
                              parent_pid, child_pid);
        }
 
@@ -1073,7 +1086,6 @@ restore_child_signals_mask (sigset_t *prev_mask)
 static int stop_wait_callback (struct lwp_info *lp, void *data);
 static int linux_thread_alive (ptid_t ptid);
 static char *linux_child_pid_to_exec_file (int pid);
 static int stop_wait_callback (struct lwp_info *lp, void *data);
 static int linux_thread_alive (ptid_t ptid);
 static char *linux_child_pid_to_exec_file (int pid);
-static int cancel_breakpoint (struct lwp_info *lp);
 
 \f
 /* Convert wait status STATUS to a string.  Used for printing debug
 
 \f
 /* Convert wait status STATUS to a string.  Used for printing debug
@@ -1095,7 +1107,7 @@ status_to_str (int status)
     }
   else if (WIFSIGNALED (status))
     snprintf (buf, sizeof (buf), "%s (terminated)",
     }
   else if (WIFSIGNALED (status))
     snprintf (buf, sizeof (buf), "%s (terminated)",
-             strsignal (WSTOPSIG (status)));
+             strsignal (WTERMSIG (status)));
   else
     snprintf (buf, sizeof (buf), "%d (exited)", WEXITSTATUS (status));
 
   else
     snprintf (buf, sizeof (buf), "%d (exited)", WEXITSTATUS (status));
 
@@ -1649,7 +1661,7 @@ get_pending_status (struct lwp_info *lp, int *status)
     {
       struct thread_info *tp = find_thread_ptid (lp->ptid);
 
     {
       struct thread_info *tp = find_thread_ptid (lp->ptid);
 
-      signo = tp->stop_signal;
+      signo = tp->suspend.stop_signal;
     }
   else if (!non_stop)
     {
     }
   else if (!non_stop)
     {
@@ -1662,7 +1674,7 @@ get_pending_status (struct lwp_info *lp, int *status)
        {
          struct thread_info *tp = find_thread_ptid (lp->ptid);
 
        {
          struct thread_info *tp = find_thread_ptid (lp->ptid);
 
-         signo = tp->stop_signal;
+         signo = tp->suspend.stop_signal;
        }
     }
 
        }
     }
 
@@ -1678,8 +1690,9 @@ get_pending_status (struct lwp_info *lp, int *status)
   else if (!signal_pass_state (signo))
     {
       if (debug_linux_nat)
   else if (!signal_pass_state (signo))
     {
       if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog, "\
-GPT: lwp %s had signal %s, but it is in no pass state\n",
+       fprintf_unfiltered (gdb_stdlog,
+                           "GPT: lwp %s had signal %s, "
+                           "but it is in no pass state\n",
                            target_pid_to_str (lp->ptid),
                            target_signal_to_string (signo));
     }
                            target_pid_to_str (lp->ptid),
                            target_signal_to_string (signo));
     }
@@ -1839,10 +1852,12 @@ resume_callback (struct lwp_info *lp, void *data)
       lp->stopped_by_watchpoint = 0;
     }
   else if (lp->stopped && debug_linux_nat)
       lp->stopped_by_watchpoint = 0;
     }
   else if (lp->stopped && debug_linux_nat)
-    fprintf_unfiltered (gdb_stdlog, "RC: Not resuming sibling %s (has pending)\n",
+    fprintf_unfiltered (gdb_stdlog,
+                       "RC: Not resuming sibling %s (has pending)\n",
                        target_pid_to_str (lp->ptid));
   else if (debug_linux_nat)
                        target_pid_to_str (lp->ptid));
   else if (debug_linux_nat)
-    fprintf_unfiltered (gdb_stdlog, "RC: Not resuming sibling %s (not stopped)\n",
+    fprintf_unfiltered (gdb_stdlog,
+                       "RC: Not resuming sibling %s (not stopped)\n",
                        target_pid_to_str (lp->ptid));
 
   return 0;
                        target_pid_to_str (lp->ptid));
 
   return 0;
@@ -1875,7 +1890,8 @@ linux_nat_resume (struct target_ops *ops,
                        "LLR: Preparing to %s %s, %s, inferior_ptid %s\n",
                        step ? "step" : "resume",
                        target_pid_to_str (ptid),
                        "LLR: Preparing to %s %s, %s, inferior_ptid %s\n",
                        step ? "step" : "resume",
                        target_pid_to_str (ptid),
-                       signo ? strsignal (signo) : "0",
+                       (signo != TARGET_SIGNAL_0
+                        ? strsignal (target_signal_to_host (signo)) : "0"),
                        target_pid_to_str (inferior_ptid));
 
   block_child_signals (&prev_mask);
                        target_pid_to_str (inferior_ptid));
 
   block_child_signals (&prev_mask);
@@ -1908,7 +1924,7 @@ linux_nat_resume (struct target_ops *ops,
 
   if (lp->status && WIFSTOPPED (lp->status))
     {
 
   if (lp->status && WIFSTOPPED (lp->status))
     {
-      int saved_signo;
+      enum target_signal saved_signo;
       struct inferior *inf;
 
       inf = find_inferior_pid (ptid_get_pid (lp->ptid));
       struct inferior *inf;
 
       inf = find_inferior_pid (ptid_get_pid (lp->ptid));
@@ -1917,7 +1933,7 @@ linux_nat_resume (struct target_ops *ops,
 
       /* Defer to common code if we're gaining control of the
         inferior.  */
 
       /* Defer to common code if we're gaining control of the
         inferior.  */
-      if (inf->stop_soon == NO_STOP_QUIETLY
+      if (inf->control.stop_soon == NO_STOP_QUIETLY
          && signal_stop_state (saved_signo) == 0
          && signal_print_state (saved_signo) == 0
          && signal_pass_state (saved_signo) == 1)
          && signal_stop_state (saved_signo) == 0
          && signal_print_state (saved_signo) == 0
          && signal_pass_state (saved_signo) == 1)
@@ -1975,7 +1991,8 @@ linux_nat_resume (struct target_ops *ops,
                        "LLR: %s %s, %s (resume event thread)\n",
                        step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
                        target_pid_to_str (ptid),
                        "LLR: %s %s, %s (resume event thread)\n",
                        step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
                        target_pid_to_str (ptid),
-                       signo ? strsignal (signo) : "0");
+                       (signo != TARGET_SIGNAL_0
+                        ? strsignal (target_signal_to_host (signo)) : "0"));
 
   restore_child_signals_mask (&prev_mask);
   if (target_can_async_p ())
 
   restore_child_signals_mask (&prev_mask);
   if (target_can_async_p ())
@@ -2079,7 +2096,8 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping)
            fprintf_unfiltered (gdb_stdlog,
                                "LHST: stopping for %s of syscall %d"
                                " for LWP %ld\n",
            fprintf_unfiltered (gdb_stdlog,
                                "LHST: stopping for %s of syscall %d"
                                " for LWP %ld\n",
-                               lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY
+                               lp->syscall_state
+                               == TARGET_WAITKIND_SYSCALL_ENTRY
                                ? "entry" : "return",
                                syscall_number,
                                GET_LWP (lp->ptid));
                                ? "entry" : "return",
                                syscall_number,
                                GET_LWP (lp->ptid));
@@ -2115,7 +2133,8 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping)
         PT_CONTINUE, can not trigger a syscall trace event.  */
       if (debug_linux_nat)
        fprintf_unfiltered (gdb_stdlog,
         PT_CONTINUE, can not trigger a syscall trace event.  */
       if (debug_linux_nat)
        fprintf_unfiltered (gdb_stdlog,
-                           "LHST: caught syscall event with no syscall catchpoints."
+                           "LHST: caught syscall event "
+                           "with no syscall catchpoints."
                            " %d for LWP %ld, ignoring\n",
                            syscall_number,
                            GET_LWP (lp->ptid));
                            " %d for LWP %ld, ignoring\n",
                            syscall_number,
                            GET_LWP (lp->ptid));
@@ -2149,7 +2168,6 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
 {
   int pid = GET_LWP (lp->ptid);
   struct target_waitstatus *ourstatus = &lp->waitstatus;
 {
   int pid = GET_LWP (lp->ptid);
   struct target_waitstatus *ourstatus = &lp->waitstatus;
-  struct lwp_info *new_lp = NULL;
   int event = status >> 16;
 
   if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK
   int event = status >> 16;
 
   if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK
@@ -2213,7 +2231,10 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
        ourstatus->kind = TARGET_WAITKIND_VFORKED;
       else
        {
        ourstatus->kind = TARGET_WAITKIND_VFORKED;
       else
        {
+         struct lwp_info *new_lp;
+
          ourstatus->kind = TARGET_WAITKIND_IGNORE;
          ourstatus->kind = TARGET_WAITKIND_IGNORE;
+
          new_lp = add_lwp (BUILD_LWP (new_pid, GET_PID (lp->ptid)));
          new_lp->cloned = 1;
          new_lp->stopped = 1;
          new_lp = add_lwp (BUILD_LWP (new_pid, GET_PID (lp->ptid)));
          new_lp->cloned = 1;
          new_lp->stopped = 1;
@@ -2265,7 +2286,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
             catchpoints.  */
          if (!stopping)
            {
             catchpoints.  */
          if (!stopping)
            {
-             int signo;
+             enum target_signal signo;
 
              new_lp->stopped = 0;
              new_lp->resumed = 1;
 
              new_lp->stopped = 0;
              new_lp->resumed = 1;
@@ -2277,10 +2298,28 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
              linux_ops->to_resume (linux_ops, pid_to_ptid (new_pid),
                                    0, signo);
            }
              linux_ops->to_resume (linux_ops, pid_to_ptid (new_pid),
                                    0, signo);
            }
+         else
+           {
+             if (status != 0)
+               {
+                 /* We created NEW_LP so it cannot yet contain STATUS.  */
+                 gdb_assert (new_lp->status == 0);
+
+                 /* Save the wait status to report later.  */
+                 if (debug_linux_nat)
+                   fprintf_unfiltered (gdb_stdlog,
+                                       "LHEW: waitpid of new LWP %ld, "
+                                       "saving status %s\n",
+                                       (long) GET_LWP (new_lp->ptid),
+                                       status_to_str (status));
+                 new_lp->status = status;
+               }
+           }
 
          if (debug_linux_nat)
            fprintf_unfiltered (gdb_stdlog,
 
          if (debug_linux_nat)
            fprintf_unfiltered (gdb_stdlog,
-                               "LHEW: Got clone event from LWP %ld, resuming\n",
+                               "LHEW: Got clone event "
+                               "from LWP %ld, resuming\n",
                                GET_LWP (lp->ptid));
          linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
                                0, TARGET_SIGNAL_0);
                                GET_LWP (lp->ptid));
          linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
                                0, TARGET_SIGNAL_0);
@@ -2310,8 +2349,9 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
       if (current_inferior ()->waiting_for_vfork_done)
        {
          if (debug_linux_nat)
       if (current_inferior ()->waiting_for_vfork_done)
        {
          if (debug_linux_nat)
-           fprintf_unfiltered (gdb_stdlog, "\
-LHEW: Got expected PTRACE_EVENT_VFORK_DONE from LWP %ld: stopping\n",
+           fprintf_unfiltered (gdb_stdlog,
+                               "LHEW: Got expected PTRACE_EVENT_"
+                               "VFORK_DONE from LWP %ld: stopping\n",
                                GET_LWP (lp->ptid));
 
          ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
                                GET_LWP (lp->ptid));
 
          ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
@@ -2319,8 +2359,9 @@ LHEW: Got expected PTRACE_EVENT_VFORK_DONE from LWP %ld: stopping\n",
        }
 
       if (debug_linux_nat)
        }
 
       if (debug_linux_nat)
-       fprintf_unfiltered (gdb_stdlog, "\
-LHEW: Got PTRACE_EVENT_VFORK_DONE from LWP %ld: resuming\n",
+       fprintf_unfiltered (gdb_stdlog,
+                           "LHEW: Got PTRACE_EVENT_VFORK_DONE "
+                           "from LWP %ld: resuming\n",
                            GET_LWP (lp->ptid));
       ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
       return 1;
                            GET_LWP (lp->ptid));
       ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
       return 1;
@@ -2587,6 +2628,43 @@ linux_nat_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
   return lp->stopped_data_address_p;
 }
 
   return lp->stopped_data_address_p;
 }
 
+/* Commonly any breakpoint / watchpoint generate only SIGTRAP.  */
+
+static int
+sigtrap_is_event (int status)
+{
+  return WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP;
+}
+
+/* SIGTRAP-like events recognizer.  */
+
+static int (*linux_nat_status_is_event) (int status) = sigtrap_is_event;
+
+/* Check for SIGTRAP-like events in LP.  */
+
+static int
+linux_nat_lp_status_is_event (struct lwp_info *lp)
+{
+  /* We check for lp->waitstatus in addition to lp->status, because we can
+     have pending process exits recorded in lp->status
+     and W_EXITCODE(0,0) == 0.  We should probably have an additional
+     lp->status_p flag.  */
+
+  return (lp->waitstatus.kind == TARGET_WAITKIND_IGNORE
+         && linux_nat_status_is_event (lp->status));
+}
+
+/* Set alternative SIGTRAP-like events recognizer.  If
+   breakpoint_inserted_here_p there then gdbarch_decr_pc_after_break will be
+   applied.  */
+
+void
+linux_nat_set_status_is_event (struct target_ops *t,
+                              int (*status_is_event) (int status))
+{
+  linux_nat_status_is_event = status_is_event;
+}
+
 /* Wait until LP is stopped.  */
 
 static int
 /* Wait until LP is stopped.  */
 
 static int
@@ -2616,7 +2694,8 @@ stop_wait_callback (struct lwp_info *lp, void *data)
          ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
          if (debug_linux_nat)
            fprintf_unfiltered (gdb_stdlog,
          ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
          if (debug_linux_nat)
            fprintf_unfiltered (gdb_stdlog,
-                               "PTRACE_CONT %s, 0, 0 (%s) (discarding SIGINT)\n",
+                               "PTRACE_CONT %s, 0, 0 (%s) "
+                               "(discarding SIGINT)\n",
                                target_pid_to_str (lp->ptid),
                                errno ? safe_strerror (errno) : "OK");
 
                                target_pid_to_str (lp->ptid),
                                errno ? safe_strerror (errno) : "OK");
 
@@ -2627,7 +2706,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
 
       if (WSTOPSIG (status) != SIGSTOP)
        {
 
       if (WSTOPSIG (status) != SIGSTOP)
        {
-         if (WSTOPSIG (status) == SIGTRAP)
+         if (linux_nat_status_is_event (status))
            {
              /* If a LWP other than the LWP that we're reporting an
                 event for has hit a GDB breakpoint (as opposed to
            {
              /* If a LWP other than the LWP that we're reporting an
                 event for has hit a GDB breakpoint (as opposed to
@@ -2647,7 +2726,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
 
              save_sigtrap (lp);
 
 
              save_sigtrap (lp);
 
-             /* Now resume this LWP and get the SIGSTOP event. */
+             /* Now resume this LWP and get the SIGSTOP event.  */
              errno = 0;
              ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
              if (debug_linux_nat)
              errno = 0;
              ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
              if (debug_linux_nat)
@@ -2662,12 +2741,12 @@ stop_wait_callback (struct lwp_info *lp, void *data)
                                      target_pid_to_str (lp->ptid));
                }
              /* Hold this event/waitstatus while we check to see if
                                      target_pid_to_str (lp->ptid));
                }
              /* Hold this event/waitstatus while we check to see if
-                there are any more (we still want to get that SIGSTOP). */
+                there are any more (we still want to get that SIGSTOP).  */
              stop_wait_callback (lp, NULL);
 
              /* Hold the SIGTRAP for handling by linux_nat_wait.  If
                 there's another event, throw it back into the
              stop_wait_callback (lp, NULL);
 
              /* Hold the SIGTRAP for handling by linux_nat_wait.  If
                 there's another event, throw it back into the
-                queue. */
+                queue.  */
              if (lp->status)
                {
                  if (debug_linux_nat)
              if (lp->status)
                {
                  if (debug_linux_nat)
@@ -2678,14 +2757,14 @@ stop_wait_callback (struct lwp_info *lp, void *data)
                  kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (lp->status));
                }
 
                  kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (lp->status));
                }
 
-             /* Save the sigtrap event. */
+             /* Save the sigtrap event.  */
              lp->status = status;
              return 0;
            }
          else
            {
              /* The thread was stopped with a signal other than
              lp->status = status;
              return 0;
            }
          else
            {
              /* The thread was stopped with a signal other than
-                SIGSTOP, and didn't accidentally trip a breakpoint. */
+                SIGSTOP, and didn't accidentally trip a breakpoint.  */
 
              if (debug_linux_nat)
                {
 
              if (debug_linux_nat)
                {
@@ -2694,7 +2773,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
                                      status_to_str ((int) status),
                                      target_pid_to_str (lp->ptid));
                }
                                      status_to_str ((int) status),
                                      target_pid_to_str (lp->ptid));
                }
-             /* Now resume this LWP and get the SIGSTOP event. */
+             /* Now resume this LWP and get the SIGSTOP event.  */
              errno = 0;
              ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
              if (debug_linux_nat)
              errno = 0;
              ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
              if (debug_linux_nat)
@@ -2704,7 +2783,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
                                    errno ? safe_strerror (errno) : "OK");
 
              /* Hold this event/waitstatus while we check to see if
                                    errno ? safe_strerror (errno) : "OK");
 
              /* Hold this event/waitstatus while we check to see if
-                there are any more (we still want to get that SIGSTOP). */
+                there are any more (we still want to get that SIGSTOP).  */
              stop_wait_callback (lp, NULL);
 
              /* If the lp->status field is still empty, use it to
              stop_wait_callback (lp, NULL);
 
              /* If the lp->status field is still empty, use it to
@@ -2782,8 +2861,7 @@ count_events_callback (struct lwp_info *lp, void *data)
   gdb_assert (count != NULL);
 
   /* Count only resumed LWPs that have a SIGTRAP event pending.  */
   gdb_assert (count != NULL);
 
   /* Count only resumed LWPs that have a SIGTRAP event pending.  */
-  if (lp->status != 0 && lp->resumed
-      && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP)
+  if (lp->resumed && linux_nat_lp_status_is_event (lp))
     (*count)++;
 
   return 0;
     (*count)++;
 
   return 0;
@@ -2809,9 +2887,8 @@ select_event_lwp_callback (struct lwp_info *lp, void *data)
 
   gdb_assert (selector != NULL);
 
 
   gdb_assert (selector != NULL);
 
-  /* Select only resumed LWPs that have a SIGTRAP event pending. */
-  if (lp->status != 0 && lp->resumed
-      && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP)
+  /* Select only resumed LWPs that have a SIGTRAP event pending.  */
+  if (lp->resumed && linux_nat_lp_status_is_event (lp))
     if ((*selector)-- == 0)
       return 1;
 
     if ((*selector)-- == 0)
       return 1;
 
@@ -2871,9 +2948,7 @@ cancel_breakpoints_callback (struct lwp_info *lp, void *data)
      delete or disable the breakpoint, but the LWP will have already
      tripped on it.  */
 
      delete or disable the breakpoint, but the LWP will have already
      tripped on it.  */
 
-  if (lp->waitstatus.kind == TARGET_WAITKIND_IGNORE
-      && lp->status != 0
-      && WIFSTOPPED (lp->status) && WSTOPSIG (lp->status) == SIGTRAP
+  if (linux_nat_lp_status_is_event (lp)
       && cancel_breakpoint (lp))
     /* Throw away the SIGTRAP.  */
     lp->status = 0;
       && cancel_breakpoint (lp))
     /* Throw away the SIGTRAP.  */
     lp->status = 0;
@@ -2990,7 +3065,7 @@ linux_nat_filter_event (int lwpid, int status, int options)
     }
 
   /* Make sure we don't report an event for the exit of an LWP not in
     }
 
   /* Make sure we don't report an event for the exit of an LWP not in
-     our list, i.e.  not part of the current process.  This can happen
+     our list, i.e. not part of the current process.  This can happen
      if we detach from a program we original forked and then it
      exits.  */
   if (!WIFSTOPPED (status) && !lp)
      if we detach from a program we original forked and then it
      exits.  */
   if (!WIFSTOPPED (status) && !lp)
@@ -3046,7 +3121,7 @@ linux_nat_filter_event (int lwpid, int status, int options)
        return NULL;
     }
 
        return NULL;
     }
 
-  if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP)
+  if (linux_nat_status_is_event (status))
     {
       /* Save the trap's siginfo in case we need it later.  */
       save_siginfo (lp);
     {
       /* Save the trap's siginfo in case we need it later.  */
       save_siginfo (lp);
@@ -3365,6 +3440,9 @@ retry:
 
          lp = linux_nat_filter_event (lwpid, status, options);
 
 
          lp = linux_nat_filter_event (lwpid, status, options);
 
+         /* STATUS is now no longer valid, use LP->STATUS instead.  */
+         status = 0;
+
          if (lp
              && ptid_is_pid (ptid)
              && ptid_get_pid (lp->ptid) != ptid_get_pid (ptid))
          if (lp
              && ptid_is_pid (ptid)
              && ptid_get_pid (lp->ptid) != ptid_get_pid (ptid))
@@ -3372,8 +3450,9 @@ retry:
              gdb_assert (lp->resumed);
 
              if (debug_linux_nat)
              gdb_assert (lp->resumed);
 
              if (debug_linux_nat)
-               fprintf (stderr, "LWP %ld got an event %06x, leaving pending.\n",
-                        ptid_get_lwp (lp->ptid), status);
+               fprintf (stderr,
+                        "LWP %ld got an event %06x, leaving pending.\n",
+                        ptid_get_lwp (lp->ptid), lp->status);
 
              if (WIFSTOPPED (lp->status))
                {
 
              if (WIFSTOPPED (lp->status))
                {
@@ -3389,8 +3468,7 @@ retry:
                         always cancels breakpoint hits in all
                         threads.  */
                      if (non_stop
                         always cancels breakpoint hits in all
                         threads.  */
                      if (non_stop
-                         && lp->waitstatus.kind == TARGET_WAITKIND_IGNORE
-                         && WSTOPSIG (lp->status) == SIGTRAP
+                         && linux_nat_lp_status_is_event (lp)
                          && cancel_breakpoint (lp))
                        {
                          /* Throw away the SIGTRAP.  */
                          && cancel_breakpoint (lp))
                        {
                          /* Throw away the SIGTRAP.  */
@@ -3398,8 +3476,9 @@ retry:
 
                          if (debug_linux_nat)
                            fprintf (stderr,
 
                          if (debug_linux_nat)
                            fprintf (stderr,
-                                    "LLW: LWP %ld hit a breakpoint while waiting "
-                                    "for another process; cancelled it\n",
+                                    "LLW: LWP %ld hit a breakpoint while"
+                                    " waiting for another process;"
+                                    " cancelled it\n",
                                     ptid_get_lwp (lp->ptid));
                        }
                      lp->stopped = 1;
                                     ptid_get_lwp (lp->ptid));
                        }
                      lp->stopped = 1;
@@ -3410,10 +3489,11 @@ retry:
                      lp->signalled = 0;
                    }
                }
                      lp->signalled = 0;
                    }
                }
-             else if (WIFEXITED (status) || WIFSIGNALED (status))
+             else if (WIFEXITED (lp->status) || WIFSIGNALED (lp->status))
                {
                  if (debug_linux_nat)
                {
                  if (debug_linux_nat)
-                   fprintf (stderr, "Process %ld exited while stopping LWPs\n",
+                   fprintf (stderr,
+                            "Process %ld exited while stopping LWPs\n",
                             ptid_get_lwp (lp->ptid));
 
                  /* This was the last lwp in the process.  Since
                             ptid_get_lwp (lp->ptid));
 
                  /* This was the last lwp in the process.  Since
@@ -3514,7 +3594,7 @@ retry:
 
   if (WIFSTOPPED (status))
     {
 
   if (WIFSTOPPED (status))
     {
-      int signo = target_signal_from_host (WSTOPSIG (status));
+      enum target_signal signo = target_signal_from_host (WSTOPSIG (status));
       struct inferior *inf;
 
       inf = find_inferior_pid (ptid_get_pid (lp->ptid));
       struct inferior *inf;
 
       inf = find_inferior_pid (ptid_get_pid (lp->ptid));
@@ -3525,7 +3605,7 @@ retry:
         skip the signal handler, or, if we're gaining control of the
         inferior.  */
       if (!lp->step
         skip the signal handler, or, if we're gaining control of the
         inferior.  */
       if (!lp->step
-         && inf->stop_soon == NO_STOP_QUIETLY
+         && inf->control.stop_soon == NO_STOP_QUIETLY
          && signal_stop_state (signo) == 0
          && signal_print_state (signo) == 0
          && signal_pass_state (signo) == 1)
          && signal_stop_state (signo) == 0
          && signal_print_state (signo) == 0
          && signal_pass_state (signo) == 1)
@@ -3544,7 +3624,9 @@ retry:
                                lp->step ?
                                "PTRACE_SINGLESTEP" : "PTRACE_CONT",
                                target_pid_to_str (lp->ptid),
                                lp->step ?
                                "PTRACE_SINGLESTEP" : "PTRACE_CONT",
                                target_pid_to_str (lp->ptid),
-                               signo ? strsignal (signo) : "0");
+                               (signo != TARGET_SIGNAL_0
+                                ? strsignal (target_signal_to_host (signo))
+                                : "0"));
          lp->stopped = 0;
          goto retry;
        }
          lp->stopped = 0;
          goto retry;
        }
@@ -3606,7 +3688,7 @@ retry:
   else
     lp->resumed = 0;
 
   else
     lp->resumed = 0;
 
-  if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP)
+  if (linux_nat_status_is_event (status))
     {
       if (debug_linux_nat)
        fprintf_unfiltered (gdb_stdlog,
     {
       if (debug_linux_nat)
        fprintf_unfiltered (gdb_stdlog,
@@ -3626,7 +3708,13 @@ retry:
     fprintf_unfiltered (gdb_stdlog, "LLW: exit\n");
 
   restore_child_signals_mask (&prev_mask);
     fprintf_unfiltered (gdb_stdlog, "LLW: exit\n");
 
   restore_child_signals_mask (&prev_mask);
-  lp->core = linux_nat_core_of_thread_1 (lp->ptid);
+
+  if (ourstatus->kind == TARGET_WAITKIND_EXITED
+      || ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
+    lp->core = -1;
+  else
+    lp->core = linux_nat_core_of_thread_1 (lp->ptid);
+
   return lp->ptid;
 }
 
   return lp->ptid;
 }
 
@@ -3679,7 +3767,8 @@ linux_nat_wait (struct target_ops *ops,
   ptid_t event_ptid;
 
   if (debug_linux_nat)
   ptid_t event_ptid;
 
   if (debug_linux_nat)
-    fprintf_unfiltered (gdb_stdlog, "linux_nat_wait: [%s]\n", target_pid_to_str (ptid));
+    fprintf_unfiltered (gdb_stdlog,
+                       "linux_nat_wait: [%s]\n", target_pid_to_str (ptid));
 
   /* Flush the async file first.  */
   if (target_can_async_p ())
 
   /* Flush the async file first.  */
   if (target_can_async_p ())
@@ -4045,9 +4134,7 @@ read_mapping (FILE *mapfile,
    regions in the inferior for a corefile.  */
 
 static int
    regions in the inferior for a corefile.  */
 
 static int
-linux_nat_find_memory_regions (int (*func) (CORE_ADDR,
-                                           unsigned long,
-                                           int, int, int, void *), void *obfd)
+linux_nat_find_memory_regions (find_memory_region_ftype func, void *obfd)
 {
   int pid = PIDGET (inferior_ptid);
   char mapsfilename[MAXPATHLEN];
 {
   int pid = PIDGET (inferior_ptid);
   char mapsfilename[MAXPATHLEN];
@@ -4101,7 +4188,7 @@ linux_nat_find_memory_regions (int (*func) (CORE_ADDR,
 static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
 static int
 find_signalled_thread (struct thread_info *info, void *data)
 {
-  if (info->stop_signal != TARGET_SIGNAL_0
+  if (info->suspend.stop_signal != TARGET_SIGNAL_0
       && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
     return 1;
 
       && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
     return 1;
 
@@ -4115,7 +4202,7 @@ find_stop_signal (void)
     iterate_over_threads (find_signalled_thread, NULL);
 
   if (info)
     iterate_over_threads (find_signalled_thread, NULL);
 
   if (info)
-    return info->stop_signal;
+    return info->suspend.stop_signal;
   else
     return TARGET_SIGNAL_0;
 }
   else
     return TARGET_SIGNAL_0;
 }
@@ -4128,8 +4215,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
                               char *note_data, int *note_size,
                               enum target_signal stop_signal)
 {
                               char *note_data, int *note_size,
                               enum target_signal stop_signal)
 {
-  gdb_gregset_t gregs;
-  gdb_fpregset_t fpregs;
   unsigned long lwp = ptid_get_lwp (ptid);
   struct gdbarch *gdbarch = target_gdbarch;
   struct regcache *regcache = get_thread_arch_regcache (ptid, gdbarch);
   unsigned long lwp = ptid_get_lwp (ptid);
   struct gdbarch *gdbarch = target_gdbarch;
   struct regcache *regcache = get_thread_arch_regcache (ptid, gdbarch);
@@ -4147,21 +4232,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
   core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
   sect_list = gdbarch_core_regset_sections (gdbarch);
 
   core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
   sect_list = gdbarch_core_regset_sections (gdbarch);
 
-  if (core_regset_p
-      && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
-                                                    sizeof (gregs))) != NULL
-      && regset->collect_regset != NULL)
-    regset->collect_regset (regset, regcache, -1,
-                           &gregs, sizeof (gregs));
-  else
-    fill_gregset (regcache, &gregs, -1);
-
-  note_data = (char *) elfcore_write_prstatus (obfd,
-                                              note_data,
-                                              note_size,
-                                              lwp,
-                                              stop_signal, &gregs);
-
   /* The loop below uses the new struct core_regset_section, which stores
      the supported section names and sizes for the core file.  Note that
      note PRSTATUS needs to be treated specially.  But the other notes are
   /* The loop below uses the new struct core_regset_section, which stores
      the supported section names and sizes for the core file.  Note that
      note PRSTATUS needs to be treated specially.  But the other notes are
@@ -4169,12 +4239,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
   if (core_regset_p && sect_list != NULL)
     while (sect_list->sect_name != NULL)
       {
   if (core_regset_p && sect_list != NULL)
     while (sect_list->sect_name != NULL)
       {
-       /* .reg was already handled above.  */
-       if (strcmp (sect_list->sect_name, ".reg") == 0)
-         {
-           sect_list++;
-           continue;
-         }
        regset = gdbarch_regset_from_core_section (gdbarch,
                                                   sect_list->sect_name,
                                                   sect_list->size);
        regset = gdbarch_regset_from_core_section (gdbarch,
                                                   sect_list->sect_name,
                                                   sect_list->size);
@@ -4182,12 +4246,17 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
        gdb_regset = xmalloc (sect_list->size);
        regset->collect_regset (regset, regcache, -1,
                                gdb_regset, sect_list->size);
        gdb_regset = xmalloc (sect_list->size);
        regset->collect_regset (regset, regcache, -1,
                                gdb_regset, sect_list->size);
-       note_data = (char *) elfcore_write_register_note (obfd,
-                                                         note_data,
-                                                         note_size,
-                                                         sect_list->sect_name,
-                                                         gdb_regset,
-                                                         sect_list->size);
+
+       if (strcmp (sect_list->sect_name, ".reg") == 0)
+         note_data = (char *) elfcore_write_prstatus
+                               (obfd, note_data, note_size,
+                                lwp, target_signal_to_host (stop_signal),
+                                gdb_regset);
+       else
+         note_data = (char *) elfcore_write_register_note
+                               (obfd, note_data, note_size,
+                                sect_list->sect_name, gdb_regset,
+                                sect_list->size);
        xfree (gdb_regset);
        sect_list++;
       }
        xfree (gdb_regset);
        sect_list++;
       }
@@ -4197,10 +4266,26 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
      the new support, the code below should be deleted.  */
   else
     {
      the new support, the code below should be deleted.  */
   else
     {
+      gdb_gregset_t gregs;
+      gdb_fpregset_t fpregs;
+
+      if (core_regset_p
+         && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
+                                                        sizeof (gregs)))
+         != NULL && regset->collect_regset != NULL)
+       regset->collect_regset (regset, regcache, -1,
+                               &gregs, sizeof (gregs));
+      else
+       fill_gregset (regcache, &gregs, -1);
+
+      note_data = (char *) elfcore_write_prstatus
+       (obfd, note_data, note_size, lwp, target_signal_to_host (stop_signal),
+        &gregs);
+
       if (core_regset_p
           && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
       if (core_regset_p
           && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
-                                                        sizeof (fpregs))) != NULL
-         && regset->collect_regset != NULL)
+                                                        sizeof (fpregs)))
+         != NULL && regset->collect_regset != NULL)
        regset->collect_regset (regset, regcache, -1,
                                &fpregs, sizeof (fpregs));
       else
        regset->collect_regset (regset, regcache, -1,
                                &fpregs, sizeof (fpregs));
       else
@@ -4484,7 +4569,7 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
        }
       else
        {
        }
       else
        {
-         /* [...] (future options here) */
+         /* [...] (future options here) */
        }
       argv++;
     }
        }
       argv++;
     }
@@ -4655,8 +4740,8 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("stime, children: %ld\n"), ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("stime, children: %ld\n"), ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
-           printf_filtered (_("jiffies remaining in current time slice: %ld\n"),
-                            ltmp);
+           printf_filtered (_("jiffies remaining in current "
+                              "time slice: %ld\n"), ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("'nice' value: %ld\n"), ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("'nice' value: %ld\n"), ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
@@ -4666,13 +4751,14 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
            printf_filtered (_("jiffies until next SIGALRM: %lu\n"),
                             (unsigned long) ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("jiffies until next SIGALRM: %lu\n"),
                             (unsigned long) ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
-           printf_filtered (_("start time (jiffies since system boot): %ld\n"),
-                            ltmp);
+           printf_filtered (_("start time (jiffies since "
+                              "system boot): %ld\n"), ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
            printf_filtered (_("Virtual memory size: %lu\n"),
                             (unsigned long) ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
            printf_filtered (_("Virtual memory size: %lu\n"),
                             (unsigned long) ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
-           printf_filtered (_("Resident set size: %lu\n"), (unsigned long) ltmp);
+           printf_filtered (_("Resident set size: %lu\n"),
+                            (unsigned long) ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
            printf_filtered (_("rlim: %lu\n"), (unsigned long) ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
            printf_filtered (_("rlim: %lu\n"), (unsigned long) ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
@@ -4681,11 +4767,11 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
            printf_filtered (_("End of text: 0x%lx\n"), ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
            printf_filtered (_("Start of stack: 0x%lx\n"), ltmp);
            printf_filtered (_("End of text: 0x%lx\n"), ltmp);
          if (fscanf (procfile, "%lu ", &ltmp) > 0)
            printf_filtered (_("Start of stack: 0x%lx\n"), ltmp);
-#if 0                          /* Don't know how architecture-dependent the rest is...
-                                  Anyway the signal bitmap info is available from "status".  */
-         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch? */
+#if 0  /* Don't know how architecture-dependent the rest is...
+          Anyway the signal bitmap info is available from "status".  */
+         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch?  */
            printf_filtered (_("Kernel stack pointer: 0x%lx\n"), ltmp);
            printf_filtered (_("Kernel stack pointer: 0x%lx\n"), ltmp);
-         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch? */
+         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch?  */
            printf_filtered (_("Kernel instr pointer: 0x%lx\n"), ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("Pending signals bitmap: 0x%lx\n"), ltmp);
            printf_filtered (_("Kernel instr pointer: 0x%lx\n"), ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("Pending signals bitmap: 0x%lx\n"), ltmp);
@@ -4695,7 +4781,7 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
            printf_filtered (_("Ignored signals bitmap: 0x%lx\n"), ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("Catched signals bitmap: 0x%lx\n"), ltmp);
            printf_filtered (_("Ignored signals bitmap: 0x%lx\n"), ltmp);
          if (fscanf (procfile, "%ld ", &ltmp) > 0)
            printf_filtered (_("Catched signals bitmap: 0x%lx\n"), ltmp);
-         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch? */
+         if (fscanf (procfile, "%lu ", &ltmp) > 0)     /* FIXME arch?  */
            printf_filtered (_("wchan (system call): 0x%lx\n"), ltmp);
 #endif
          do_cleanups (cleanup);
            printf_filtered (_("wchan (system call): 0x%lx\n"), ltmp);
 #endif
          do_cleanups (cleanup);
@@ -4889,7 +4975,8 @@ add_line_to_sigset (const char *line, sigset_t *sigs)
    SIGS to match.  */
 
 void
    SIGS to match.  */
 
 void
-linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigset_t *ignored)
+linux_proc_pending_signals (int pid, sigset_t *pending,
+                           sigset_t *blocked, sigset_t *ignored)
 {
   FILE *procfile;
   char buffer[MAXPATHLEN], fname[MAXPATHLEN];
 {
   FILE *procfile;
   char buffer[MAXPATHLEN], fname[MAXPATHLEN];
@@ -4942,6 +5029,45 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
 
   gdb_assert (object == TARGET_OBJECT_OSDATA);
 
 
   gdb_assert (object == TARGET_OBJECT_OSDATA);
 
+  if (!annex)
+    {
+      if (offset == 0)
+       {
+         if (len_avail != -1 && len_avail != 0)
+           obstack_free (&obstack, NULL);
+         len_avail = 0;
+         buf = NULL;
+         obstack_init (&obstack);
+         obstack_grow_str (&obstack, "<osdata type=\"types\">\n");
+
+         obstack_xml_printf (&obstack,
+                             "<item>"
+                             "<column name=\"Type\">processes</column>"
+                             "<column name=\"Description\">"
+                             "Listing of all processes</column>"
+                             "</item>");
+
+         obstack_grow_str0 (&obstack, "</osdata>\n");
+         buf = obstack_finish (&obstack);
+         len_avail = strlen (buf);
+       }
+
+      if (offset >= len_avail)
+       {
+         /* Done.  Get rid of the obstack.  */
+         obstack_free (&obstack, NULL);
+         buf = NULL;
+         len_avail = 0;
+         return 0;
+       }
+
+      if (len > len_avail - offset)
+       len = len_avail - offset;
+      memcpy (readbuf, buf + offset, len);
+
+      return len;
+    }
+
   if (strcmp (annex, "processes") != 0)
     return 0;
 
   if (strcmp (annex, "processes") != 0)
     return 0;
 
@@ -5392,12 +5518,13 @@ linux_nat_stop_lwp (struct lwp_info *lwp, void *data)
       if (debug_linux_nat)
        {
          if (find_thread_ptid (lwp->ptid)->stop_requested)
       if (debug_linux_nat)
        {
          if (find_thread_ptid (lwp->ptid)->stop_requested)
-           fprintf_unfiltered (gdb_stdlog, "\
-LNSL: already stopped/stop_requested %s\n",
+           fprintf_unfiltered (gdb_stdlog,
+                               "LNSL: already stopped/stop_requested %s\n",
                                target_pid_to_str (lwp->ptid));
          else
                                target_pid_to_str (lwp->ptid));
          else
-           fprintf_unfiltered (gdb_stdlog, "\
-LNSL: already stopped/no stop_requested yet %s\n",
+           fprintf_unfiltered (gdb_stdlog,
+                               "LNSL: already stopped/no "
+                               "stop_requested yet %s\n",
                                target_pid_to_str (lwp->ptid));
        }
     }
                                target_pid_to_str (lwp->ptid));
        }
     }
@@ -5503,15 +5630,21 @@ linux_nat_core_of_thread_1 (ptid_t ptid)
   make_cleanup (xfree, content);
 
   p = strchr (content, '(');
   make_cleanup (xfree, content);
 
   p = strchr (content, '(');
-  p = strchr (p, ')') + 2; /* skip ")" and a whitespace. */
+
+  /* Skip ")".  */
+  if (p != NULL)
+    p = strchr (p, ')');
+  if (p != NULL)
+    p++;
 
   /* If the first field after program name has index 0, then core number is
      the field with index 36.  There's no constant for that anywhere.  */
 
   /* If the first field after program name has index 0, then core number is
      the field with index 36.  There's no constant for that anywhere.  */
-  p = strtok_r (p, " ", &ts);
-  for (i = 0; i != 36; ++i)
+  if (p != NULL)
+    p = strtok_r (p, " ", &ts);
+  for (i = 0; p != NULL && i != 36; ++i)
     p = strtok_r (NULL, " ", &ts);
 
     p = strtok_r (NULL, " ", &ts);
 
-  if (sscanf (p, "%d", &core) == 0)
+  if (p == NULL || sscanf (p, "%d", &core) == 0)
     core = -1;
 
   do_cleanups (back_to);
     core = -1;
 
   do_cleanups (back_to);
This page took 1.065525 seconds and 4 git commands to generate.