2010-07-13 Emmanuel Thomé <Emmanuel.Thome@gmail.com>
[binutils-gdb.git] / gdb / linux-nat.c
index c0c024073142a84a8f92127b22c856d8177f85f5..93adfcd4e0df2c87927dd0b6f73be81c84ea3277 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU/Linux native-dependent code common to multiple platforms.
 
-   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -270,8 +270,6 @@ this platform."));
 #endif /* !HAVE_PERSONALITY */
 }
 
-static int linux_parent_pid;
-
 struct simple_pid_list
 {
   int pid;
@@ -370,6 +368,7 @@ static void
 add_to_pid_list (struct simple_pid_list **listp, int pid, int status)
 {
   struct simple_pid_list *new_pid = xmalloc (sizeof (struct simple_pid_list));
+
   new_pid->pid = pid;
   new_pid->status = status;
   new_pid->next = *listp;
@@ -385,6 +384,7 @@ pull_pid_from_list (struct simple_pid_list **listp, int pid, int *status)
     if ((*p)->pid == pid)
       {
        struct simple_pid_list *next = (*p)->next;
+
        *status = (*p)->status;
        xfree (*p);
        *p = next;
@@ -405,8 +405,6 @@ linux_record_stopped_pid (int pid, int status)
 static void
 linux_tracefork_child (void)
 {
-  int ret;
-
   ptrace (PTRACE_TRACEME, 0, 0, 0);
   kill (getpid (), SIGSTOP);
   fork ();
@@ -681,7 +679,7 @@ 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, _("\
-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"));
       return 1;
@@ -769,7 +767,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
                 breakpoint.  If a "cloned-VM" event was propagated
                 better throughout the core, this wouldn't be
                 required.  */
-             solib_create_inferior_hook ();
+             solib_create_inferior_hook (0);
            }
 
          /* Let the thread_db layer learn about this new process.  */
@@ -793,6 +791,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
             subsequent child exec or exit is enough to know when does
             the child stops using the parent's address space.  */
          parent_inf->waiting_for_vfork_done = detach_fork;
+         parent_inf->pspace->breakpoints_not_allowed = detach_fork;
 
          lp = find_lwp_pid (pid_to_ptid (parent_pid));
          gdb_assert (linux_supports_tracefork_flag >= 0);
@@ -866,7 +865,6 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
     }
   else
     {
-      struct thread_info *tp;
       struct inferior *parent_inf, *child_inf;
       struct lwp_info *lp;
       struct program_space *parent_pspace;
@@ -951,7 +949,7 @@ Attaching after process %d fork to child process %d.\n"),
             shared libraries, and install the solib event breakpoint.
             If a "cloned-VM" event was propagated better throughout
             the core, this wouldn't be required.  */
-         solib_create_inferior_hook ();
+         solib_create_inferior_hook (0);
        }
 
       /* Let the thread_db layer learn about this new process.  */
@@ -1104,25 +1102,6 @@ status_to_str (int status)
   return buf;
 }
 
-/* Initialize the list of LWPs.  Note that this module, contrary to
-   what GDB's generic threads layer does for its thread list,
-   re-initializes the LWP lists whenever we mourn or detach (which
-   doesn't involve mourning) the inferior.  */
-
-static void
-init_lwp_list (void)
-{
-  struct lwp_info *lp, *lpnext;
-
-  for (lp = lwp_list; lp; lp = lpnext)
-    {
-      lpnext = lp->next;
-      xfree (lp);
-    }
-
-  lwp_list = NULL;
-}
-
 /* Remove all LWPs belong to PID from the lwp list.  */
 
 static void
@@ -1183,6 +1162,7 @@ add_lwp (ptid_t ptid)
   lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
 
   lp->ptid = ptid;
+  lp->core = -1;
 
   lp->next = lwp_list;
   lwp_list = lp;
@@ -1238,33 +1218,6 @@ find_lwp_pid (ptid_t ptid)
   return NULL;
 }
 
-/* Returns true if PTID matches filter FILTER.  FILTER can be the wild
-   card MINUS_ONE_PTID (all ptid match it); can be a ptid representing
-   a process (ptid_is_pid returns true), in which case, all lwps of
-   that give process match, lwps of other process do not; or, it can
-   represent a specific thread, in which case, only that thread will
-   match true.  PTID must represent an LWP, it can never be a wild
-   card.  */
-
-static int
-ptid_match (ptid_t ptid, ptid_t filter)
-{
-  /* Since both parameters have the same type, prevent easy mistakes
-     from happening.  */
-  gdb_assert (!ptid_equal (ptid, minus_one_ptid)
-             && !ptid_equal (ptid, null_ptid));
-
-  if (ptid_equal (filter, minus_one_ptid))
-    return 1;
-  if (ptid_is_pid (filter)
-      && ptid_get_pid (ptid) == ptid_get_pid (filter))
-    return 1;
-  else if (ptid_equal (ptid, filter))
-    return 1;
-
-  return 0;
-}
-
 /* Call CALLBACK with its second argument set to DATA for every LWP in
    the list.  If CALLBACK returns 1 for a particular LWP, return a
    pointer to the structure describing that LWP immediately.
@@ -1695,6 +1648,7 @@ get_pending_status (struct lwp_info *lp, int *status)
   else if (non_stop && !is_executing (lp->ptid))
     {
       struct thread_info *tp = find_thread_ptid (lp->ptid);
+
       signo = tp->stop_signal;
     }
   else if (!non_stop)
@@ -1707,6 +1661,7 @@ get_pending_status (struct lwp_info *lp, int *status)
       if (GET_LWP (lp->ptid) == GET_LWP (last_ptid))
        {
          struct thread_info *tp = find_thread_ptid (lp->ptid);
+
          signo = tp->stop_signal;
        }
     }
@@ -1796,7 +1751,6 @@ linux_nat_detach (struct target_ops *ops, char *args, int from_tty)
 {
   int pid;
   int status;
-  enum target_signal sig;
   struct lwp_info *main_lwp;
 
   pid = GET_PID (inferior_ptid);
@@ -1827,10 +1781,11 @@ linux_nat_detach (struct target_ops *ops, char *args, int from_tty)
         pass it along with PTRACE_DETACH.  */
       args = alloca (8);
       sprintf (args, "%d", (int) WSTOPSIG (status));
-      fprintf_unfiltered (gdb_stdlog,
-                         "LND: Sending signal %s to %s\n",
-                         args,
-                         target_pid_to_str (main_lwp->ptid));
+      if (debug_linux_nat)
+       fprintf_unfiltered (gdb_stdlog,
+                           "LND: Sending signal %s to %s\n",
+                           args,
+                           target_pid_to_str (main_lwp->ptid));
     }
 
   delete_lwp (main_lwp->ptid);
@@ -1881,6 +1836,7 @@ resume_callback (struct lwp_info *lp, void *data)
       lp->stopped = 0;
       lp->step = 0;
       memset (&lp->siginfo, 0, sizeof (lp->siginfo));
+      lp->stopped_by_watchpoint = 0;
     }
   else if (lp->stopped && debug_linux_nat)
     fprintf_unfiltered (gdb_stdlog, "RC: Not resuming sibling %s (has pending)\n",
@@ -1928,14 +1884,8 @@ linux_nat_resume (struct target_ops *ops,
   resume_many = (ptid_equal (minus_one_ptid, ptid)
                 || ptid_is_pid (ptid));
 
-  if (!non_stop)
-    {
-      /* Mark the lwps we're resuming as resumed.  */
-      iterate_over_lwps (minus_one_ptid, resume_clear_callback, NULL);
-      iterate_over_lwps (ptid, resume_set_callback, NULL);
-    }
-  else
-    iterate_over_lwps (minus_one_ptid, resume_set_callback, NULL);
+  /* Mark the lwps we're resuming as resumed.  */
+  iterate_over_lwps (ptid, resume_set_callback, NULL);
 
   /* See if it's the current inferior that should be handled
      specially.  */
@@ -2018,6 +1968,7 @@ linux_nat_resume (struct target_ops *ops,
 
   linux_ops->to_resume (linux_ops, ptid, step, signo);
   memset (&lp->siginfo, 0, sizeof (lp->siginfo));
+  lp->stopped_by_watchpoint = 0;
 
   if (debug_linux_nat)
     fprintf_unfiltered (gdb_stdlog,
@@ -2031,27 +1982,29 @@ linux_nat_resume (struct target_ops *ops,
     target_async (inferior_event_handler, 0);
 }
 
-/* Issue kill to specified lwp.  */
-
-static int tkill_failed;
+/* Send a signal to an LWP.  */
 
 static int
 kill_lwp (int lwpid, int signo)
 {
-  errno = 0;
-
-/* Use tkill, if possible, in case we are using nptl threads.  If tkill
-   fails, then we are not using nptl threads and we should be using kill.  */
+  /* Use tkill, if possible, in case we are using nptl threads.  If tkill
+     fails, then we are not using nptl threads and we should be using kill.  */
 
 #ifdef HAVE_TKILL_SYSCALL
-  if (!tkill_failed)
-    {
-      int ret = syscall (__NR_tkill, lwpid, signo);
-      if (errno != ENOSYS)
-       return ret;
-      errno = 0;
-      tkill_failed = 1;
-    }
+  {
+    static int tkill_failed;
+
+    if (!tkill_failed)
+      {
+       int ret;
+
+       errno = 0;
+       ret = syscall (__NR_tkill, lwpid, signo);
+       if (errno != ENOSYS)
+         return ret;
+       tkill_failed = 1;
+      }
+  }
 #endif
 
   return kill (lwpid, signo);
@@ -2260,8 +2213,6 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
        ourstatus->kind = TARGET_WAITKIND_VFORKED;
       else
        {
-         struct cleanup *old_chain;
-
          ourstatus->kind = TARGET_WAITKIND_IGNORE;
          new_lp = add_lwp (BUILD_LWP (new_pid, GET_PID (lp->ptid)));
          new_lp->cloned = 1;
@@ -2520,7 +2471,6 @@ static int
 linux_nat_has_pending_sigint (int pid)
 {
   sigset_t pending, blocked, ignored;
-  int i;
 
   linux_proc_pending_signals (pid, &pending, &blocked, &ignored);
 
@@ -2569,6 +2519,74 @@ maybe_clear_ignore_sigint (struct lwp_info *lp)
     }
 }
 
+/* Fetch the possible triggered data watchpoint info and store it in
+   LP.
+
+   On some archs, like x86, that use debug registers to set
+   watchpoints, it's possible that the way to know which watched
+   address trapped, is to check the register that is used to select
+   which address to watch.  Problem is, between setting the watchpoint
+   and reading back which data address trapped, the user may change
+   the set of watchpoints, and, as a consequence, GDB changes the
+   debug registers in the inferior.  To avoid reading back a stale
+   stopped-data-address when that happens, we cache in LP the fact
+   that a watchpoint trapped, and the corresponding data address, as
+   soon as we see LP stop with a SIGTRAP.  If GDB changes the debug
+   registers meanwhile, we have the cached data we can rely on.  */
+
+static void
+save_sigtrap (struct lwp_info *lp)
+{
+  struct cleanup *old_chain;
+
+  if (linux_ops->to_stopped_by_watchpoint == NULL)
+    {
+      lp->stopped_by_watchpoint = 0;
+      return;
+    }
+
+  old_chain = save_inferior_ptid ();
+  inferior_ptid = lp->ptid;
+
+  lp->stopped_by_watchpoint = linux_ops->to_stopped_by_watchpoint ();
+
+  if (lp->stopped_by_watchpoint)
+    {
+      if (linux_ops->to_stopped_data_address != NULL)
+       lp->stopped_data_address_p =
+         linux_ops->to_stopped_data_address (&current_target,
+                                             &lp->stopped_data_address);
+      else
+       lp->stopped_data_address_p = 0;
+    }
+
+  do_cleanups (old_chain);
+}
+
+/* See save_sigtrap.  */
+
+static int
+linux_nat_stopped_by_watchpoint (void)
+{
+  struct lwp_info *lp = find_lwp_pid (inferior_ptid);
+
+  gdb_assert (lp != NULL);
+
+  return lp->stopped_by_watchpoint;
+}
+
+static int
+linux_nat_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
+{
+  struct lwp_info *lp = find_lwp_pid (inferior_ptid);
+
+  gdb_assert (lp != NULL);
+
+  *addr_p = lp->stopped_data_address;
+
+  return lp->stopped_data_address_p;
+}
+
 /* Wait until LP is stopped.  */
 
 static int
@@ -2627,6 +2645,8 @@ stop_wait_callback (struct lwp_info *lp, void *data)
              /* Save the trap's siginfo in case we need it later.  */
              save_siginfo (lp);
 
+             save_sigtrap (lp);
+
              /* Now resume this LWP and get the SIGSTOP event. */
              errno = 0;
              ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
@@ -3026,9 +3046,13 @@ linux_nat_filter_event (int lwpid, int status, int options)
        return NULL;
     }
 
-  /* Save the trap's siginfo in case we need it later.  */
   if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP)
-    save_siginfo (lp);
+    {
+      /* Save the trap's siginfo in case we need it later.  */
+      save_siginfo (lp);
+
+      save_sigtrap (lp);
+    }
 
   /* Check if the thread has exited.  */
   if ((WIFEXITED (status) || WIFSIGNALED (status))
@@ -3201,8 +3225,20 @@ retry:
   lp = NULL;
   status = 0;
 
-  /* Make sure there is at least one LWP that has been resumed.  */
-  gdb_assert (iterate_over_lwps (ptid, resumed_callback, NULL));
+  /* Make sure that of those LWPs we want to get an event from, there
+     is at least one LWP that has been resumed.  If there's none, just
+     bail out.  The core may just be flushing asynchronously all
+     events.  */
+  if (iterate_over_lwps (ptid, resumed_callback, NULL) == NULL)
+    {
+      ourstatus->kind = TARGET_WAITKIND_IGNORE;
+
+      if (debug_linux_nat_async)
+       fprintf_unfiltered (gdb_stdlog, "LLW: exit (no resumed LWP)\n");
+
+      restore_child_signals_mask (&prev_mask);
+      return minus_one_ptid;
+    }
 
   /* First check if there is a LWP with a wait status pending.  */
   if (pid == -1)
@@ -3333,6 +3369,8 @@ retry:
              && ptid_is_pid (ptid)
              && ptid_get_pid (lp->ptid) != ptid_get_pid (ptid))
            {
+             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);
@@ -3341,12 +3379,30 @@ retry:
                {
                  if (WSTOPSIG (lp->status) != SIGSTOP)
                    {
-                     stop_callback (lp, NULL);
-
-                     /* Resume in order to collect the sigstop.  */
-                     ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
-
-                     stop_wait_callback (lp, NULL);
+                     /* Cancel breakpoint hits.  The breakpoint may
+                        be removed before we fetch events from this
+                        process to report to the core.  It is best
+                        not to assume the moribund breakpoints
+                        heuristic always handles these cases --- it
+                        could be too many events go through to the
+                        core before this one is handled.  All-stop
+                        always cancels breakpoint hits in all
+                        threads.  */
+                     if (non_stop
+                         && lp->waitstatus.kind == TARGET_WAITKIND_IGNORE
+                         && WSTOPSIG (lp->status) == SIGTRAP
+                         && cancel_breakpoint (lp))
+                       {
+                         /* Throw away the SIGTRAP.  */
+                         lp->status = 0;
+
+                         if (debug_linux_nat)
+                           fprintf (stderr,
+                                    "LLW: LWP %ld hit a breakpoint while waiting "
+                                    "for another process; cancelled it\n",
+                                    ptid_get_lwp (lp->ptid));
+                       }
+                     lp->stopped = 1;
                    }
                  else
                    {
@@ -3536,12 +3592,19 @@ retry:
         starvation.  */
       if (pid == -1)
        select_event_lwp (ptid, &lp, &status);
-    }
 
-  /* Now that we've selected our final event LWP, cancel any
-     breakpoints in other LWPs that have hit a GDB breakpoint.  See
-     the comment in cancel_breakpoints_callback to find out why.  */
-  iterate_over_lwps (minus_one_ptid, cancel_breakpoints_callback, lp);
+      /* Now that we've selected our final event LWP, cancel any
+        breakpoints in other LWPs that have hit a GDB breakpoint.
+        See the comment in cancel_breakpoints_callback to find out
+        why.  */
+      iterate_over_lwps (minus_one_ptid, cancel_breakpoints_callback, lp);
+
+      /* In all-stop, from the core's perspective, all LWPs are now
+        stopped until a new resume action is sent over.  */
+      iterate_over_lwps (minus_one_ptid, resume_clear_callback, NULL);
+    }
+  else
+    lp->resumed = 0;
 
   if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP)
     {
@@ -3563,9 +3626,57 @@ retry:
     fprintf_unfiltered (gdb_stdlog, "LLW: exit\n");
 
   restore_child_signals_mask (&prev_mask);
+
+  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;
 }
 
+/* Resume LWPs that are currently stopped without any pending status
+   to report, but are resumed from the core's perspective.  */
+
+static int
+resume_stopped_resumed_lwps (struct lwp_info *lp, void *data)
+{
+  ptid_t *wait_ptid_p = data;
+
+  if (lp->stopped
+      && lp->resumed
+      && lp->status == 0
+      && lp->waitstatus.kind == TARGET_WAITKIND_IGNORE)
+    {
+      gdb_assert (is_executing (lp->ptid));
+
+      /* Don't bother if there's a breakpoint at PC that we'd hit
+        immediately, and we're not waiting for this LWP.  */
+      if (!ptid_match (lp->ptid, *wait_ptid_p))
+       {
+         struct regcache *regcache = get_thread_regcache (lp->ptid);
+         CORE_ADDR pc = regcache_read_pc (regcache);
+
+         if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
+           return 0;
+       }
+
+      if (debug_linux_nat)
+       fprintf_unfiltered (gdb_stdlog,
+                           "RSRL: resuming stopped-resumed LWP %s\n",
+                           target_pid_to_str (lp->ptid));
+
+      linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
+                           lp->step, TARGET_SIGNAL_0);
+      lp->stopped = 0;
+      memset (&lp->siginfo, 0, sizeof (lp->siginfo));
+      lp->stopped_by_watchpoint = 0;
+    }
+
+  return 0;
+}
+
 static ptid_t
 linux_nat_wait (struct target_ops *ops,
                ptid_t ptid, struct target_waitstatus *ourstatus,
@@ -3580,6 +3691,16 @@ linux_nat_wait (struct target_ops *ops,
   if (target_can_async_p ())
     async_file_flush ();
 
+  /* Resume LWPs that are currently stopped without any pending status
+     to report, but are resumed from the core's perspective.  LWPs get
+     in this state if we find them stopping at a time we're not
+     interested in reporting the event (target_wait on a
+     specific_process, for example, see linux_nat_wait_1), and
+     meanwhile the event became uninteresting.  Don't bother resuming
+     LWPs we're not going to wait for if they'd stop immediately.  */
+  if (non_stop)
+    iterate_over_lwps (minus_one_ptid, resume_stopped_resumed_lwps, &ptid);
+
   event_ptid = linux_nat_wait_1 (ops, ptid, ourstatus, target_options);
 
   /* If we requested any event, and something came out, assume there
@@ -3691,6 +3812,7 @@ linux_nat_kill (struct target_ops *ops)
   else
     {
       ptid_t ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+
       /* Stop all threads before killing them, since ptrace requires
         that the thread is stopped to sucessfully PTRACE_KILL.  */
       iterate_over_lwps (ptid, stop_callback, NULL);
@@ -3939,7 +4061,6 @@ linux_nat_find_memory_regions (int (*func) (CORE_ADDR,
   long long addr, endaddr, size, offset, inode;
   char permissions[8], device[8], filename[MAXPATHLEN];
   int read, write, exec;
-  int ret;
   struct cleanup *cleanup;
 
   /* Compose the filename for the /proc memory map, and open it.  */
@@ -3966,8 +4087,8 @@ linux_nat_find_memory_regions (int (*func) (CORE_ADDR,
       if (info_verbose)
        {
          fprintf_filtered (gdb_stdout,
-                           "Save segment, %lld bytes at %s (%c%c%c)",
-                           size, paddress (target_gdbarch, addr),
+                           "Save segment, %s bytes at %s (%c%c%c)",
+                           plongest (size), paddress (target_gdbarch, addr),
                            read ? 'r' : ' ',
                            write ? 'w' : ' ', exec ? 'x' : ' ');
          if (filename[0])
@@ -4013,8 +4134,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
                               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);
@@ -4032,21 +4151,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);
 
-  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
@@ -4054,12 +4158,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
   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);
@@ -4067,12 +4165,16 @@ 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);
-       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, 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++;
       }
@@ -4082,6 +4184,24 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
      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,
+                                                  stop_signal, &gregs);
+
       if (core_regset_p
           && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
                                                         sizeof (fpregs))) != NULL
@@ -4230,6 +4350,7 @@ static char *
 linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size)
 {
   struct linux_spu_corefile_data args;
+
   args.obfd = obfd;
   args.note_data = note_data;
   args.note_size = note_size;
@@ -4247,13 +4368,11 @@ static char *
 linux_nat_make_corefile_notes (bfd *obfd, int *note_size)
 {
   struct linux_nat_corefile_thread_data thread_args;
-  struct cleanup *old_chain;
   /* The variable size must be >= sizeof (prpsinfo_t.pr_fname).  */
   char fname[16] = { '\0' };
   /* The variable size must be >= sizeof (prpsinfo_t.pr_psargs).  */
   char psargs[80] = { '\0' };
   char *note_data = NULL;
-  ptid_t current_ptid = inferior_ptid;
   ptid_t filter = pid_to_ptid (ptid_get_pid (inferior_ptid));
   gdb_byte *auxv;
   int auxv_len;
@@ -4323,7 +4442,6 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
   int cwd_f = 1;
   int exe_f = 1;
   int mappings_f = 0;
-  int environ_f = 0;
   int status_f = 0;
   int stat_f = 0;
   int all = 0;
@@ -4389,6 +4507,7 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
       if ((procfile = fopen (fname1, "r")) != NULL)
        {
          struct cleanup *cleanup = make_cleanup_fclose (procfile);
+
           if (fgets (buffer, sizeof (buffer), procfile))
             printf_filtered ("cmdline = '%s'\n", buffer);
           else
@@ -4484,6 +4603,7 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
       if ((procfile = fopen (fname1, "r")) != NULL)
        {
          struct cleanup *cleanup = make_cleanup_fclose (procfile);
+
          while (fgets (buffer, sizeof (buffer), procfile) != NULL)
            puts_filtered (buffer);
          do_cleanups (cleanup);
@@ -4778,7 +4898,6 @@ linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigse
 {
   FILE *procfile;
   char buffer[MAXPATHLEN], fname[MAXPATHLEN];
-  int signum;
   struct cleanup *cleanup;
 
   sigemptyset (pending);
@@ -4815,8 +4934,8 @@ linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigse
 
 static LONGEST
 linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
-                    const char *annex, gdb_byte *readbuf,
-                    const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
+                      const char *annex, gdb_byte *readbuf,
+                      const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
 {
   /* We make the process list snapshot when the object starts to be
      read.  */
@@ -4828,6 +4947,45 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
 
   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;
 
@@ -4836,7 +4994,7 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
   if (offset == 0)
     {
       if (len_avail != -1 && len_avail != 0)
-       obstack_free (&obstack, NULL);
+       obstack_free (&obstack, NULL);
       len_avail = 0;
       buf = NULL;
       obstack_init (&obstack);
@@ -4844,60 +5002,63 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
 
       dirp = opendir ("/proc");
       if (dirp)
-       {
-         struct dirent *dp;
-         while ((dp = readdir (dirp)) != NULL)
-           {
-             struct stat statbuf;
-             char procentry[sizeof ("/proc/4294967295")];
-
-             if (!isdigit (dp->d_name[0])
-                 || NAMELEN (dp) > sizeof ("4294967295") - 1)
-               continue;
-
-             sprintf (procentry, "/proc/%s", dp->d_name);
-             if (stat (procentry, &statbuf) == 0
-                 && S_ISDIR (statbuf.st_mode))
-               {
-                 char *pathname;
-                 FILE *f;
-                 char cmd[MAXPATHLEN + 1];
-                 struct passwd *entry;
-
-                 pathname = xstrprintf ("/proc/%s/cmdline", dp->d_name);
-                 entry = getpwuid (statbuf.st_uid);
-
-                 if ((f = fopen (pathname, "r")) != NULL)
-                   {
-                     size_t len = fread (cmd, 1, sizeof (cmd) - 1, f);
-                     if (len > 0)
-                       {
-                         int i;
-                         for (i = 0; i < len; i++)
-                           if (cmd[i] == '\0')
-                             cmd[i] = ' ';
-                         cmd[len] = '\0';
-
-                         obstack_xml_printf (
-                          &obstack,
-                          "<item>"
-                          "<column name=\"pid\">%s</column>"
-                          "<column name=\"user\">%s</column>"
-                          "<column name=\"command\">%s</column>"
-                          "</item>",
-                          dp->d_name,
-                          entry ? entry->pw_name : "?",
-                          cmd);
-                       }
-                     fclose (f);
-                   }
-
-                 xfree (pathname);
-               }
-           }
-
-         closedir (dirp);
-       }
+       {
+         struct dirent *dp;
+
+         while ((dp = readdir (dirp)) != NULL)
+           {
+             struct stat statbuf;
+             char procentry[sizeof ("/proc/4294967295")];
+
+             if (!isdigit (dp->d_name[0])
+                 || NAMELEN (dp) > sizeof ("4294967295") - 1)
+               continue;
+
+             sprintf (procentry, "/proc/%s", dp->d_name);
+             if (stat (procentry, &statbuf) == 0
+                 && S_ISDIR (statbuf.st_mode))
+               {
+                 char *pathname;
+                 FILE *f;
+                 char cmd[MAXPATHLEN + 1];
+                 struct passwd *entry;
+
+                 pathname = xstrprintf ("/proc/%s/cmdline", dp->d_name);
+                 entry = getpwuid (statbuf.st_uid);
+
+                 if ((f = fopen (pathname, "r")) != NULL)
+                   {
+                     size_t len = fread (cmd, 1, sizeof (cmd) - 1, f);
+
+                     if (len > 0)
+                       {
+                         int i;
+
+                         for (i = 0; i < len; i++)
+                           if (cmd[i] == '\0')
+                             cmd[i] = ' ';
+                         cmd[len] = '\0';
+
+                         obstack_xml_printf (
+                           &obstack,
+                           "<item>"
+                           "<column name=\"pid\">%s</column>"
+                           "<column name=\"user\">%s</column>"
+                           "<column name=\"command\">%s</column>"
+                           "</item>",
+                           dp->d_name,
+                           entry ? entry->pw_name : "?",
+                           cmd);
+                       }
+                     fclose (f);
+                   }
+
+                 xfree (pathname);
+               }
+           }
+
+         closedir (dirp);
+       }
 
       obstack_grow_str0 (&obstack, "</osdata>\n");
       buf = obstack_finish (&obstack);
@@ -4928,7 +5089,7 @@ linux_xfer_partial (struct target_ops *ops, enum target_object object,
   LONGEST xfer;
 
   if (object == TARGET_OBJECT_AUXV)
-    return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf,
+    return memory_xfer_auxv (ops, object, annex, readbuf, writebuf,
                             offset, len);
 
   if (object == TARGET_OBJECT_OSDATA)
@@ -5243,7 +5404,6 @@ linux_nat_stop_lwp (struct lwp_info *lwp, void *data)
 {
   if (!lwp->stopped)
     {
-      int pid, status;
       ptid_t ptid = lwp->ptid;
 
       if (debug_linux_nat)
@@ -5344,6 +5504,83 @@ linux_nat_thread_address_space (struct target_ops *t, ptid_t ptid)
   return inf->aspace;
 }
 
+int
+linux_nat_core_of_thread_1 (ptid_t ptid)
+{
+  struct cleanup *back_to;
+  char *filename;
+  FILE *f;
+  char *content = NULL;
+  char *p;
+  char *ts = 0;
+  int content_read = 0;
+  int i;
+  int core;
+
+  filename = xstrprintf ("/proc/%d/task/%ld/stat",
+                        GET_PID (ptid), GET_LWP (ptid));
+  back_to = make_cleanup (xfree, filename);
+
+  f = fopen (filename, "r");
+  if (!f)
+    {
+      do_cleanups (back_to);
+      return -1;
+    }
+
+  make_cleanup_fclose (f);
+
+  for (;;)
+    {
+      int n;
+
+      content = xrealloc (content, content_read + 1024);
+      n = fread (content + content_read, 1, 1024, f);
+      content_read += n;
+      if (n < 1024)
+       {
+         content[content_read] = '\0';
+         break;
+       }
+    }
+
+  make_cleanup (xfree, content);
+
+  p = strchr (content, '(');
+
+  /* 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 (p != NULL)
+    p = strtok_r (p, " ", &ts);
+  for (i = 0; p != NULL && i != 36; ++i)
+    p = strtok_r (NULL, " ", &ts);
+
+  if (p == NULL || sscanf (p, "%d", &core) == 0)
+    core = -1;
+
+  do_cleanups (back_to);
+
+  return core;
+}
+
+/* Return the cached value of the processor core for thread PTID.  */
+
+int
+linux_nat_core_of_thread (struct target_ops *ops, ptid_t ptid)
+{
+  struct lwp_info *info = find_lwp_pid (ptid);
+
+  if (info)
+    return info->core;
+  return -1;
+}
+
 void
 linux_nat_add_target (struct target_ops *t)
 {
@@ -5367,6 +5604,8 @@ linux_nat_add_target (struct target_ops *t)
   t->to_pid_to_str = linux_nat_pid_to_str;
   t->to_has_thread_control = tc_schedlock;
   t->to_thread_address_space = linux_nat_thread_address_space;
+  t->to_stopped_by_watchpoint = linux_nat_stopped_by_watchpoint;
+  t->to_stopped_data_address = linux_nat_stopped_data_address;
 
   t->to_can_async_p = linux_nat_can_async_p;
   t->to_is_async_p = linux_nat_is_async_p;
@@ -5382,6 +5621,8 @@ linux_nat_add_target (struct target_ops *t)
 
   t->to_supports_multi_process = linux_nat_supports_multi_process;
 
+  t->to_core_of_thread = linux_nat_core_of_thread;
+
   /* We don't change the stratum; this target will sit at
      process_stratum and thread_db will set at thread_stratum.  This
      is a little strange, since this is a multi-threaded-capable
@@ -5431,8 +5672,6 @@ extern initialize_file_ftype _initialize_linux_nat;
 void
 _initialize_linux_nat (void)
 {
-  sigset_t mask;
-
   add_info ("proc", linux_nat_info_proc_cmd, _("\
 Show /proc process information about any running process.\n\
 Specify any process id, or use the program being debugged by default.\n\