gdb/
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-low.c
index ba1d7b46bb96e4cec83ea698e40511d284f16532..06ec5763c624d66f1be540f7268688da6b459215 100644 (file)
@@ -1,6 +1,5 @@
 /* Low level interface to ptrace, for the remote server for GDB.
-   Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1995-1996, 1998-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #include "server.h"
 #include "linux-low.h"
+#include "linux-osdata.h"
+#include "agent.h"
 
 #include <sys/wait.h>
 #include <stdio.h>
 #include <sys/param.h>
 #include <sys/ptrace.h>
+#include "linux-ptrace.h"
+#include "linux-procfs.h"
 #include <signal.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <pwd.h>
 #include <sys/types.h>
 #include <dirent.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <sys/uio.h>
+#ifndef ELFMAG0
+/* Don't include <linux/elf.h> here.  If it got included by gdb_proc_service.h
+   then ELFMAG0 will have been defined.  If it didn't get included by
+   gdb_proc_service.h then including it will likely introduce a duplicate
+   definition of elf_fpregset_t.  */
+#include <elf.h>
+#endif
+
+#ifndef SPUFS_MAGIC
+#define SPUFS_MAGIC 0x23c9b64e
+#endif
 
-#ifndef PTRACE_GETSIGINFO
-# define PTRACE_GETSIGINFO 0x4202
-# define PTRACE_SETSIGINFO 0x4203
+#ifdef HAVE_PERSONALITY
+# include <sys/personality.h>
+# if !HAVE_DECL_ADDR_NO_RANDOMIZE
+#  define ADDR_NO_RANDOMIZE 0x0040000
+# endif
 #endif
 
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
 #endif
 
-/* If the system headers did not provide the constants, hard-code the normal
-   values.  */
-#ifndef PTRACE_EVENT_FORK
-
-#define PTRACE_SETOPTIONS      0x4200
-#define PTRACE_GETEVENTMSG     0x4201
-
-/* options set using PTRACE_SETOPTIONS */
-#define PTRACE_O_TRACESYSGOOD  0x00000001
-#define PTRACE_O_TRACEFORK     0x00000002
-#define PTRACE_O_TRACEVFORK    0x00000004
-#define PTRACE_O_TRACECLONE    0x00000008
-#define PTRACE_O_TRACEEXEC     0x00000010
-#define PTRACE_O_TRACEVFORKDONE        0x00000020
-#define PTRACE_O_TRACEEXIT     0x00000040
-
-/* Wait extended result codes for the above trace options.  */
-#define PTRACE_EVENT_FORK      1
-#define PTRACE_EVENT_VFORK     2
-#define PTRACE_EVENT_CLONE     3
-#define PTRACE_EVENT_EXEC      4
-#define PTRACE_EVENT_VFORK_DONE        5
-#define PTRACE_EVENT_EXIT      6
-
-#endif /* PTRACE_EVENT_FORK */
-
-/* We can't always assume that this flag is available, but all systems
-   with the ptrace event handlers also have __WALL, so it's safe to use
-   in some contexts.  */
-#ifndef __WALL
-#define __WALL          0x40000000 /* Wait for any child.  */
+#ifndef W_STOPCODE
+#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
+#endif
+
+/* This is the kernel's hard limit.  Not to be confused with
+   SIGRTMIN.  */
+#ifndef __SIGRTMIN
+#define __SIGRTMIN 32
 #endif
 
 #ifdef __UCLIBC__
    representation of the thread ID.
 
    ``all_lwps'' is keyed by the process ID - which on Linux is (presently)
-   the same as the LWP ID.  */
+   the same as the LWP ID.
+
+   ``all_processes'' is keyed by the "overall process ID", which
+   GNU/Linux calls tgid, "thread group ID".  */
 
 struct inferior_list all_lwps;
 
-/* A list of all unknown processes which receive stop signals.  Some other
-   process will presumably claim each of these as forked children
-   momentarily.  */
+/* A list of all unknown processes which receive stop signals.  Some
+   other process will presumably claim each of these as forked
+   children momentarily.  */
+
+struct simple_pid_list
+{
+  /* The process ID.  */
+  int pid;
+
+  /* The status as reported by waitpid.  */
+  int status;
+
+  /* Next in chain.  */
+  struct simple_pid_list *next;
+};
+struct simple_pid_list *stopped_pids;
+
+/* Trivial list manipulation functions to keep track of a list of new
+   stopped processes.  */
+
+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;
+  *listp = new_pid;
+}
+
+static int
+pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp)
+{
+  struct simple_pid_list **p;
+
+  for (p = listp; *p != NULL; p = &(*p)->next)
+    if ((*p)->pid == pid)
+      {
+       struct simple_pid_list *next = (*p)->next;
 
-struct inferior_list stopped_pids;
+       *statusp = (*p)->status;
+       xfree (*p);
+       *p = next;
+       return 1;
+      }
+  return 0;
+}
 
 /* FIXME this is a bit of a hack, and could be removed.  */
 int stopping_threads;
 
 /* FIXME make into a target method?  */
 int using_threads = 1;
-static int thread_db_active;
 
-static int must_set_ptrace_flags;
-
-/* This flag is true iff we've just created or attached to a new inferior
-   but it has not stopped yet.  As soon as it does, we need to call the
-   low target's arch_setup callback.  */
+/* True if we're presently stabilizing threads (moving them out of
+   jump pads).  */
+static int stabilizing_threads;
+
+/* This flag is true iff we've just created or attached to our first
+   inferior but it has not stopped yet.  As soon as it does, we need
+   to call the low target's arch_setup callback.  Doing this only on
+   the first inferior avoids reinializing the architecture on every
+   inferior, and avoids messing with the register caches of the
+   already running inferiors.  NOTE: this assumes all inferiors under
+   control of gdbserver have the same architecture.  */
 static int new_inferior;
 
-static void linux_resume_one_lwp (struct inferior_list_entry *entry,
+static void linux_resume_one_lwp (struct lwp_info *lwp,
                                  int step, int signal, siginfo_t *info);
 static void linux_resume (struct thread_resume *resume_info, size_t n);
-static void stop_all_lwps (void);
-static int linux_wait_for_event (int pid, int *wstat, int options);
-static int check_removed_breakpoint (struct lwp_info *event_child);
-static void *add_lwp (unsigned long pid);
-static int my_waitpid (int pid, int *status, int flags);
+static void stop_all_lwps (int suspend, struct lwp_info *except);
+static void unstop_all_lwps (int unsuspend, struct lwp_info *except);
+static int linux_wait_for_event (ptid_t ptid, int *wstat, int options);
+static void *add_lwp (ptid_t ptid);
 static int linux_stopped_by_watchpoint (void);
+static void mark_lwp_dead (struct lwp_info *lwp, int wstat);
+static void proceed_all_lwps (void);
+static int finish_step_over (struct lwp_info *lwp);
+static CORE_ADDR get_stop_pc (struct lwp_info *lwp);
+static int kill_lwp (unsigned long lwpid, int signo);
+static void linux_enable_event_reporting (int pid);
+
+/* True if the low target can hardware single-step.  Such targets
+   don't need a BREAKPOINT_REINSERT_ADDR callback.  */
+
+static int
+can_hardware_single_step (void)
+{
+  return (the_low_target.breakpoint_reinsert_addr == NULL);
+}
+
+/* True if the low target supports memory breakpoints.  If so, we'll
+   have a GET_PC implementation.  */
+
+static int
+supports_breakpoints (void)
+{
+  return (the_low_target.get_pc != NULL);
+}
+
+/* Returns true if this target can support fast tracepoints.  This
+   does not mean that the in-process agent has been loaded in the
+   inferior.  */
+
+static int
+supports_fast_tracepoints (void)
+{
+  return the_low_target.install_fast_tracepoint_jump_pad != NULL;
+}
 
 struct pending_signals
 {
@@ -131,7 +211,8 @@ struct pending_signals
   struct pending_signals *prev;
 };
 
-#define PTRACE_ARG3_TYPE long
+#define PTRACE_ARG3_TYPE void *
+#define PTRACE_ARG4_TYPE void *
 #define PTRACE_XFER_TYPE long
 
 #ifdef HAVE_LINUX_REGSETS
@@ -139,9 +220,6 @@ static char *disabled_regsets;
 static int num_regsets;
 #endif
 
-/* FIXME: Delete eventually.  */
-#define inferior_pid (lwpid_of (get_thread_lwp (current_inferior)))
-
 /* The read/write ends of the pipe registered as waitable file in the
    event loop.  */
 static int linux_event_pipe[2] = { -1, -1 };
@@ -149,17 +227,162 @@ static int linux_event_pipe[2] = { -1, -1 };
 /* True if we're currently in async mode.  */
 #define target_is_async_p() (linux_event_pipe[0] != -1)
 
-static void send_sigstop (struct inferior_list_entry *entry);
+static void send_sigstop (struct lwp_info *lwp);
 static void wait_for_sigstop (struct inferior_list_entry *entry);
 
+/* Return non-zero if HEADER is a 64-bit ELF file.  */
+
+static int
+elf_64_header_p (const Elf64_Ehdr *header)
+{
+  return (header->e_ident[EI_MAG0] == ELFMAG0
+          && header->e_ident[EI_MAG1] == ELFMAG1
+          && header->e_ident[EI_MAG2] == ELFMAG2
+          && header->e_ident[EI_MAG3] == ELFMAG3
+          && header->e_ident[EI_CLASS] == ELFCLASS64);
+}
+
+/* Return non-zero if FILE is a 64-bit ELF file,
+   zero if the file is not a 64-bit ELF file,
+   and -1 if the file is not accessible or doesn't exist.  */
+
+static int
+elf_64_file_p (const char *file)
+{
+  Elf64_Ehdr header;
+  int fd;
+
+  fd = open (file, O_RDONLY);
+  if (fd < 0)
+    return -1;
+
+  if (read (fd, &header, sizeof (header)) != sizeof (header))
+    {
+      close (fd);
+      return 0;
+    }
+  close (fd);
+
+  return elf_64_header_p (&header);
+}
+
+/* Accepts an integer PID; Returns true if the executable PID is
+   running is a 64-bit ELF file..  */
+
+int
+linux_pid_exe_is_elf_64_file (int pid)
+{
+  char file[MAXPATHLEN];
+
+  sprintf (file, "/proc/%d/exe", pid);
+  return elf_64_file_p (file);
+}
+
 static void
 delete_lwp (struct lwp_info *lwp)
 {
   remove_thread (get_lwp_thread (lwp));
   remove_inferior (&all_lwps, &lwp->head);
+  free (lwp->arch_private);
   free (lwp);
 }
 
+/* Add a process to the common process list, and set its private
+   data.  */
+
+static struct process_info *
+linux_add_process (int pid, int attached)
+{
+  struct process_info *proc;
+
+  /* Is this the first process?  If so, then set the arch.  */
+  if (all_processes.head == NULL)
+    new_inferior = 1;
+
+  proc = add_process (pid, attached);
+  proc->private = xcalloc (1, sizeof (*proc->private));
+
+  if (the_low_target.new_process != NULL)
+    proc->private->arch_private = the_low_target.new_process ();
+
+  return proc;
+}
+
+/* Wrapper function for waitpid which handles EINTR, and emulates
+   __WALL for systems where that is not available.  */
+
+static int
+my_waitpid (int pid, int *status, int flags)
+{
+  int ret, out_errno;
+
+  if (debug_threads)
+    fprintf (stderr, "my_waitpid (%d, 0x%x)\n", pid, flags);
+
+  if (flags & __WALL)
+    {
+      sigset_t block_mask, org_mask, wake_mask;
+      int wnohang;
+
+      wnohang = (flags & WNOHANG) != 0;
+      flags &= ~(__WALL | __WCLONE);
+      flags |= WNOHANG;
+
+      /* Block all signals while here.  This avoids knowing about
+        LinuxThread's signals.  */
+      sigfillset (&block_mask);
+      sigprocmask (SIG_BLOCK, &block_mask, &org_mask);
+
+      /* ... except during the sigsuspend below.  */
+      sigemptyset (&wake_mask);
+
+      while (1)
+       {
+         /* Since all signals are blocked, there's no need to check
+            for EINTR here.  */
+         ret = waitpid (pid, status, flags);
+         out_errno = errno;
+
+         if (ret == -1 && out_errno != ECHILD)
+           break;
+         else if (ret > 0)
+           break;
+
+         if (flags & __WCLONE)
+           {
+             /* We've tried both flavors now.  If WNOHANG is set,
+                there's nothing else to do, just bail out.  */
+             if (wnohang)
+               break;
+
+             if (debug_threads)
+               fprintf (stderr, "blocking\n");
+
+             /* Block waiting for signals.  */
+             sigsuspend (&wake_mask);
+           }
+
+         flags ^= __WCLONE;
+       }
+
+      sigprocmask (SIG_SETMASK, &org_mask, NULL);
+    }
+  else
+    {
+      do
+       ret = waitpid (pid, status, flags);
+      while (ret == -1 && errno == EINTR);
+      out_errno = errno;
+    }
+
+  if (debug_threads)
+    fprintf (stderr, "my_waitpid (%d, 0x%x): status(%x), %d\n",
+            pid, flags, status ? *status : -1, ret);
+
+  errno = out_errno;
+  return ret;
+}
+
 /* Handle a GNU/Linux extended wait response.  If we see a clone
    event, we need to add the new LWP to our list (and not report the
    trap to higher layers).  */
@@ -172,13 +395,14 @@ handle_extended_wait (struct lwp_info *event_child, int wstat)
 
   if (event == PTRACE_EVENT_CLONE)
     {
+      ptid_t ptid;
       unsigned long new_pid;
-      int ret, status = W_STOPCODE (SIGSTOP);
+      int ret, status;
 
       ptrace (PTRACE_GETEVENTMSG, lwpid_of (event_child), 0, &new_pid);
 
       /* If we haven't already seen the new PID stop, wait for it now.  */
-      if (! pull_pid_from_list (&stopped_pids, new_pid))
+      if (!pull_pid_from_list (&stopped_pids, new_pid, &status))
        {
          /* The new child has a pending SIGSTOP.  We can't affect it until it
             hits the SIGSTOP, but we're already attached.  */
@@ -193,11 +417,17 @@ handle_extended_wait (struct lwp_info *event_child, int wstat)
            warning ("wait returned unexpected status 0x%x", status);
        }
 
-      ptrace (PTRACE_SETOPTIONS, new_pid, 0, PTRACE_O_TRACECLONE);
+      linux_enable_event_reporting (new_pid);
+
+      ptid = ptid_build (pid_of (event_child), new_pid, 0);
+      new_lwp = (struct lwp_info *) add_lwp (ptid);
+      add_thread (ptid, new_lwp);
 
-      new_lwp = (struct lwp_info *) add_lwp (new_pid);
-      add_thread (new_pid, new_lwp, new_pid);
-      new_thread_notify (thread_id_to_gdb_id (lwpid_of (new_lwp)));
+      /* Either we're going to immediately resume the new thread
+        or leave it stopped.  linux_resume_one_lwp is a nop if it
+        thinks the thread is currently running, so set this first
+        before calling linux_resume_one_lwp.  */
+      new_lwp->stopped = 1;
 
       /* Normally we will get the pending SIGSTOP.  But in some cases
         we might get another signal delivered to the group first.
@@ -205,34 +435,60 @@ handle_extended_wait (struct lwp_info *event_child, int wstat)
       if (WSTOPSIG (status) == SIGSTOP)
        {
          if (stopping_threads)
-           new_lwp->stopped = 1;
+           new_lwp->stop_pc = get_stop_pc (new_lwp);
          else
-           ptrace (PTRACE_CONT, new_pid, 0, 0);
+           linux_resume_one_lwp (new_lwp, 0, 0, NULL);
        }
       else
        {
          new_lwp->stop_expected = 1;
+
          if (stopping_threads)
            {
-             new_lwp->stopped = 1;
+             new_lwp->stop_pc = get_stop_pc (new_lwp);
              new_lwp->status_pending_p = 1;
              new_lwp->status_pending = status;
            }
          else
            /* Pass the signal on.  This is what GDB does - except
               shouldn't we really report it instead?  */
-           ptrace (PTRACE_CONT, new_pid, 0, WSTOPSIG (status));
+           linux_resume_one_lwp (new_lwp, 0, WSTOPSIG (status), NULL);
        }
 
       /* Always resume the current thread.  If we are stopping
         threads, it will have a pending SIGSTOP; we may as well
         collect it now.  */
-      linux_resume_one_lwp (&event_child->head,
-                           event_child->stepping, 0, NULL);
+      linux_resume_one_lwp (event_child, event_child->stepping, 0, NULL);
     }
 }
 
-/* This function should only be called if the process got a SIGTRAP.
+/* Return the PC as read from the regcache of LWP, without any
+   adjustment.  */
+
+static CORE_ADDR
+get_pc (struct lwp_info *lwp)
+{
+  struct thread_info *saved_inferior;
+  struct regcache *regcache;
+  CORE_ADDR pc;
+
+  if (the_low_target.get_pc == NULL)
+    return 0;
+
+  saved_inferior = current_inferior;
+  current_inferior = get_lwp_thread (lwp);
+
+  regcache = get_thread_regcache (current_inferior, 1);
+  pc = (*the_low_target.get_pc) (regcache);
+
+  if (debug_threads)
+    fprintf (stderr, "pc is 0x%lx\n", (long) pc);
+
+  current_inferior = saved_inferior;
+  return pc;
+}
+
+/* This function should only be called if LWP got a SIGTRAP.
    The SIGTRAP could mean several things.
 
    On i386, where decr_pc_after_break is non-zero:
@@ -255,25 +511,39 @@ handle_extended_wait (struct lwp_info *event_child, int wstat)
    instruction.  */
 
 static CORE_ADDR
-get_stop_pc (void)
+get_stop_pc (struct lwp_info *lwp)
 {
-  CORE_ADDR stop_pc = (*the_low_target.get_pc) ();
+  CORE_ADDR stop_pc;
 
-  if (get_thread_lwp (current_inferior)->stepping)
-    return stop_pc;
-  else
-    return stop_pc - the_low_target.decr_pc_after_break;
+  if (the_low_target.get_pc == NULL)
+    return 0;
+
+  stop_pc = get_pc (lwp);
+
+  if (WSTOPSIG (lwp->last_status) == SIGTRAP
+      && !lwp->stepping
+      && !lwp->stopped_by_watchpoint
+      && lwp->last_status >> 16 == 0)
+    stop_pc -= the_low_target.decr_pc_after_break;
+
+  if (debug_threads)
+    fprintf (stderr, "stop pc is 0x%lx\n", (long) stop_pc);
+
+  return stop_pc;
 }
 
 static void *
-add_lwp (unsigned long pid)
+add_lwp (ptid_t ptid)
 {
   struct lwp_info *lwp;
 
   lwp = (struct lwp_info *) xmalloc (sizeof (*lwp));
   memset (lwp, 0, sizeof (*lwp));
 
-  lwp->head.id = pid;
+  lwp->head.id = ptid;
+
+  if (the_low_target.new_thread != NULL)
+    lwp->arch_private = the_low_target.new_thread ();
 
   add_inferior_to_list (&all_lwps, &lwp->head);
 
@@ -286,8 +556,29 @@ add_lwp (unsigned long pid)
 static int
 linux_create_inferior (char *program, char **allargs)
 {
-  void *new_lwp;
+#ifdef HAVE_PERSONALITY
+  int personality_orig = 0, personality_set = 0;
+#endif
+  struct lwp_info *new_lwp;
   int pid;
+  ptid_t ptid;
+
+#ifdef HAVE_PERSONALITY
+  if (disable_randomization)
+    {
+      errno = 0;
+      personality_orig = personality (0xffffffff);
+      if (errno == 0 && !(personality_orig & ADDR_NO_RANDOMIZE))
+       {
+         personality_set = 1;
+         personality (personality_orig | ADDR_NO_RANDOMIZE);
+       }
+      if (errno != 0 || (personality_set
+                        && !(personality (0xffffffff) & ADDR_NO_RANDOMIZE)))
+       warning ("Error disabling address space randomization: %s",
+                strerror (errno));
+    }
+#endif
 
 #if defined(__UCLIBC__) && defined(HAS_NOMMU)
   pid = vfork ();
@@ -301,10 +592,25 @@ linux_create_inferior (char *program, char **allargs)
     {
       ptrace (PTRACE_TRACEME, 0, 0, 0);
 
+#ifndef __ANDROID__ /* Bionic doesn't use SIGRTMIN the way glibc does.  */
       signal (__SIGRTMIN + 1, SIG_DFL);
+#endif
 
       setpgid (0, 0);
 
+      /* If gdbserver is connected to gdb via stdio, redirect the inferior's
+        stdout to stderr so that inferior i/o doesn't corrupt the connection.
+        Also, redirect stdin to /dev/null.  */
+      if (remote_connection_is_stdio ())
+       {
+         close (0);
+         open ("/dev/null", O_RDONLY);
+         dup2 (2, 1);
+         if (write (2, "stdin/stdout redirected\n",
+                    sizeof ("stdin/stdout redirected\n") - 1) < 0)
+           /* Errors ignored.  */;
+       }
+
       execv (program, allargs);
       if (errno == ENOENT)
        execvp (program, allargs);
@@ -315,44 +621,98 @@ linux_create_inferior (char *program, char **allargs)
       _exit (0177);
     }
 
-  new_lwp = add_lwp (pid);
-  add_thread (pid, new_lwp, pid);
-  must_set_ptrace_flags = 1;
-  new_inferior = 1;
+#ifdef HAVE_PERSONALITY
+  if (personality_set)
+    {
+      errno = 0;
+      personality (personality_orig);
+      if (errno != 0)
+       warning ("Error restoring address space randomization: %s",
+                strerror (errno));
+    }
+#endif
+
+  linux_add_process (pid, 0);
+
+  ptid = ptid_build (pid, pid, 0);
+  new_lwp = add_lwp (ptid);
+  add_thread (ptid, new_lwp);
+  new_lwp->must_set_ptrace_flags = 1;
 
   return pid;
 }
 
 /* Attach to an inferior process.  */
 
-void
-linux_attach_lwp (unsigned long pid)
+static void
+linux_attach_lwp_1 (unsigned long lwpid, int initial)
 {
+  ptid_t ptid;
   struct lwp_info *new_lwp;
 
-  if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
+  if (ptrace (PTRACE_ATTACH, lwpid, 0, 0) != 0)
     {
-      if (all_threads.head != NULL)
+      if (!initial)
        {
          /* If we fail to attach to an LWP, just warn.  */
-         fprintf (stderr, "Cannot attach to lwp %ld: %s (%d)\n", pid,
+         fprintf (stderr, "Cannot attach to lwp %ld: %s (%d)\n", lwpid,
                   strerror (errno), errno);
          fflush (stderr);
          return;
        }
-      else
-       /* If we fail to attach to a process, report an error.  */
-       error ("Cannot attach to lwp %ld: %s (%d)\n", pid,
-              strerror (errno), errno);
+
+      /* If we fail to attach to a process, report an error.  */
+      error ("Cannot attach to lwp %ld: %s (%d)\n", lwpid,
+            strerror (errno), errno);
+    }
+
+  if (initial)
+    /* If lwp is the tgid, we handle adding existing threads later.
+       Otherwise we just add lwp without bothering about any other
+       threads.  */
+    ptid = ptid_build (lwpid, lwpid, 0);
+  else
+    {
+      /* Note that extracting the pid from the current inferior is
+        safe, since we're always called in the context of the same
+        process as this new thread.  */
+      int pid = pid_of (get_thread_lwp (current_inferior));
+      ptid = ptid_build (pid, lwpid, 0);
     }
 
-  /* FIXME: This intermittently fails.
-     We need to wait for SIGSTOP first.  */
-  ptrace (PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACECLONE);
+  new_lwp = (struct lwp_info *) add_lwp (ptid);
+  add_thread (ptid, new_lwp);
 
-  new_lwp = (struct lwp_info *) add_lwp (pid);
-  add_thread (pid, new_lwp, pid);
-  new_thread_notify (thread_id_to_gdb_id (lwpid_of (new_lwp)));
+  /* We need to wait for SIGSTOP before being able to make the next
+     ptrace call on this LWP.  */
+  new_lwp->must_set_ptrace_flags = 1;
+
+  if (linux_proc_pid_is_stopped (lwpid))
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "Attached to a stopped process\n");
+
+      /* The process is definitely stopped.  It is in a job control
+        stop, unless the kernel predates the TASK_STOPPED /
+        TASK_TRACED distinction, in which case it might be in a
+        ptrace stop.  Make sure it is in a ptrace stop; from there we
+        can kill it, signal it, et cetera.
+
+        First make sure there is a pending SIGSTOP.  Since we are
+        already attached, the process can not transition from stopped
+        to running without a PTRACE_CONT; so we know this signal will
+        go into the queue.  The SIGSTOP generated by PTRACE_ATTACH is
+        probably already in the queue (unless this kernel is old
+        enough to use TASK_STOPPED for ptrace stops); but since
+        SIGSTOP is not an RT signal, it can only be queued once.  */
+      kill_lwp (lwpid, SIGSTOP);
+
+      /* Finally, resume the stopped process.  This will deliver the
+        SIGSTOP (or a higher priority signal, just like normal
+        PTRACE_ATTACH), which we'll catch later on.  */
+      ptrace (PTRACE_CONT, lwpid, 0, 0);
+    }
 
   /* The next time we wait for this LWP we'll see a SIGSTOP as PTRACE_ATTACH
      brings it to a halt.
@@ -361,16 +721,20 @@ linux_attach_lwp (unsigned long pid)
 
      1) gdbserver has already attached to the process and is being notified
        of a new thread that is being created.
-       In this case we should ignore that SIGSTOP and resume the process.
-       This is handled below by setting stop_expected = 1.
+       In this case we should ignore that SIGSTOP and resume the
+       process.  This is handled below by setting stop_expected = 1,
+       and the fact that add_thread sets last_resume_kind ==
+       resume_continue.
 
      2) This is the first thread (the process thread), and we're attaching
        to it via attach_inferior.
        In this case we want the process thread to stop.
-       This is handled by having linux_attach clear stop_expected after
-       we return.
-       ??? If the process already has several threads we leave the other
-       threads running.
+       This is handled by having linux_attach set last_resume_kind ==
+       resume_stop after we return.
+
+       If the pid we are attaching to is also the tgid, we attach to and
+       stop all the existing threads.  Otherwise, we attach to pid and
+       ignore any other threads in the same group as this pid.
 
      3) GDB is connecting to gdbserver and is requesting an enumeration of all
        existing threads.
@@ -385,174 +749,455 @@ linux_attach_lwp (unsigned long pid)
      because we are guaranteed that the add_lwp call above added us to the
      end of the list, and so the new thread has not yet reached
      wait_for_sigstop (but will).  */
-  if (! stopping_threads)
-    new_lwp->stop_expected = 1;
+  new_lwp->stop_expected = 1;
+}
+
+void
+linux_attach_lwp (unsigned long lwpid)
+{
+  linux_attach_lwp_1 (lwpid, 0);
 }
 
+/* Attach to PID.  If PID is the tgid, attach to it and all
+   of its threads.  */
+
 int
 linux_attach (unsigned long pid)
 {
-  struct lwp_info *lwp;
-
-  linux_attach_lwp (pid);
+  /* Attach to PID.  We will check for other threads
+     soon.  */
+  linux_attach_lwp_1 (pid, 1);
+  linux_add_process (pid, 1);
 
   if (!non_stop)
     {
-      /* Don't ignore the initial SIGSTOP if we just attached to this
-        process.  It will be collected by wait shortly.  */
-      lwp = (struct lwp_info *) find_inferior_id (&all_lwps, pid);
-      lwp->stop_expected = 0;
+      struct thread_info *thread;
+
+     /* Don't ignore the initial SIGSTOP if we just attached to this
+       process.  It will be collected by wait shortly.  */
+      thread = find_thread_ptid (ptid_build (pid, pid, 0));
+      thread->last_resume_kind = resume_stop;
     }
 
-  new_inferior = 1;
+  if (linux_proc_get_tgid (pid) == pid)
+    {
+      DIR *dir;
+      char pathname[128];
+
+      sprintf (pathname, "/proc/%ld/task", pid);
+
+      dir = opendir (pathname);
+
+      if (!dir)
+       {
+         fprintf (stderr, "Could not open /proc/%ld/task.\n", pid);
+         fflush (stderr);
+       }
+      else
+       {
+         /* At this point we attached to the tgid.  Scan the task for
+            existing threads.  */
+         unsigned long lwp;
+         int new_threads_found;
+         int iterations = 0;
+         struct dirent *dp;
+
+         while (iterations < 2)
+           {
+             new_threads_found = 0;
+             /* Add all the other threads.  While we go through the
+                threads, new threads may be spawned.  Cycle through
+                the list of threads until we have done two iterations without
+                finding new threads.  */
+             while ((dp = readdir (dir)) != NULL)
+               {
+                 /* Fetch one lwp.  */
+                 lwp = strtoul (dp->d_name, NULL, 10);
+
+                 /* Is this a new thread?  */
+                 if (lwp
+                     && find_thread_ptid (ptid_build (pid, lwp, 0)) == NULL)
+                   {
+                     linux_attach_lwp_1 (lwp, 0);
+                     new_threads_found++;
+
+                     if (debug_threads)
+                       fprintf (stderr, "\
+Found and attached to new lwp %ld\n", lwp);
+                   }
+               }
+
+             if (!new_threads_found)
+               iterations++;
+             else
+               iterations = 0;
+
+             rewinddir (dir);
+           }
+         closedir (dir);
+       }
+    }
 
   return 0;
 }
 
-/* Kill the inferior process.  Make us have no inferior.  */
-
-static void
-linux_kill_one_lwp (struct inferior_list_entry *entry)
+struct counter
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct lwp_info *lwp = get_thread_lwp (thread);
   int pid;
-  int wstat;
+  int count;
+};
 
-  /* We avoid killing the first thread here, because of a Linux kernel (at
-     least 2.6.0-test7 through 2.6.8-rc4) bug; if we kill the parent before
-     the children get a chance to be reaped, it will remain a zombie
-     forever.  */
-  if (entry == all_threads.head)
-    return;
+static int
+second_thread_of_pid_p (struct inferior_list_entry *entry, void *args)
+{
+  struct counter *counter = args;
 
-  /* If we're killing a running inferior, make sure it is stopped
-     first, as PTRACE_KILL will not work otherwise.  */
-  if (!lwp->stopped)
-    send_sigstop (&lwp->head);
+  if (ptid_get_pid (entry->id) == counter->pid)
+    {
+      if (++counter->count > 1)
+       return 1;
+    }
+
+  return 0;
+}
+
+static int
+last_thread_of_process_p (struct thread_info *thread)
+{
+  ptid_t ptid = ((struct inferior_list_entry *)thread)->id;
+  int pid = ptid_get_pid (ptid);
+  struct counter counter = { pid , 0 };
+
+  return (find_inferior (&all_threads,
+                        second_thread_of_pid_p, &counter) == NULL);
+}
+
+/* Kill LWP.  */
+
+static void
+linux_kill_one_lwp (struct lwp_info *lwp)
+{
+  int pid = lwpid_of (lwp);
+
+  /* PTRACE_KILL is unreliable.  After stepping into a signal handler,
+     there is no signal context, and ptrace(PTRACE_KILL) (or
+     ptrace(PTRACE_CONT, SIGKILL), pretty much the same) acts like
+     ptrace(CONT, pid, 0,0) and just resumes the tracee.  A better
+     alternative is to kill with SIGKILL.  We only need one SIGKILL
+     per process, not one for each thread.  But since we still support
+     linuxthreads, and we also support debugging programs using raw
+     clone without CLONE_THREAD, we send one for each thread.  For
+     years, we used PTRACE_KILL only, so we're being a bit paranoid
+     about some old kernels where PTRACE_KILL might work better
+     (dubious if there are any such, but that's why it's paranoia), so
+     we try SIGKILL first, PTRACE_KILL second, and so we're fine
+     everywhere.  */
+
+  errno = 0;
+  kill (pid, SIGKILL);
+  if (debug_threads)
+    fprintf (stderr,
+            "LKL:  kill (SIGKILL) %s, 0, 0 (%s)\n",
+            target_pid_to_str (ptid_of (lwp)),
+            errno ? strerror (errno) : "OK");
+
+  errno = 0;
+  ptrace (PTRACE_KILL, pid, 0, 0);
+  if (debug_threads)
+    fprintf (stderr,
+            "LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
+            target_pid_to_str (ptid_of (lwp)),
+            errno ? strerror (errno) : "OK");
+}
+
+/* Callback for `find_inferior'.  Kills an lwp of a given process,
+   except the leader.  */
+
+static int
+kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
+{
+  struct thread_info *thread = (struct thread_info *) entry;
+  struct lwp_info *lwp = get_thread_lwp (thread);
+  int wstat;
+  int pid = * (int *) args;
+
+  if (ptid_get_pid (entry->id) != pid)
+    return 0;
+
+  /* We avoid killing the first thread here, because of a Linux kernel (at
+     least 2.6.0-test7 through 2.6.8-rc4) bug; if we kill the parent before
+     the children get a chance to be reaped, it will remain a zombie
+     forever.  */
+
+  if (lwpid_of (lwp) == pid)
+    {
+      if (debug_threads)
+       fprintf (stderr, "lkop: is last of process %s\n",
+                target_pid_to_str (entry->id));
+      return 0;
+    }
 
   do
     {
-      ptrace (PTRACE_KILL, lwpid_of (lwp), 0, 0);
+      linux_kill_one_lwp (lwp);
 
       /* Make sure it died.  The loop is most likely unnecessary.  */
-      pid = linux_wait_for_event (lwpid_of (lwp), &wstat, __WALL);
+      pid = linux_wait_for_event (lwp->head.id, &wstat, __WALL);
     } while (pid > 0 && WIFSTOPPED (wstat));
+
+  return 0;
 }
 
-static void
-linux_kill (void)
+static int
+linux_kill (int pid)
 {
-  struct thread_info *thread = (struct thread_info *) all_threads.head;
+  struct process_info *process;
   struct lwp_info *lwp;
   int wstat;
-  int pid;
+  int lwpid;
 
-  if (thread == NULL)
-    return;
+  process = find_process_pid (pid);
+  if (process == NULL)
+    return -1;
+
+  /* If we're killing a running inferior, make sure it is stopped
+     first, as PTRACE_KILL will not work otherwise.  */
+  stop_all_lwps (0, NULL);
 
-  for_each_inferior (&all_threads, linux_kill_one_lwp);
+  find_inferior (&all_threads, kill_one_lwp_callback , &pid);
 
   /* See the comment in linux_kill_one_lwp.  We did not kill the first
      thread in the list, so do so now.  */
-  lwp = get_thread_lwp (thread);
+  lwp = find_lwp_pid (pid_to_ptid (pid));
 
-  if (debug_threads)
-    fprintf (stderr, "lk_1: killing lwp %ld\n", lwpid_of (lwp));
+  if (lwp == NULL)
+    {
+      if (debug_threads)
+       fprintf (stderr, "lk_1: cannot find lwp %ld, for pid: %d\n",
+                lwpid_of (lwp), pid);
+    }
+  else
+    {
+      if (debug_threads)
+       fprintf (stderr, "lk_1: killing lwp %ld, for pid: %d\n",
+                lwpid_of (lwp), pid);
 
-  /* If we're killing a running inferior, make sure it is stopped
-     first, as PTRACE_KILL will not work otherwise.  */
-  if (!lwp->stopped)
-    send_sigstop (&lwp->head);
+      do
+       {
+         linux_kill_one_lwp (lwp);
 
-  do
-    {
-      ptrace (PTRACE_KILL, lwpid_of (lwp), 0, 0);
+         /* Make sure it died.  The loop is most likely unnecessary.  */
+         lwpid = linux_wait_for_event (lwp->head.id, &wstat, __WALL);
+       } while (lwpid > 0 && WIFSTOPPED (wstat));
+    }
 
-      /* Make sure it died.  The loop is most likely unnecessary.  */
-      pid = linux_wait_for_event (lwpid_of (lwp), &wstat, __WALL);
-    } while (pid > 0 && WIFSTOPPED (wstat));
+  the_target->mourn (process);
 
-  delete_lwp (lwp);
-  clear_inferiors ();
+  /* Since we presently can only stop all lwps of all processes, we
+     need to unstop lwps of other processes.  */
+  unstop_all_lwps (0, NULL);
+  return 0;
 }
 
-static void
-linux_detach_one_lwp (struct inferior_list_entry *entry)
+/* Get pending signal of THREAD, for detaching purposes.  This is the
+   signal the thread last stopped for, which we need to deliver to the
+   thread when detaching, otherwise, it'd be suppressed/lost.  */
+
+static int
+get_detach_signal (struct thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct lwp_info *lwp = get_thread_lwp (thread);
+  enum target_signal signo = TARGET_SIGNAL_0;
+  int status;
+  struct lwp_info *lp = get_thread_lwp (thread);
 
-  /* If we're detaching from a running inferior, make sure it is
-     stopped first, as PTRACE_DETACH will not work otherwise.  */
-  if (!lwp->stopped)
+  if (lp->status_pending_p)
+    status = lp->status_pending;
+  else
+    {
+      /* If the thread had been suspended by gdbserver, and it stopped
+        cleanly, then it'll have stopped with SIGSTOP.  But we don't
+        want to deliver that SIGSTOP.  */
+      if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
+         || thread->last_status.value.sig == TARGET_SIGNAL_0)
+       return 0;
+
+      /* Otherwise, we may need to deliver the signal we
+        intercepted.  */
+      status = lp->last_status;
+    }
+
+  if (!WIFSTOPPED (status))
     {
-      int pid = lwpid_of (lwp);
+      if (debug_threads)
+       fprintf (stderr,
+                "GPS: lwp %s hasn't stopped: no pending signal\n",
+                target_pid_to_str (ptid_of (lp)));
+      return 0;
+    }
 
-      stopping_threads = 1;
-      send_sigstop (&lwp->head);
+  /* Extended wait statuses aren't real SIGTRAPs.  */
+  if (WSTOPSIG (status) == SIGTRAP && status >> 16 != 0)
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "GPS: lwp %s had stopped with extended "
+                "status: no pending signal\n",
+                target_pid_to_str (ptid_of (lp)));
+      return 0;
+    }
 
-      /* If this detects a new thread through a clone event, the new
-        thread is appended to the end of the lwp list, so we'll
-        eventually detach from it.  */
-      wait_for_sigstop (&lwp->head);
-      stopping_threads = 0;
+  signo = target_signal_from_host (WSTOPSIG (status));
 
-      /* If LWP exits while we're trying to stop it, there's nothing
-        left to do.  */
-      lwp = (struct lwp_info *) find_inferior_id (&all_lwps, pid);
-      if (lwp == NULL)
-       return;
+  if (program_signals_p && !program_signals[signo])
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "GPS: lwp %s had signal %s, but it is in nopass state\n",
+                target_pid_to_str (ptid_of (lp)),
+                target_signal_to_string (signo));
+      return 0;
+    }
+  else if (!program_signals_p
+          /* If we have no way to know which signals GDB does not
+             want to have passed to the program, assume
+             SIGTRAP/SIGINT, which is GDB's default.  */
+          && (signo == TARGET_SIGNAL_TRAP || signo == TARGET_SIGNAL_INT))
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "GPS: lwp %s had signal %s, "
+                "but we don't know if we should pass it.  Default to not.\n",
+                target_pid_to_str (ptid_of (lp)),
+                target_signal_to_string (signo));
+      return 0;
+    }
+  else
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "GPS: lwp %s has pending signal %s: delivering it.\n",
+                target_pid_to_str (ptid_of (lp)),
+                target_signal_to_string (signo));
+
+      return WSTOPSIG (status);
     }
+}
+
+static int
+linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
+{
+  struct thread_info *thread = (struct thread_info *) entry;
+  struct lwp_info *lwp = get_thread_lwp (thread);
+  int pid = * (int *) args;
+  int sig;
 
-  /* Make sure the process isn't stopped at a breakpoint that's
-     no longer there.  */
-  check_removed_breakpoint (lwp);
+  if (ptid_get_pid (entry->id) != pid)
+    return 0;
 
-  /* If this process is stopped but is expecting a SIGSTOP, then make
-     sure we take care of that now.  This isn't absolutely guaranteed
-     to collect the SIGSTOP, but is fairly likely to.  */
+  /* If there is a pending SIGSTOP, get rid of it.  */
   if (lwp->stop_expected)
     {
-      int wstat;
-      /* Clear stop_expected, so that the SIGSTOP will be reported.  */
+      if (debug_threads)
+       fprintf (stderr,
+                "Sending SIGCONT to %s\n",
+                target_pid_to_str (ptid_of (lwp)));
+
+      kill_lwp (lwpid_of (lwp), SIGCONT);
       lwp->stop_expected = 0;
-      if (lwp->stopped)
-       linux_resume_one_lwp (&lwp->head, 0, 0, NULL);
-      linux_wait_for_event (lwpid_of (lwp), &wstat, __WALL);
     }
 
   /* Flush any pending changes to the process's registers.  */
   regcache_invalidate_one ((struct inferior_list_entry *)
                           get_lwp_thread (lwp));
 
+  /* Pass on any pending signal for this thread.  */
+  sig = get_detach_signal (thread);
+
   /* Finally, let it resume.  */
-  ptrace (PTRACE_DETACH, lwpid_of (lwp), 0, 0);
+  if (the_low_target.prepare_to_resume != NULL)
+    the_low_target.prepare_to_resume (lwp);
+  if (ptrace (PTRACE_DETACH, lwpid_of (lwp), 0, sig) < 0)
+    error (_("Can't detach %s: %s"),
+          target_pid_to_str (ptid_of (lwp)),
+          strerror (errno));
 
   delete_lwp (lwp);
+  return 0;
+}
+
+static int
+linux_detach (int pid)
+{
+  struct process_info *process;
+
+  process = find_process_pid (pid);
+  if (process == NULL)
+    return -1;
+
+  /* Stop all threads before detaching.  First, ptrace requires that
+     the thread is stopped to sucessfully detach.  Second, thread_db
+     may need to uninstall thread event breakpoints from memory, which
+     only works with a stopped process anyway.  */
+  stop_all_lwps (0, NULL);
+
+#ifdef USE_THREAD_DB
+  thread_db_detach (process);
+#endif
+
+  /* Stabilize threads (move out of jump pads).  */
+  stabilize_threads ();
+
+  find_inferior (&all_threads, linux_detach_one_lwp, &pid);
+
+  the_target->mourn (process);
+
+  /* Since we presently can only stop all lwps of all processes, we
+     need to unstop lwps of other processes.  */
+  unstop_all_lwps (0, NULL);
+  return 0;
 }
 
+/* Remove all LWPs that belong to process PROC from the lwp list.  */
+
 static int
-linux_detach (void)
+delete_lwp_callback (struct inferior_list_entry *entry, void *proc)
 {
-  delete_all_breakpoints ();
-  for_each_inferior (&all_threads, linux_detach_one_lwp);
-  clear_inferiors ();
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+  struct process_info *process = proc;
+
+  if (pid_of (lwp) == pid_of (process))
+    delete_lwp (lwp);
+
   return 0;
 }
 
 static void
-linux_join (void)
+linux_mourn (struct process_info *process)
 {
-  int status, ret;
-  struct thread_info *thread;
-  struct lwp_info *lwp;
+  struct process_info_private *priv;
 
-  thread = (struct thread_info *) all_threads.head;
-  lwp = get_thread_lwp (thread);
+#ifdef USE_THREAD_DB
+  thread_db_mourn (process);
+#endif
+
+  find_inferior (&all_lwps, delete_lwp_callback, process);
+
+  /* Freeing all private data.  */
+  priv = process->private;
+  free (priv->arch_private);
+  free (priv);
+  process->private = NULL;
+
+  remove_process (process);
+}
+
+static void
+linux_join (int pid)
+{
+  int status, ret;
 
   do {
-    ret = my_waitpid (lwpid_of (lwp), &status, 0);
+    ret = my_waitpid (pid, &status, 0);
     if (WIFEXITED (status) || WIFSIGNALED (status))
       break;
   } while (ret != -1 || errno != ECHILD);
@@ -560,108 +1205,81 @@ linux_join (void)
 
 /* Return nonzero if the given thread is still alive.  */
 static int
-linux_thread_alive (unsigned long lwpid)
+linux_thread_alive (ptid_t ptid)
 {
-  if (find_inferior_id (&all_threads, lwpid) != NULL)
-    return 1;
+  struct lwp_info *lwp = find_lwp_pid (ptid);
+
+  /* We assume we always know if a thread exits.  If a whole process
+     exited but we still haven't been able to report it to GDB, we'll
+     hold on to the last lwp of the dead process.  */
+  if (lwp != NULL)
+    return !lwp->dead;
   else
     return 0;
 }
 
-/* Return nonzero if this process stopped at a breakpoint which
-   no longer appears to be inserted.  Also adjust the PC
-   appropriately to resume where the breakpoint used to be.  */
+/* Return 1 if this lwp has an interesting status pending.  */
 static int
-check_removed_breakpoint (struct lwp_info *event_child)
+status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
 {
-  CORE_ADDR stop_pc;
-  struct thread_info *saved_inferior;
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+  ptid_t ptid = * (ptid_t *) arg;
+  struct thread_info *thread;
 
-  if (event_child->pending_is_breakpoint == 0)
+  /* Check if we're only interested in events from a specific process
+     or its lwps.  */
+  if (!ptid_equal (minus_one_ptid, ptid)
+      && ptid_get_pid (ptid) != ptid_get_pid (lwp->head.id))
     return 0;
 
-  if (debug_threads)
-    fprintf (stderr, "Checking for breakpoint in lwp %ld.\n",
-            lwpid_of (event_child));
-
-  saved_inferior = current_inferior;
-  current_inferior = get_lwp_thread (event_child);
-
-  stop_pc = get_stop_pc ();
-
-  /* If the PC has changed since we stopped, then we shouldn't do
-     anything.  This happens if, for instance, GDB handled the
-     decr_pc_after_break subtraction itself.  */
-  if (stop_pc != event_child->pending_stop_pc)
-    {
-      if (debug_threads)
-       fprintf (stderr, "Ignoring, PC was changed.  Old PC was 0x%08llx\n",
-                event_child->pending_stop_pc);
+  thread = get_lwp_thread (lwp);
 
-      event_child->pending_is_breakpoint = 0;
-      current_inferior = saved_inferior;
-      return 0;
-    }
+  /* If we got a `vCont;t', but we haven't reported a stop yet, do
+     report any status pending the LWP may have.  */
+  if (thread->last_resume_kind == resume_stop
+      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
+    return 0;
 
-  /* If the breakpoint is still there, we will report hitting it.  */
-  if ((*the_low_target.breakpoint_at) (stop_pc))
-    {
-      if (debug_threads)
-       fprintf (stderr, "Ignoring, breakpoint is still present.\n");
-      current_inferior = saved_inferior;
-      return 0;
-    }
+  return lwp->status_pending_p;
+}
 
-  if (debug_threads)
-    fprintf (stderr, "Removed breakpoint.\n");
+static int
+same_lwp (struct inferior_list_entry *entry, void *data)
+{
+  ptid_t ptid = *(ptid_t *) data;
+  int lwp;
 
-  /* For decr_pc_after_break targets, here is where we perform the
-     decrement.  We go immediately from this function to resuming,
-     and can not safely call get_stop_pc () again.  */
-  if (the_low_target.set_pc != NULL)
-    (*the_low_target.set_pc) (stop_pc);
+  if (ptid_get_lwp (ptid) != 0)
+    lwp = ptid_get_lwp (ptid);
+  else
+    lwp = ptid_get_pid (ptid);
 
-  /* We consumed the pending SIGTRAP.  */
-  event_child->pending_is_breakpoint = 0;
-  event_child->status_pending_p = 0;
-  event_child->status_pending = 0;
+  if (ptid_get_lwp (entry->id) == lwp)
+    return 1;
 
-  current_inferior = saved_inferior;
-  return 1;
+  return 0;
 }
 
-/* Return 1 if this lwp has an interesting status pending.  This
-   function may silently resume an inferior lwp.  */
-static int
-status_pending_p (struct inferior_list_entry *entry, void *dummy)
+struct lwp_info *
+find_lwp_pid (ptid_t ptid)
 {
-  struct lwp_info *lwp = (struct lwp_info *) entry;
-
-  if (lwp->status_pending_p && !lwp->suspended)
-    if (check_removed_breakpoint (lwp))
-      {
-       /* This thread was stopped at a breakpoint, and the breakpoint
-          is now gone.  We were told to continue (or step...) all threads,
-          so GDB isn't trying to single-step past this breakpoint.
-          So instead of reporting the old SIGTRAP, pretend we got to
-          the breakpoint just after it was removed instead of just
-          before; resume the process.  */
-       linux_resume_one_lwp (&lwp->head, 0, 0, NULL);
-       return 0;
-      }
-
-  return (lwp->status_pending_p && !lwp->suspended);
+  return (struct lwp_info*) find_inferior (&all_lwps, same_lwp, &ptid);
 }
 
 static struct lwp_info *
-linux_wait_for_lwp (int pid, int *wstatp, int options)
+linux_wait_for_lwp (ptid_t ptid, int *wstatp, int options)
 {
   int ret;
-  int to_wait_for = pid;
+  int to_wait_for = -1;
   struct lwp_info *child = NULL;
 
   if (debug_threads)
-    fprintf (stderr, "linux_wait_for_lwp: %d\n", pid);
+    fprintf (stderr, "linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
+
+  if (ptid_equal (ptid, minus_one_ptid))
+    to_wait_for = -1;                  /* any child */
+  else
+    to_wait_for = ptid_get_lwp (ptid); /* this lwp only */
 
   options |= __WALL;
 
@@ -679,7 +1297,7 @@ retry:
              && WSTOPSIG (*wstatp) != 33)))
     fprintf (stderr, "Got an event from %d (%x)\n", ret, *wstatp);
 
-  child = (struct lwp_info *) find_inferior_id (&all_lwps, ret);
+  child = find_lwp_pid (pid_to_ptid (ret));
 
   /* If we didn't find a process, one of two things presumably happened:
      - A process we started and then detached from has exited.  Ignore it.
@@ -687,14 +1305,13 @@ retry:
      was reported to us by the kernel.  Save its PID.  */
   if (child == NULL && WIFSTOPPED (*wstatp))
     {
-      add_pid_to_list (&stopped_pids, ret);
+      add_to_pid_list (&stopped_pids, ret, *wstatp);
       goto retry;
     }
   else if (child == NULL)
     goto retry;
 
   child->stopped = 1;
-  child->pending_is_breakpoint = 0;
 
   child->last_status = *wstatp;
 
@@ -711,1926 +1328,4296 @@ retry:
       new_inferior = 0;
     }
 
+  /* Fetch the possibly triggered data watchpoint info and store it in
+     CHILD.
+
+     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 CHILD stop with a SIGTRAP.  If GDB
+     changes the debug registers meanwhile, we have the cached data we
+     can rely on.  */
+
+  if (WIFSTOPPED (*wstatp) && WSTOPSIG (*wstatp) == SIGTRAP)
+    {
+      if (the_low_target.stopped_by_watchpoint == NULL)
+       {
+         child->stopped_by_watchpoint = 0;
+       }
+      else
+       {
+         struct thread_info *saved_inferior;
+
+         saved_inferior = current_inferior;
+         current_inferior = get_lwp_thread (child);
+
+         child->stopped_by_watchpoint
+           = the_low_target.stopped_by_watchpoint ();
+
+         if (child->stopped_by_watchpoint)
+           {
+             if (the_low_target.stopped_data_address != NULL)
+               child->stopped_data_address
+                 = the_low_target.stopped_data_address ();
+             else
+               child->stopped_data_address = 0;
+           }
+
+         current_inferior = saved_inferior;
+       }
+    }
+
+  /* Store the STOP_PC, with adjustment applied.  This depends on the
+     architecture being defined already (so that CHILD has a valid
+     regcache), and on LAST_STATUS being set (to check for SIGTRAP or
+     not).  */
+  if (WIFSTOPPED (*wstatp))
+    child->stop_pc = get_stop_pc (child);
+
   if (debug_threads
-      && WIFSTOPPED (*wstatp))
+      && WIFSTOPPED (*wstatp)
+      && the_low_target.get_pc != NULL)
     {
       struct thread_info *saved_inferior = current_inferior;
-      current_inferior = (struct thread_info *)
-       find_inferior_id (&all_threads, lwpid_of (child));
-      /* For testing only; i386_stop_pc prints out a diagnostic.  */
-      if (the_low_target.get_pc != NULL)
-       get_stop_pc ();
+      struct regcache *regcache;
+      CORE_ADDR pc;
+
+      current_inferior = get_lwp_thread (child);
+      regcache = get_thread_regcache (current_inferior, 1);
+      pc = (*the_low_target.get_pc) (regcache);
+      fprintf (stderr, "linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
       current_inferior = saved_inferior;
     }
 
   return child;
 }
 
-/* Wait for an event from child PID.  If PID is -1, wait for any
-   child.  Store the stop status through the status pointer WSTAT.
-   OPTIONS is passed to the waitpid call.  Return 0 if no child stop
-   event was found and OPTIONS contains WNOHANG.  Return the PID of
-   the stopped child otherwise.  */
+/* This function should only be called if the LWP got a SIGTRAP.
+
+   Handle any tracepoint steps or hits.  Return true if a tracepoint
+   event was handled, 0 otherwise.  */
 
 static int
-linux_wait_for_event (int pid, int *wstat, int options)
+handle_tracepoints (struct lwp_info *lwp)
 {
-  CORE_ADDR stop_pc;
-  struct lwp_info *event_child = NULL;
-  int bp_status;
-  struct lwp_info *requested_child = NULL;
+  struct thread_info *tinfo = get_lwp_thread (lwp);
+  int tpoint_related_event = 0;
 
-  /* Check for a process with a pending status.  */
-  /* It is possible that the user changed the pending task's registers since
-     it stopped.  We correctly handle the change of PC if we hit a breakpoint
-     (in check_removed_breakpoint); signals should be reported anyway.  */
+  /* If this tracepoint hit causes a tracing stop, we'll immediately
+     uninsert tracepoints.  To do this, we temporarily pause all
+     threads, unpatch away, and then unpause threads.  We need to make
+     sure the unpausing doesn't resume LWP too.  */
+  lwp->suspended++;
 
-  if (pid == -1)
-    {
-      event_child = (struct lwp_info *)
-       find_inferior (&all_lwps, status_pending_p, NULL);
-      if (debug_threads && event_child)
-       fprintf (stderr, "Got a pending child %ld\n", lwpid_of (event_child));
-    }
-  else
-    {
-      requested_child = (struct lwp_info *)
-       find_inferior_id (&all_lwps, pid);
-      if (requested_child->status_pending_p
-         && !check_removed_breakpoint (requested_child))
-       event_child = requested_child;
-    }
+  /* And we need to be sure that any all-threads-stopping doesn't try
+     to move threads out of the jump pads, as it could deadlock the
+     inferior (LWP could be in the jump pad, maybe even holding the
+     lock.)  */
 
-  if (event_child != NULL)
+  /* Do any necessary step collect actions.  */
+  tpoint_related_event |= tracepoint_finished_step (tinfo, lwp->stop_pc);
+
+  tpoint_related_event |= handle_tracepoint_bkpts (tinfo, lwp->stop_pc);
+
+  /* See if we just hit a tracepoint and do its main collect
+     actions.  */
+  tpoint_related_event |= tracepoint_was_hit (tinfo, lwp->stop_pc);
+
+  lwp->suspended--;
+
+  gdb_assert (lwp->suspended == 0);
+  gdb_assert (!stabilizing_threads || lwp->collecting_fast_tracepoint);
+
+  if (tpoint_related_event)
     {
       if (debug_threads)
-       fprintf (stderr, "Got an event from pending child %ld (%04x)\n",
-                lwpid_of (event_child), event_child->status_pending);
-      *wstat = event_child->status_pending;
-      event_child->status_pending_p = 0;
-      event_child->status_pending = 0;
-      current_inferior = get_lwp_thread (event_child);
-      return lwpid_of (event_child);
+       fprintf (stderr, "got a tracepoint event\n");
+      return 1;
     }
 
-  /* We only enter this loop if no process has a pending wait status.  Thus
-     any action taken in response to a wait status inside this loop is
-     responding as soon as we detect the status, not after any pending
-     events.  */
-  while (1)
-    {
-      event_child = linux_wait_for_lwp (pid, wstat, options);
+  return 0;
+}
 
-      if ((options & WNOHANG) && event_child == NULL)
-       return 0;
+/* Convenience wrapper.  Returns true if LWP is presently collecting a
+   fast tracepoint.  */
 
-      if (event_child == NULL)
-       error ("event from unknown child");
+static int
+linux_fast_tracepoint_collecting (struct lwp_info *lwp,
+                                 struct fast_tpoint_collect_status *status)
+{
+  CORE_ADDR thread_area;
 
-      current_inferior = get_lwp_thread (event_child);
+  if (the_low_target.get_thread_area == NULL)
+    return 0;
 
-      /* Check for thread exit.  */
-      if (! WIFSTOPPED (*wstat))
-       {
-         int lwpid = lwpid_of (event_child);
-         if (debug_threads)
-           fprintf (stderr, "LWP %d exiting\n", lwpid);
+  /* Get the thread area address.  This is used to recognize which
+     thread is which when tracing with the in-process agent library.
+     We don't read anything from the address, and treat it as opaque;
+     it's the address itself that we assume is unique per-thread.  */
+  if ((*the_low_target.get_thread_area) (lwpid_of (lwp), &thread_area) == -1)
+    return 0;
 
-         /* If the last thread is exiting, just return.  */
-         if (all_threads.head == all_threads.tail)
+  return fast_tracepoint_collecting (thread_area, lwp->stop_pc, status);
+}
+
+/* The reason we resume in the caller, is because we want to be able
+   to pass lwp->status_pending as WSTAT, and we need to clear
+   status_pending_p before resuming, otherwise, linux_resume_one_lwp
+   refuses to resume.  */
+
+static int
+maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
+{
+  struct thread_info *saved_inferior;
+
+  saved_inferior = current_inferior;
+  current_inferior = get_lwp_thread (lwp);
+
+  if ((wstat == NULL
+       || (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) != SIGTRAP))
+      && supports_fast_tracepoints ()
+      && agent_loaded_p ())
+    {
+      struct fast_tpoint_collect_status status;
+      int r;
+
+      if (debug_threads)
+       fprintf (stderr, "\
+Checking whether LWP %ld needs to move out of the jump pad.\n",
+                lwpid_of (lwp));
+
+      r = linux_fast_tracepoint_collecting (lwp, &status);
+
+      if (wstat == NULL
+         || (WSTOPSIG (*wstat) != SIGILL
+             && WSTOPSIG (*wstat) != SIGFPE
+             && WSTOPSIG (*wstat) != SIGSEGV
+             && WSTOPSIG (*wstat) != SIGBUS))
+       {
+         lwp->collecting_fast_tracepoint = r;
+
+         if (r != 0)
            {
+             if (r == 1 && lwp->exit_jump_pad_bkpt == NULL)
+               {
+                 /* Haven't executed the original instruction yet.
+                    Set breakpoint there, and wait till it's hit,
+                    then single-step until exiting the jump pad.  */
+                 lwp->exit_jump_pad_bkpt
+                   = set_breakpoint_at (status.adjusted_insn_addr, NULL);
+               }
+
              if (debug_threads)
-               fprintf (stderr, "LWP %d is last lwp of process\n", lwpid);
-             return lwpid_of (event_child);
+               fprintf (stderr, "\
+Checking whether LWP %ld needs to move out of the jump pad...it does\n",
+                lwpid_of (lwp));
+             current_inferior = saved_inferior;
+
+             return 1;
            }
+       }
+      else
+       {
+         /* If we get a synchronous signal while collecting, *and*
+            while executing the (relocated) original instruction,
+            reset the PC to point at the tpoint address, before
+            reporting to GDB.  Otherwise, it's an IPA lib bug: just
+            report the signal to GDB, and pray for the best.  */
 
-         dead_thread_notify (thread_id_to_gdb_id (lwpid_of (event_child)));
-         delete_lwp (event_child);
+         lwp->collecting_fast_tracepoint = 0;
 
-         if (!non_stop)
+         if (r != 0
+             && (status.adjusted_insn_addr <= lwp->stop_pc
+                 && lwp->stop_pc < status.adjusted_insn_addr_end))
            {
-             current_inferior = (struct thread_info *) all_threads.head;
-             if (debug_threads)
-               fprintf (stderr, "Current inferior is now %ld\n",
-                        lwpid_of (get_thread_lwp (current_inferior)));
+             siginfo_t info;
+             struct regcache *regcache;
+
+             /* The si_addr on a few signals references the address
+                of the faulting instruction.  Adjust that as
+                well.  */
+             if ((WSTOPSIG (*wstat) == SIGILL
+                  || WSTOPSIG (*wstat) == SIGFPE
+                  || WSTOPSIG (*wstat) == SIGBUS
+                  || WSTOPSIG (*wstat) == SIGSEGV)
+                 && ptrace (PTRACE_GETSIGINFO, lwpid_of (lwp), 0, &info) == 0
+                 /* Final check just to make sure we don't clobber
+                    the siginfo of non-kernel-sent signals.  */
+                 && (uintptr_t) info.si_addr == lwp->stop_pc)
+               {
+                 info.si_addr = (void *) (uintptr_t) status.tpoint_addr;
+                 ptrace (PTRACE_SETSIGINFO, lwpid_of (lwp), 0, &info);
+               }
+
+             regcache = get_thread_regcache (get_lwp_thread (lwp), 1);
+             (*the_low_target.set_pc) (regcache, status.tpoint_addr);
+             lwp->stop_pc = status.tpoint_addr;
+
+             /* Cancel any fast tracepoint lock this thread was
+                holding.  */
+             force_unlock_trace_buffer ();
            }
-         else
+
+         if (lwp->exit_jump_pad_bkpt != NULL)
            {
-             current_inferior = NULL;
              if (debug_threads)
-               fprintf (stderr, "Current inferior is now <NULL>\n");
-           }
+               fprintf (stderr,
+                        "Cancelling fast exit-jump-pad: removing bkpt. "
+                        "stopping all threads momentarily.\n");
 
-         /* If we were waiting for this particular child to do something...
-            well, it did something.  */
-         if (requested_child != NULL)
-           return lwpid;
+             stop_all_lwps (1, lwp);
+             cancel_breakpoints ();
 
-         /* Wait for a more interesting event.  */
-         continue;
-       }
+             delete_breakpoint (lwp->exit_jump_pad_bkpt);
+             lwp->exit_jump_pad_bkpt = NULL;
 
-      if (WIFSTOPPED (*wstat)
-         && WSTOPSIG (*wstat) == SIGSTOP
-         && event_child->stop_expected)
-       {
-         if (debug_threads)
-           fprintf (stderr, "Expected stop.\n");
-         event_child->stop_expected = 0;
-         linux_resume_one_lwp (&event_child->head,
-                               event_child->stepping, 0, NULL);
-         continue;
+             unstop_all_lwps (1, lwp);
+
+             gdb_assert (lwp->suspended >= 0);
+           }
        }
+    }
 
-      if (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) == SIGTRAP
-         && *wstat >> 16 != 0)
+  if (debug_threads)
+    fprintf (stderr, "\
+Checking whether LWP %ld needs to move out of the jump pad...no\n",
+            lwpid_of (lwp));
+
+  current_inferior = saved_inferior;
+  return 0;
+}
+
+/* Enqueue one signal in the "signals to report later when out of the
+   jump pad" list.  */
+
+static void
+enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
+{
+  struct pending_signals *p_sig;
+
+  if (debug_threads)
+    fprintf (stderr, "\
+Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
+
+  if (debug_threads)
+    {
+      struct pending_signals *sig;
+
+      for (sig = lwp->pending_signals_to_report;
+          sig != NULL;
+          sig = sig->prev)
+       fprintf (stderr,
+                "   Already queued %d\n",
+                sig->signal);
+
+      fprintf (stderr, "   (no more currently queued signals)\n");
+    }
+
+  /* Don't enqueue non-RT signals if they are already in the deferred
+     queue.  (SIGSTOP being the easiest signal to see ending up here
+     twice)  */
+  if (WSTOPSIG (*wstat) < __SIGRTMIN)
+    {
+      struct pending_signals *sig;
+
+      for (sig = lwp->pending_signals_to_report;
+          sig != NULL;
+          sig = sig->prev)
        {
-         handle_extended_wait (event_child, *wstat);
-         continue;
+         if (sig->signal == WSTOPSIG (*wstat))
+           {
+             if (debug_threads)
+               fprintf (stderr,
+                        "Not requeuing already queued non-RT signal %d"
+                        " for LWP %ld\n",
+                        sig->signal,
+                        lwpid_of (lwp));
+             return;
+           }
        }
+    }
 
-      /* If GDB is not interested in this signal, don't stop other
-        threads, and don't report it to GDB.  Just resume the
-        inferior right away.  We do this for threading-related
-        signals as well as any that GDB specifically requested we
-        ignore.  But never ignore SIGSTOP if we sent it ourselves,
-        and do not ignore signals when stepping - they may require
-        special handling to skip the signal handler.  */
-      /* FIXME drow/2002-06-09: Get signal numbers from the inferior's
-        thread library?  */
-      if (WIFSTOPPED (*wstat)
-         && !event_child->stepping
-         && (
-#ifdef USE_THREAD_DB
-             (thread_db_active
-              && (WSTOPSIG (*wstat) == __SIGRTMIN
-                  || WSTOPSIG (*wstat) == __SIGRTMIN + 1))
-             ||
-#endif
-             (pass_signals[target_signal_from_host (WSTOPSIG (*wstat))]
-              && (WSTOPSIG (*wstat) != SIGSTOP || !stopping_threads))))
-       {
-         siginfo_t info, *info_p;
+  p_sig = xmalloc (sizeof (*p_sig));
+  p_sig->prev = lwp->pending_signals_to_report;
+  p_sig->signal = WSTOPSIG (*wstat);
+  memset (&p_sig->info, 0, sizeof (siginfo_t));
+  ptrace (PTRACE_GETSIGINFO, lwpid_of (lwp), 0, &p_sig->info);
 
-         if (debug_threads)
-           fprintf (stderr, "Ignored signal %d for LWP %ld.\n",
-                    WSTOPSIG (*wstat), lwpid_of (event_child));
+  lwp->pending_signals_to_report = p_sig;
+}
 
-         if (ptrace (PTRACE_GETSIGINFO, lwpid_of (event_child), 0, &info) == 0)
-           info_p = &info;
-         else
-           info_p = NULL;
-         linux_resume_one_lwp (&event_child->head,
-                               event_child->stepping,
-                               WSTOPSIG (*wstat), info_p);
-         continue;
-       }
+/* Dequeue one signal from the "signals to report later when out of
+   the jump pad" list.  */
+
+static int
+dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
+{
+  if (lwp->pending_signals_to_report != NULL)
+    {
+      struct pending_signals **p_sig;
 
-      /* If this event was not handled above, and is not a SIGTRAP, report
-        it.  */
-      if (!WIFSTOPPED (*wstat) || WSTOPSIG (*wstat) != SIGTRAP)
-       return lwpid_of (event_child);
+      p_sig = &lwp->pending_signals_to_report;
+      while ((*p_sig)->prev != NULL)
+       p_sig = &(*p_sig)->prev;
 
-      /* If this target does not support breakpoints, we simply report the
-        SIGTRAP; it's of no concern to us.  */
-      if (the_low_target.get_pc == NULL)
-       return lwpid_of (event_child);
+      *wstat = W_STOPCODE ((*p_sig)->signal);
+      if ((*p_sig)->info.si_signo != 0)
+       ptrace (PTRACE_SETSIGINFO, lwpid_of (lwp), 0, &(*p_sig)->info);
+      free (*p_sig);
+      *p_sig = NULL;
 
-      stop_pc = get_stop_pc ();
+      if (debug_threads)
+       fprintf (stderr, "Reporting deferred signal %d for LWP %ld.\n",
+                WSTOPSIG (*wstat), lwpid_of (lwp));
 
-      /* bp_reinsert will only be set if we were single-stepping.
-        Notice that we will resume the process after hitting
-        a gdbserver breakpoint; single-stepping to/over one
-        is not supported (yet).  */
-      if (event_child->bp_reinsert != 0)
+      if (debug_threads)
        {
-         if (debug_threads)
-           fprintf (stderr, "Reinserted breakpoint.\n");
-         reinsert_breakpoint (event_child->bp_reinsert);
-         event_child->bp_reinsert = 0;
+         struct pending_signals *sig;
 
-         /* Clear the single-stepping flag and SIGTRAP as we resume.  */
-         linux_resume_one_lwp (&event_child->head, 0, 0, NULL);
-         continue;
+         for (sig = lwp->pending_signals_to_report;
+              sig != NULL;
+              sig = sig->prev)
+           fprintf (stderr,
+                    "   Still queued %d\n",
+                    sig->signal);
+
+         fprintf (stderr, "   (no more queued signals)\n");
        }
 
-      bp_status = check_breakpoints (stop_pc);
+      return 1;
+    }
 
-      if (bp_status != 0)
-       {
-         if (debug_threads)
-           fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+  return 0;
+}
 
-         /* We hit one of our own breakpoints.  We mark it as a pending
-            breakpoint, so that check_removed_breakpoint () will do the PC
-            adjustment for us at the appropriate time.  */
-         event_child->pending_is_breakpoint = 1;
-         event_child->pending_stop_pc = stop_pc;
-
-         /* We may need to put the breakpoint back.  We continue in the event
-            loop instead of simply replacing the breakpoint right away,
-            in order to not lose signals sent to the thread that hit the
-            breakpoint.  Unfortunately this increases the window where another
-            thread could sneak past the removed breakpoint.  For the current
-            use of server-side breakpoints (thread creation) this is
-            acceptable; but it needs to be considered before this breakpoint
-            mechanism can be used in more general ways.  For some breakpoints
-            it may be necessary to stop all other threads, but that should
-            be avoided where possible.
-
-            If breakpoint_reinsert_addr is NULL, that means that we can
-            use PTRACE_SINGLESTEP on this platform.  Uninsert the breakpoint,
-            mark it for reinsertion, and single-step.
-
-            Otherwise, call the target function to figure out where we need
-            our temporary breakpoint, create it, and continue executing this
-            process.  */
+/* Arrange for a breakpoint to be hit again later.  We don't keep the
+   SIGTRAP status and don't forward the SIGTRAP signal to the LWP.  We
+   will handle the current event, eventually we will resume this LWP,
+   and this breakpoint will trap again.  */
 
-         /* NOTE: we're lifting breakpoints in non-stop mode.  This
-            is currently only used for thread event breakpoints, so
-            it isn't that bad as long as we have PTRACE_EVENT_CLONE
-            events.  */
-         if (bp_status == 2)
-           /* No need to reinsert.  */
-           linux_resume_one_lwp (&event_child->head, 0, 0, NULL);
-         else if (the_low_target.breakpoint_reinsert_addr == NULL)
-           {
-             event_child->bp_reinsert = stop_pc;
-             uninsert_breakpoint (stop_pc);
-             linux_resume_one_lwp (&event_child->head, 1, 0, NULL);
-           }
-         else
-           {
-             reinsert_breakpoint_by_bp
-               (stop_pc, (*the_low_target.breakpoint_reinsert_addr) ());
-             linux_resume_one_lwp (&event_child->head, 0, 0, NULL);
-           }
+static int
+cancel_breakpoint (struct lwp_info *lwp)
+{
+  struct thread_info *saved_inferior;
 
-         continue;
-       }
+  /* There's nothing to do if we don't support breakpoints.  */
+  if (!supports_breakpoints ())
+    return 0;
 
-      if (debug_threads)
-       fprintf (stderr, "Hit a non-gdbserver breakpoint.\n");
+  /* breakpoint_at reads from current inferior.  */
+  saved_inferior = current_inferior;
+  current_inferior = get_lwp_thread (lwp);
 
-      /* If we were single-stepping, we definitely want to report the
-        SIGTRAP.  Although the single-step operation has completed,
-        do not clear clear the stepping flag yet; we need to check it
-        in wait_for_sigstop.  */
-      if (event_child->stepping)
-       return lwpid_of (event_child);
+  if ((*the_low_target.breakpoint_at) (lwp->stop_pc))
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "CB: Push back breakpoint for %s\n",
+                target_pid_to_str (ptid_of (lwp)));
 
-      /* A SIGTRAP that we can't explain.  It may have been a breakpoint.
-        Check if it is a breakpoint, and if so mark the process information
-        accordingly.  This will handle both the necessary fiddling with the
-        PC on decr_pc_after_break targets and suppressing extra threads
-        hitting a breakpoint if two hit it at once and then GDB removes it
-        after the first is reported.  Arguably it would be better to report
-        multiple threads hitting breakpoints simultaneously, but the current
-        remote protocol does not allow this.  */
-      if ((*the_low_target.breakpoint_at) (stop_pc))
+      /* Back up the PC if necessary.  */
+      if (the_low_target.decr_pc_after_break)
        {
-         event_child->pending_is_breakpoint = 1;
-         event_child->pending_stop_pc = stop_pc;
+         struct regcache *regcache
+           = get_thread_regcache (current_inferior, 1);
+         (*the_low_target.set_pc) (regcache, lwp->stop_pc);
        }
 
-      return lwpid_of (event_child);
+      current_inferior = saved_inferior;
+      return 1;
+    }
+  else
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "CB: No breakpoint found at %s for [%s]\n",
+                paddress (lwp->stop_pc),
+                target_pid_to_str (ptid_of (lwp)));
     }
 
-  /* NOTREACHED */
+  current_inferior = saved_inferior;
   return 0;
 }
 
-/* Wait for process, returns status.  */
+/* When the event-loop is doing a step-over, this points at the thread
+   being stepped.  */
+ptid_t step_over_bkpt;
+
+/* Wait for an event from child PID.  If PID is -1, wait for any
+   child.  Store the stop status through the status pointer WSTAT.
+   OPTIONS is passed to the waitpid call.  Return 0 if no child stop
+   event was found and OPTIONS contains WNOHANG.  Return the PID of
+   the stopped child otherwise.  */
 
-static unsigned long
-linux_wait_1 (struct target_waitstatus *ourstatus, int target_options)
+static int
+linux_wait_for_event (ptid_t ptid, int *wstat, int options)
 {
-  int w;
-  struct thread_info *thread = NULL;
-  struct lwp_info *lwp = NULL;
-  int options;
-  int wait_pid = -1;
-  int pid;
+  struct lwp_info *event_child, *requested_child;
+  ptid_t wait_ptid;
 
-  /* Translate generic target options into linux options.  */
-  options = __WALL;
-  if (target_options & TARGET_WNOHANG)
-    options |= WNOHANG;
+  event_child = NULL;
+  requested_child = NULL;
 
-retry:
-  ourstatus->kind = TARGET_WAITKIND_IGNORE;
+  /* Check for a lwp with a pending status.  */
 
-  /* If we were only supposed to resume one thread, only wait for
-     that thread - if it's still alive.  If it died, however - which
-     can happen if we're coming from the thread death case below -
-     then we need to make sure we restart the other threads.  We could
-     pick a thread at random or restart all; restarting all is less
-     arbitrary.  */
-  if (!non_stop && cont_thread != 0 && cont_thread != -1)
+  if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
     {
-      thread = (struct thread_info *) find_inferior_id (&all_threads,
-                                                       cont_thread);
+      event_child = (struct lwp_info *)
+       find_inferior (&all_lwps, status_pending_p_callback, &ptid);
+      if (debug_threads && event_child)
+       fprintf (stderr, "Got a pending child %ld\n", lwpid_of (event_child));
+    }
+  else
+    {
+      requested_child = find_lwp_pid (ptid);
 
-      /* No stepping, no signal - unless one is pending already, of course.  */
-      if (thread == NULL)
+      if (!stopping_threads
+         && requested_child->status_pending_p
+         && requested_child->collecting_fast_tracepoint)
        {
-         struct thread_resume resume_info;
-         resume_info.thread = -1;
-         resume_info.kind = resume_continue;
-         resume_info.sig = 0;
-         linux_resume (&resume_info, 1);
+         enqueue_one_deferred_signal (requested_child,
+                                      &requested_child->status_pending);
+         requested_child->status_pending_p = 0;
+         requested_child->status_pending = 0;
+         linux_resume_one_lwp (requested_child, 0, 0, NULL);
        }
-      else
-       wait_pid = cont_thread;
-    }
 
-  pid = linux_wait_for_event (wait_pid, &w, options);
-  if (pid == 0) /* only if TARGET_WNOHANG */
-    return pid;
+      if (requested_child->suspended
+         && requested_child->status_pending_p)
+       fatal ("requesting an event out of a suspended child?");
 
-  lwp = get_thread_lwp (current_inferior);
+      if (requested_child->status_pending_p)
+       event_child = requested_child;
+    }
 
-  if (must_set_ptrace_flags)
+  if (event_child != NULL)
     {
-      ptrace (PTRACE_SETOPTIONS, lwpid_of (lwp), 0, PTRACE_O_TRACECLONE);
-      must_set_ptrace_flags = 0;
+      if (debug_threads)
+       fprintf (stderr, "Got an event from pending child %ld (%04x)\n",
+                lwpid_of (event_child), event_child->status_pending);
+      *wstat = event_child->status_pending;
+      event_child->status_pending_p = 0;
+      event_child->status_pending = 0;
+      current_inferior = get_lwp_thread (event_child);
+      return lwpid_of (event_child);
     }
-  /* If we are waiting for a particular child, and it exited,
-     linux_wait_for_event will return its exit status.  Similarly if
-     the last child exited.  If this is not the last child, however,
-     do not report it as exited until there is a 'thread exited' response
-     available in the remote protocol.  Instead, just wait for another event.
-     This should be safe, because if the thread crashed we will already
-     have reported the termination signal to GDB; that should stop any
-     in-progress stepping operations, etc.
 
-     Report the exit status of the last thread to exit.  This matches
-     LinuxThreads' behavior.  */
+  if (ptid_is_pid (ptid))
+    {
+      /* A request to wait for a specific tgid.  This is not possible
+        with waitpid, so instead, we wait for any child, and leave
+        children we're not interested in right now with a pending
+        status to report later.  */
+      wait_ptid = minus_one_ptid;
+    }
+  else
+    wait_ptid = ptid;
 
-  if (all_threads.head == all_threads.tail)
+  /* We only enter this loop if no process has a pending wait status.  Thus
+     any action taken in response to a wait status inside this loop is
+     responding as soon as we detect the status, not after any pending
+     events.  */
+  while (1)
     {
-      if (WIFEXITED (w) || WIFSIGNALED (w))
+      event_child = linux_wait_for_lwp (wait_ptid, wstat, options);
+
+      if ((options & WNOHANG) && event_child == NULL)
        {
-         int pid;
+         if (debug_threads)
+           fprintf (stderr, "WNOHANG set, no event found\n");
+         return 0;
+       }
+
+      if (event_child == NULL)
+       error ("event from unknown child");
 
-         pid = pid_of (lwp);
+      if (ptid_is_pid (ptid)
+         && ptid_get_pid (ptid) != ptid_get_pid (ptid_of (event_child)))
+       {
+         if (! WIFSTOPPED (*wstat))
+           mark_lwp_dead (event_child, *wstat);
+         else
+           {
+             event_child->status_pending_p = 1;
+             event_child->status_pending = *wstat;
+           }
+         continue;
+       }
 
-         delete_lwp (lwp);
-         clear_inferiors ();
+      current_inferior = get_lwp_thread (event_child);
 
-         current_inferior = NULL;
+      /* Check for thread exit.  */
+      if (! WIFSTOPPED (*wstat))
+       {
+         if (debug_threads)
+           fprintf (stderr, "LWP %ld exiting\n", lwpid_of (event_child));
 
-         if (WIFEXITED (w))
+         /* If the last thread is exiting, just return.  */
+         if (last_thread_of_process_p (current_inferior))
            {
-             ourstatus->kind = TARGET_WAITKIND_EXITED;
-             ourstatus->value.integer = WEXITSTATUS (w);
+             if (debug_threads)
+               fprintf (stderr, "LWP %ld is last lwp of process\n",
+                        lwpid_of (event_child));
+             return lwpid_of (event_child);
+           }
 
+         if (!non_stop)
+           {
+             current_inferior = (struct thread_info *) all_threads.head;
              if (debug_threads)
-               fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
+               fprintf (stderr, "Current inferior is now %ld\n",
+                        lwpid_of (get_thread_lwp (current_inferior)));
            }
          else
            {
-             ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-             ourstatus->value.sig = target_signal_from_host (WTERMSIG (w));
-
+             current_inferior = NULL;
              if (debug_threads)
-               fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+               fprintf (stderr, "Current inferior is now <NULL>\n");
+           }
 
+         /* If we were waiting for this particular child to do something...
+            well, it did something.  */
+         if (requested_child != NULL)
+           {
+             int lwpid = lwpid_of (event_child);
+
+             /* Cancel the step-over operation --- the thread that
+                started it is gone.  */
+             if (finish_step_over (event_child))
+               unstop_all_lwps (1, event_child);
+             delete_lwp (event_child);
+             return lwpid;
            }
 
-         return pid;
-       }
-    }
-  else
-    {
-      if (!WIFSTOPPED (w))
-       goto retry;
-    }
+         delete_lwp (event_child);
 
-  /* In all-stop, stop all threads.  Be careful to only do this if
-     we're about to report an event to GDB.  */
-  if (!non_stop)
-    stop_all_lwps ();
+         /* Wait for a more interesting event.  */
+         continue;
+       }
 
-  ourstatus->kind = TARGET_WAITKIND_STOPPED;
+      if (event_child->must_set_ptrace_flags)
+       {
+         linux_enable_event_reporting (lwpid_of (event_child));
+         event_child->must_set_ptrace_flags = 0;
+       }
 
-  if (lwp->suspended && WSTOPSIG (w) == SIGSTOP)
-    {
-      /* A thread that has been requested to stop by GDB with vCont;t,
-        and it stopped cleanly, so report as SIG0.  The use of
-        SIGSTOP is an implementation detail.  */
-      ourstatus->value.sig = TARGET_SIGNAL_0;
-    }
-  else if (lwp->suspended && WSTOPSIG (w) != SIGSTOP)
-    {
-      /* A thread that has been requested to stop by GDB with vCont;t,
-        but, it stopped for other reasons.  Set stop_expected so the
-        pending SIGSTOP is ignored and the LWP is resumed.  */
-      lwp->stop_expected = 1;
-      ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
-    }
-  else
-    {
-      ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
-    }
+      if (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) == SIGTRAP
+         && *wstat >> 16 != 0)
+       {
+         handle_extended_wait (event_child, *wstat);
+         continue;
+       }
 
-  if (debug_threads)
-    fprintf (stderr, "linux_wait ret = %ld, %d, %d\n",
-            lwpid_of (lwp),
-            ourstatus->kind,
-            ourstatus->value.sig);
+      if (WIFSTOPPED (*wstat)
+         && WSTOPSIG (*wstat) == SIGSTOP
+         && event_child->stop_expected)
+       {
+         int should_stop;
 
-  return lwpid_of (lwp);
-}
+         if (debug_threads)
+           fprintf (stderr, "Expected stop.\n");
+         event_child->stop_expected = 0;
 
-/* Get rid of any pending event in the pipe.  */
-static void
-async_file_flush (void)
-{
-  int ret;
-  char buf;
+         should_stop = (current_inferior->last_resume_kind == resume_stop
+                        || stopping_threads);
 
-  do
-    ret = read (linux_event_pipe[0], &buf, 1);
-  while (ret >= 0 || (ret == -1 && errno == EINTR));
-}
+         if (!should_stop)
+           {
+             linux_resume_one_lwp (event_child,
+                                   event_child->stepping, 0, NULL);
+             continue;
+           }
+       }
 
-/* Put something in the pipe, so the event loop wakes up.  */
-static void
-async_file_mark (void)
-{
-  int ret;
+      return lwpid_of (event_child);
+    }
 
-  async_file_flush ();
+  /* NOTREACHED */
+  return 0;
+}
 
-  do
-    ret = write (linux_event_pipe[1], "+", 1);
-  while (ret == 0 || (ret == -1 && errno == EINTR));
+/* Count the LWP's that have had events.  */
 
-  /* Ignore EAGAIN.  If the pipe is full, the event loop will already
-     be awakened anyway.  */
+static int
+count_events_callback (struct inferior_list_entry *entry, void *data)
+{
+  struct lwp_info *lp = (struct lwp_info *) entry;
+  struct thread_info *thread = get_lwp_thread (lp);
+  int *count = data;
+
+  gdb_assert (count != NULL);
+
+  /* Count only resumed LWPs that have a SIGTRAP event pending that
+     should be reported to GDB.  */
+  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+      && thread->last_resume_kind != resume_stop
+      && lp->status_pending_p
+      && WIFSTOPPED (lp->status_pending)
+      && WSTOPSIG (lp->status_pending) == SIGTRAP
+      && !breakpoint_inserted_here (lp->stop_pc))
+    (*count)++;
+
+  return 0;
 }
 
-static unsigned long
-linux_wait (struct target_waitstatus *ourstatus, int target_options)
-{
-  unsigned long event_ptid;
+/* Select the LWP (if any) that is currently being single-stepped.  */
 
-  if (debug_threads)
-    fprintf (stderr, "linux_wait\n");
+static int
+select_singlestep_lwp_callback (struct inferior_list_entry *entry, void *data)
+{
+  struct lwp_info *lp = (struct lwp_info *) entry;
+  struct thread_info *thread = get_lwp_thread (lp);
 
-  /* Flush the async file first.  */
-  if (target_is_async_p ())
-    async_file_flush ();
+  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+      && thread->last_resume_kind == resume_step
+      && lp->status_pending_p)
+    return 1;
+  else
+    return 0;
+}
 
-  event_ptid = linux_wait_1 (ourstatus, target_options);
+/* Select the Nth LWP that has had a SIGTRAP event that should be
+   reported to GDB.  */
 
-  /* If at least one stop was reported, there may be more.  A single
-     SIGCHLD can signal more than one child stop.  */
-  if (target_is_async_p ()
-      && (target_options & TARGET_WNOHANG) != 0
-      && event_ptid != 0)
-    async_file_mark ();
+static int
+select_event_lwp_callback (struct inferior_list_entry *entry, void *data)
+{
+  struct lwp_info *lp = (struct lwp_info *) entry;
+  struct thread_info *thread = get_lwp_thread (lp);
+  int *selector = data;
+
+  gdb_assert (selector != NULL);
+
+  /* Select only resumed LWPs that have a SIGTRAP event pending. */
+  if (thread->last_resume_kind != resume_stop
+      && thread->last_status.kind == TARGET_WAITKIND_IGNORE
+      && lp->status_pending_p
+      && WIFSTOPPED (lp->status_pending)
+      && WSTOPSIG (lp->status_pending) == SIGTRAP
+      && !breakpoint_inserted_here (lp->stop_pc))
+    if ((*selector)-- == 0)
+      return 1;
 
-  return event_ptid;
+  return 0;
 }
 
-/* Send a signal to an LWP.  For LinuxThreads, kill is enough; however, if
-   thread groups are in use, we need to use tkill.  */
-
 static int
-kill_lwp (unsigned long lwpid, int signo)
+cancel_breakpoints_callback (struct inferior_list_entry *entry, void *data)
 {
-  static int tkill_failed;
+  struct lwp_info *lp = (struct lwp_info *) entry;
+  struct thread_info *thread = get_lwp_thread (lp);
+  struct lwp_info *event_lp = data;
 
-  errno = 0;
+  /* Leave the LWP that has been elected to receive a SIGTRAP alone.  */
+  if (lp == event_lp)
+    return 0;
 
-#ifdef SYS_tkill
-  if (!tkill_failed)
-    {
-      int ret = syscall (SYS_tkill, lwpid, signo);
-      if (errno != ENOSYS)
-       return ret;
-      errno = 0;
-      tkill_failed = 1;
-    }
-#endif
+  /* If a LWP other than the LWP that we're reporting an event for has
+     hit a GDB breakpoint (as opposed to some random trap signal),
+     then just arrange for it to hit it again later.  We don't keep
+     the SIGTRAP status and don't forward the SIGTRAP signal to the
+     LWP.  We will handle the current event, eventually we will resume
+     all LWPs, and this one will get its breakpoint trap again.
+
+     If we do not do this, then we run the risk that the user will
+     delete or disable the breakpoint, but the LWP will have already
+     tripped on it.  */
+
+  if (thread->last_resume_kind != resume_stop
+      && thread->last_status.kind == TARGET_WAITKIND_IGNORE
+      && lp->status_pending_p
+      && WIFSTOPPED (lp->status_pending)
+      && WSTOPSIG (lp->status_pending) == SIGTRAP
+      && !lp->stepping
+      && !lp->stopped_by_watchpoint
+      && cancel_breakpoint (lp))
+    /* Throw away the SIGTRAP.  */
+    lp->status_pending_p = 0;
 
-  return kill (lwpid, signo);
+  return 0;
 }
 
 static void
-send_sigstop (struct inferior_list_entry *entry)
+linux_cancel_breakpoints (void)
 {
-  struct lwp_info *lwp = (struct lwp_info *) entry;
-  int pid;
-
-  if (lwp->stopped)
-    return;
+  find_inferior (&all_lwps, cancel_breakpoints_callback, NULL);
+}
 
-  pid = lwpid_of (lwp);
+/* Select one LWP out of those that have events pending.  */
 
-  /* If we already have a pending stop signal for this process, don't
-     send another.  */
-  if (lwp->stop_expected)
+static void
+select_event_lwp (struct lwp_info **orig_lp)
+{
+  int num_events = 0;
+  int random_selector;
+  struct lwp_info *event_lp;
+
+  /* Give preference to any LWP that is being single-stepped.  */
+  event_lp
+    = (struct lwp_info *) find_inferior (&all_lwps,
+                                        select_singlestep_lwp_callback, NULL);
+  if (event_lp != NULL)
     {
       if (debug_threads)
-       fprintf (stderr, "Have pending sigstop for lwp %d\n", pid);
-
-      /* We clear the stop_expected flag so that wait_for_sigstop
-        will receive the SIGSTOP event (instead of silently resuming and
-        waiting again).  It'll be reset below.  */
-      lwp->stop_expected = 0;
-      return;
+       fprintf (stderr,
+                "SEL: Select single-step %s\n",
+                target_pid_to_str (ptid_of (event_lp)));
     }
+  else
+    {
+      /* No single-stepping LWP.  Select one at random, out of those
+         which have had SIGTRAP events.  */
 
-  if (debug_threads)
-    fprintf (stderr, "Sending sigstop to lwp %d\n", pid);
+      /* First see how many SIGTRAP events we have.  */
+      find_inferior (&all_lwps, count_events_callback, &num_events);
 
-  kill_lwp (pid, SIGSTOP);
-}
+      /* Now randomly pick a LWP out of those that have had a SIGTRAP.  */
+      random_selector = (int)
+       ((num_events * (double) rand ()) / (RAND_MAX + 1.0));
 
-static void
-wait_for_sigstop (struct inferior_list_entry *entry)
-{
-  struct lwp_info *lwp = (struct lwp_info *) entry;
-  struct thread_info *saved_inferior;
-  int wstat;
-  unsigned long saved_tid;
-  unsigned long ptid;
+      if (debug_threads && num_events > 1)
+       fprintf (stderr,
+                "SEL: Found %d SIGTRAP events, selecting #%d\n",
+                num_events, random_selector);
 
-  if (lwp->stopped)
-    return;
+      event_lp = (struct lwp_info *) find_inferior (&all_lwps,
+                                                   select_event_lwp_callback,
+                                                   &random_selector);
+    }
 
-  saved_inferior = current_inferior;
-  if (saved_inferior != NULL)
-    saved_tid = ((struct inferior_list_entry *) saved_inferior)->id;
-  else
-    saved_tid = 0; /* avoid bogus unused warning */
+  if (event_lp != NULL)
+    {
+      /* Switch the event LWP.  */
+      *orig_lp = event_lp;
+    }
+}
 
-  ptid = lwpid_of (lwp);
+/* Decrement the suspend count of an LWP.  */
 
-  linux_wait_for_event (ptid, &wstat, __WALL);
+static int
+unsuspend_one_lwp (struct inferior_list_entry *entry, void *except)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
 
-  /* If we stopped with a non-SIGSTOP signal, save it for later
-     and record the pending SIGSTOP.  If the process exited, just
-     return.  */
-  if (WIFSTOPPED (wstat)
-      && WSTOPSIG (wstat) != SIGSTOP)
-    {
-      if (debug_threads)
-       fprintf (stderr, "LWP %ld stopped with non-sigstop status %06x\n",
-                lwpid_of (lwp), wstat);
-
-      /* Do not leave a pending single-step finish to be reported to
-        the client.  The client will give us a new action for this
-        thread, possibly a continue request --- otherwise, the client
-        would consider this pending SIGTRAP reported later a spurious
-        signal.  */
-      if (WSTOPSIG (wstat) == SIGTRAP
-         && lwp->stepping
-         && !linux_stopped_by_watchpoint ())
-       {
-         if (debug_threads)
-           fprintf (stderr, "  single-step SIGTRAP ignored\n");
-       }
-      else
-       {
-         lwp->status_pending_p = 1;
-         lwp->status_pending = wstat;
-       }
-      lwp->stop_expected = 1;
-    }
+  /* Ignore EXCEPT.  */
+  if (lwp == except)
+    return 0;
 
-  if (saved_inferior == NULL || linux_thread_alive (saved_tid))
-    current_inferior = saved_inferior;
-  else
-    {
-      if (debug_threads)
-       fprintf (stderr, "Previously current thread died.\n");
+  lwp->suspended--;
 
-      if (non_stop)
-       {
-         /* We can't change the current inferior behind GDB's back,
-            otherwise, a subsequent command may apply to the wrong
-            process.  */
-         current_inferior = NULL;
-       }
-      else
-       {
-         /* Set a valid thread as current.  */
-         set_desired_inferior (0);
-       }
-    }
+  gdb_assert (lwp->suspended >= 0);
+  return 0;
 }
 
+/* Decrement the suspend count of all LWPs, except EXCEPT, if non
+   NULL.  */
+
 static void
-stop_all_lwps (void)
+unsuspend_all_lwps (struct lwp_info *except)
 {
-  stopping_threads = 1;
-  for_each_inferior (&all_lwps, send_sigstop);
-  for_each_inferior (&all_lwps, wait_for_sigstop);
-  stopping_threads = 0;
+  find_inferior (&all_lwps, unsuspend_one_lwp, except);
 }
 
-/* Resume execution of the inferior process.
-   If STEP is nonzero, single-step it.
-   If SIGNAL is nonzero, give it that signal.  */
+static void move_out_of_jump_pad_callback (struct inferior_list_entry *entry);
+static int stuck_in_jump_pad_callback (struct inferior_list_entry *entry,
+                                      void *data);
+static int lwp_running (struct inferior_list_entry *entry, void *data);
+static ptid_t linux_wait_1 (ptid_t ptid,
+                           struct target_waitstatus *ourstatus,
+                           int target_options);
+
+/* Stabilize threads (move out of jump pads).
+
+   If a thread is midway collecting a fast tracepoint, we need to
+   finish the collection and move it out of the jump pad before
+   reporting the signal.
+
+   This avoids recursion while collecting (when a signal arrives
+   midway, and the signal handler itself collects), which would trash
+   the trace buffer.  In case the user set a breakpoint in a signal
+   handler, this avoids the backtrace showing the jump pad, etc..
+   Most importantly, there are certain things we can't do safely if
+   threads are stopped in a jump pad (or in its callee's).  For
+   example:
+
+     - starting a new trace run.  A thread still collecting the
+   previous run, could trash the trace buffer when resumed.  The trace
+   buffer control structures would have been reset but the thread had
+   no way to tell.  The thread could even midway memcpy'ing to the
+   buffer, which would mean that when resumed, it would clobber the
+   trace buffer that had been set for a new run.
+
+     - we can't rewrite/reuse the jump pads for new tracepoints
+   safely.  Say you do tstart while a thread is stopped midway while
+   collecting.  When the thread is later resumed, it finishes the
+   collection, and returns to the jump pad, to execute the original
+   instruction that was under the tracepoint jump at the time the
+   older run had been started.  If the jump pad had been rewritten
+   since for something else in the new run, the thread would now
+   execute the wrong / random instructions.  */
 
 static void
-linux_resume_one_lwp (struct inferior_list_entry *entry,
-                     int step, int signal, siginfo_t *info)
+linux_stabilize_threads (void)
 {
-  struct lwp_info *lwp = (struct lwp_info *) entry;
-  struct thread_info *saved_inferior;
+  struct thread_info *save_inferior;
+  struct lwp_info *lwp_stuck;
 
-  if (lwp->stopped == 0)
-    return;
-
-  /* If we have pending signals or status, and a new signal, enqueue the
-     signal.  Also enqueue the signal if we are waiting to reinsert a
-     breakpoint; it will be picked up again below.  */
-  if (signal != 0
-      && (lwp->status_pending_p || lwp->pending_signals != NULL
-         || lwp->bp_reinsert != 0))
+  lwp_stuck
+    = (struct lwp_info *) find_inferior (&all_lwps,
+                                        stuck_in_jump_pad_callback, NULL);
+  if (lwp_stuck != NULL)
     {
-      struct pending_signals *p_sig;
-      p_sig = xmalloc (sizeof (*p_sig));
-      p_sig->prev = lwp->pending_signals;
-      p_sig->signal = signal;
-      if (info == NULL)
-       memset (&p_sig->info, 0, sizeof (siginfo_t));
-      else
-       memcpy (&p_sig->info, info, sizeof (siginfo_t));
-      lwp->pending_signals = p_sig;
+      if (debug_threads)
+       fprintf (stderr, "can't stabilize, LWP %ld is stuck in jump pad\n",
+                lwpid_of (lwp_stuck));
+      return;
     }
 
-  if (lwp->status_pending_p && !check_removed_breakpoint (lwp))
-    return;
-
-  saved_inferior = current_inferior;
-  current_inferior = get_lwp_thread (lwp);
+  save_inferior = current_inferior;
 
-  if (debug_threads)
-    fprintf (stderr, "Resuming lwp %ld (%s, signal %d, stop %s)\n",
-            lwpid_of (lwp), step ? "step" : "continue", signal,
-            lwp->stop_expected ? "expected" : "not expected");
+  stabilizing_threads = 1;
 
-  /* This bit needs some thinking about.  If we get a signal that
-     we must report while a single-step reinsert is still pending,
-     we often end up resuming the thread.  It might be better to
-     (ew) allow a stack of pending events; then we could be sure that
-     the reinsert happened right away and not lose any signals.
+  /* Kick 'em all.  */
+  for_each_inferior (&all_lwps, move_out_of_jump_pad_callback);
 
-     Making this stack would also shrink the window in which breakpoints are
-     uninserted (see comment in linux_wait_for_lwp) but not enough for
-     complete correctness, so it won't solve that problem.  It may be
-     worthwhile just to solve this one, however.  */
-  if (lwp->bp_reinsert != 0)
+  /* Loop until all are stopped out of the jump pads.  */
+  while (find_inferior (&all_lwps, lwp_running, NULL) != NULL)
     {
-      if (debug_threads)
-       fprintf (stderr, "  pending reinsert at %08lx", (long)lwp->bp_reinsert);
-      if (step == 0)
-       fprintf (stderr, "BAD - reinserting but not stepping.\n");
-      step = 1;
+      struct target_waitstatus ourstatus;
+      struct lwp_info *lwp;
+      int wstat;
 
-      /* Postpone any pending signal.  It was enqueued above.  */
-      signal = 0;
-    }
+      /* Note that we go through the full wait even loop.  While
+        moving threads out of jump pad, we need to be able to step
+        over internal breakpoints and such.  */
+      linux_wait_1 (minus_one_ptid, &ourstatus, 0);
+
+      if (ourstatus.kind == TARGET_WAITKIND_STOPPED)
+       {
+         lwp = get_thread_lwp (current_inferior);
 
-  check_removed_breakpoint (lwp);
+         /* Lock it.  */
+         lwp->suspended++;
 
-  if (debug_threads && the_low_target.get_pc != NULL)
-    {
-      fprintf (stderr, "  ");
-      (*the_low_target.get_pc) ();
+         if (ourstatus.value.sig != TARGET_SIGNAL_0
+             || current_inferior->last_resume_kind == resume_stop)
+           {
+             wstat = W_STOPCODE (target_signal_to_host (ourstatus.value.sig));
+             enqueue_one_deferred_signal (lwp, &wstat);
+           }
+       }
     }
 
-  /* If we have pending signals, consume one unless we are trying to reinsert
-     a breakpoint.  */
-  if (lwp->pending_signals != NULL && lwp->bp_reinsert == 0)
-    {
-      struct pending_signals **p_sig;
+  find_inferior (&all_lwps, unsuspend_one_lwp, NULL);
 
-      p_sig = &lwp->pending_signals;
-      while ((*p_sig)->prev != NULL)
-       p_sig = &(*p_sig)->prev;
+  stabilizing_threads = 0;
 
-      signal = (*p_sig)->signal;
-      if ((*p_sig)->info.si_signo != 0)
-       ptrace (PTRACE_SETSIGINFO, lwpid_of (lwp), 0, &(*p_sig)->info);
+  current_inferior = save_inferior;
 
-      free (*p_sig);
-      *p_sig = NULL;
-    }
-
-  regcache_invalidate_one ((struct inferior_list_entry *)
-                          get_lwp_thread (lwp));
-  errno = 0;
-  lwp->stopped = 0;
-  lwp->stepping = step;
-  ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, lwpid_of (lwp), 0, signal);
-
-  current_inferior = saved_inferior;
-  if (errno)
+  if (debug_threads)
     {
-      /* ESRCH from ptrace either means that the thread was already
-        running (an error) or that it is gone (a race condition).  If
-        it's gone, we will get a notification the next time we wait,
-        so we can ignore the error.  We could differentiate these
-        two, but it's tricky without waiting; the thread still exists
-        as a zombie, so sending it signal 0 would succeed.  So just
-        ignore ESRCH.  */
-      if (errno == ESRCH)
-       return;
-
-      perror_with_name ("ptrace");
+      lwp_stuck
+       = (struct lwp_info *) find_inferior (&all_lwps,
+                                        stuck_in_jump_pad_callback, NULL);
+      if (lwp_stuck != NULL)
+       fprintf (stderr, "couldn't stabilize, LWP %ld got stuck in jump pad\n",
+                lwpid_of (lwp_stuck));
     }
 }
 
-struct thread_resume_array
+/* Wait for process, returns status.  */
+
+static ptid_t
+linux_wait_1 (ptid_t ptid,
+             struct target_waitstatus *ourstatus, int target_options)
 {
-  struct thread_resume *resume;
-  size_t n;
-};
+  int w;
+  struct lwp_info *event_child;
+  int options;
+  int pid;
+  int step_over_finished;
+  int bp_explains_trap;
+  int maybe_internal_trap;
+  int report_to_gdb;
+  int trace_event;
 
-/* This function is called once per thread.  We look up the thread
-   in RESUME_PTR, and mark the thread with a pointer to the appropriate
-   resume request.
+  /* Translate generic target options into linux options.  */
+  options = __WALL;
+  if (target_options & TARGET_WNOHANG)
+    options |= WNOHANG;
 
-   This algorithm is O(threads * resume elements), but resume elements
-   is small (and will remain small at least until GDB supports thread
-   suspension).  */
-static int
-linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
-{
-  struct lwp_info *lwp;
-  struct thread_info *thread;
-  int ndx;
-  struct thread_resume_array *r;
+retry:
+  bp_explains_trap = 0;
+  trace_event = 0;
+  ourstatus->kind = TARGET_WAITKIND_IGNORE;
 
-  thread = (struct thread_info *) entry;
-  lwp = get_thread_lwp (thread);
-  r = arg;
+  /* If we were only supposed to resume one thread, only wait for
+     that thread - if it's still alive.  If it died, however - which
+     can happen if we're coming from the thread death case below -
+     then we need to make sure we restart the other threads.  We could
+     pick a thread at random or restart all; restarting all is less
+     arbitrary.  */
+  if (!non_stop
+      && !ptid_equal (cont_thread, null_ptid)
+      && !ptid_equal (cont_thread, minus_one_ptid))
+    {
+      struct thread_info *thread;
 
-  for (ndx = 0; ndx < r->n; ndx++)
-    if (r->resume[ndx].thread == -1 || r->resume[ndx].thread == entry->id)
-      {
-       lwp->resume = &r->resume[ndx];
-       return 0;
-      }
+      thread = (struct thread_info *) find_inferior_id (&all_threads,
+                                                       cont_thread);
 
-  /* No resume action for this thread.  */
-  lwp->resume = NULL;
+      /* No stepping, no signal - unless one is pending already, of course.  */
+      if (thread == NULL)
+       {
+         struct thread_resume resume_info;
+         resume_info.thread = minus_one_ptid;
+         resume_info.kind = resume_continue;
+         resume_info.sig = 0;
+         linux_resume (&resume_info, 1);
+       }
+      else
+       ptid = cont_thread;
+    }
 
-  return 0;
-}
+  if (ptid_equal (step_over_bkpt, null_ptid))
+    pid = linux_wait_for_event (ptid, &w, options);
+  else
+    {
+      if (debug_threads)
+       fprintf (stderr, "step_over_bkpt set [%s], doing a blocking wait\n",
+                target_pid_to_str (step_over_bkpt));
+      pid = linux_wait_for_event (step_over_bkpt, &w, options & ~WNOHANG);
+    }
 
+  if (pid == 0) /* only if TARGET_WNOHANG */
+    return null_ptid;
 
-/* Set *FLAG_P if this lwp has an interesting status pending.  */
-static int
-resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
-{
-  struct lwp_info *lwp = (struct lwp_info *) entry;
+  event_child = get_thread_lwp (current_inferior);
 
-  /* LWPs which will not be resumed are not interesting, because
-     we might not wait for them next time through linux_wait.  */
-  if (lwp->resume == NULL)
-    return 0;
+  /* If we are waiting for a particular child, and it exited,
+     linux_wait_for_event will return its exit status.  Similarly if
+     the last child exited.  If this is not the last child, however,
+     do not report it as exited until there is a 'thread exited' response
+     available in the remote protocol.  Instead, just wait for another event.
+     This should be safe, because if the thread crashed we will already
+     have reported the termination signal to GDB; that should stop any
+     in-progress stepping operations, etc.
 
-  /* If this thread has a removed breakpoint, we won't have any
-     events to report later, so check now.  check_removed_breakpoint
-     may clear status_pending_p.  We avoid calling check_removed_breakpoint
-     for any thread that we are not otherwise going to resume - this
-     lets us preserve stopped status when two threads hit a breakpoint.
-     GDB removes the breakpoint to single-step a particular thread
-     past it, then re-inserts it and resumes all threads.  We want
-     to report the second thread without resuming it in the interim.  */
-  if (lwp->status_pending_p)
-    check_removed_breakpoint (lwp);
+     Report the exit status of the last thread to exit.  This matches
+     LinuxThreads' behavior.  */
 
-  if (lwp->status_pending_p)
-    * (int *) flag_p = 1;
+  if (last_thread_of_process_p (current_inferior))
+    {
+      if (WIFEXITED (w) || WIFSIGNALED (w))
+       {
+         if (WIFEXITED (w))
+           {
+             ourstatus->kind = TARGET_WAITKIND_EXITED;
+             ourstatus->value.integer = WEXITSTATUS (w);
 
-  return 0;
-}
+             if (debug_threads)
+               fprintf (stderr,
+                        "\nChild exited with retcode = %x \n",
+                        WEXITSTATUS (w));
+           }
+         else
+           {
+             ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
+             ourstatus->value.sig = target_signal_from_host (WTERMSIG (w));
 
-/* This function is called once per thread.  We check the thread's resume
-   request, which will tell us whether to resume, step, or leave the thread
-   stopped; and what signal, if any, it should be sent.
+             if (debug_threads)
+               fprintf (stderr,
+                        "\nChild terminated with signal = %x \n",
+                        WTERMSIG (w));
 
-   For threads which we aren't explicitly told otherwise, we preserve
-   the stepping flag; this is used for stepping over gdbserver-placed
-   breakpoints.
+           }
 
-   If pending_flags was set in any thread, we queue any needed
-   signals, since we won't actually resume.  We already have a pending
-   event to report, so we don't need to preserve any step requests;
-   they should be re-issued if necessary.  */
+         return ptid_of (event_child);
+       }
+    }
+  else
+    {
+      if (!WIFSTOPPED (w))
+       goto retry;
+    }
 
-static int
-linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
-{
-  struct lwp_info *lwp;
-  struct thread_info *thread;
-  int step;
-  int pending_flag = * (int *) arg;
+  /* If this event was not handled before, and is not a SIGTRAP, we
+     report it.  SIGILL and SIGSEGV are also treated as traps in case
+     a breakpoint is inserted at the current PC.  If this target does
+     not support internal breakpoints at all, we also report the
+     SIGTRAP without further processing; it's of no concern to us.  */
+  maybe_internal_trap
+    = (supports_breakpoints ()
+       && (WSTOPSIG (w) == SIGTRAP
+          || ((WSTOPSIG (w) == SIGILL
+               || WSTOPSIG (w) == SIGSEGV)
+              && (*the_low_target.breakpoint_at) (event_child->stop_pc))));
+
+  if (maybe_internal_trap)
+    {
+      /* Handle anything that requires bookkeeping before deciding to
+        report the event or continue waiting.  */
+
+      /* First check if we can explain the SIGTRAP with an internal
+        breakpoint, or if we should possibly report the event to GDB.
+        Do this before anything that may remove or insert a
+        breakpoint.  */
+      bp_explains_trap = breakpoint_inserted_here (event_child->stop_pc);
+
+      /* We have a SIGTRAP, possibly a step-over dance has just
+        finished.  If so, tweak the state machine accordingly,
+        reinsert breakpoints and delete any reinsert (software
+        single-step) breakpoints.  */
+      step_over_finished = finish_step_over (event_child);
+
+      /* Now invoke the callbacks of any internal breakpoints there.  */
+      check_breakpoints (event_child->stop_pc);
+
+      /* Handle tracepoint data collecting.  This may overflow the
+        trace buffer, and cause a tracing stop, removing
+        breakpoints.  */
+      trace_event = handle_tracepoints (event_child);
+
+      if (bp_explains_trap)
+       {
+         /* If we stepped or ran into an internal breakpoint, we've
+            already handled it.  So next time we resume (from this
+            PC), we should step over it.  */
+         if (debug_threads)
+           fprintf (stderr, "Hit a gdbserver breakpoint.\n");
 
-  thread = (struct thread_info *) entry;
-  lwp = get_thread_lwp (thread);
+         if (breakpoint_here (event_child->stop_pc))
+           event_child->need_step_over = 1;
+       }
+    }
+  else
+    {
+      /* We have some other signal, possibly a step-over dance was in
+        progress, and it should be cancelled too.  */
+      step_over_finished = finish_step_over (event_child);
+    }
 
-  if (lwp->resume == NULL)
-    return 0;
+  /* We have all the data we need.  Either report the event to GDB, or
+     resume threads and keep waiting for more.  */
 
-  if (lwp->resume->kind == resume_stop)
+  /* If we're collecting a fast tracepoint, finish the collection and
+     move out of the jump pad before delivering a signal.  See
+     linux_stabilize_threads.  */
+
+  if (WIFSTOPPED (w)
+      && WSTOPSIG (w) != SIGTRAP
+      && supports_fast_tracepoints ()
+      && agent_loaded_p ())
     {
       if (debug_threads)
-       fprintf (stderr, "suspending LWP %ld\n", lwpid_of (lwp));
-
-      if (!lwp->stopped)
+       fprintf (stderr,
+                "Got signal %d for LWP %ld.  Check if we need "
+                "to defer or adjust it.\n",
+                WSTOPSIG (w), lwpid_of (event_child));
+
+      /* Allow debugging the jump pad itself.  */
+      if (current_inferior->last_resume_kind != resume_step
+         && maybe_move_out_of_jump_pad (event_child, &w))
        {
+         enqueue_one_deferred_signal (event_child, &w);
+
          if (debug_threads)
-           fprintf (stderr, "running -> suspending %ld\n", lwpid_of (lwp));
+           fprintf (stderr,
+                    "Signal %d for LWP %ld deferred (in jump pad)\n",
+                    WSTOPSIG (w), lwpid_of (event_child));
 
-         lwp->suspended = 1;
-         send_sigstop (&lwp->head);
+         linux_resume_one_lwp (event_child, 0, 0, NULL);
+         goto retry;
        }
-      else
+    }
+
+  if (event_child->collecting_fast_tracepoint)
+    {
+      if (debug_threads)
+       fprintf (stderr, "\
+LWP %ld was trying to move out of the jump pad (%d).  \
+Check if we're already there.\n",
+                lwpid_of (event_child),
+                event_child->collecting_fast_tracepoint);
+
+      trace_event = 1;
+
+      event_child->collecting_fast_tracepoint
+       = linux_fast_tracepoint_collecting (event_child, NULL);
+
+      if (event_child->collecting_fast_tracepoint != 1)
+       {
+         /* No longer need this breakpoint.  */
+         if (event_child->exit_jump_pad_bkpt != NULL)
+           {
+             if (debug_threads)
+               fprintf (stderr,
+                        "No longer need exit-jump-pad bkpt; removing it."
+                        "stopping all threads momentarily.\n");
+
+             /* Other running threads could hit this breakpoint.
+                We don't handle moribund locations like GDB does,
+                instead we always pause all threads when removing
+                breakpoints, so that any step-over or
+                decr_pc_after_break adjustment is always taken
+                care of while the breakpoint is still
+                inserted.  */
+             stop_all_lwps (1, event_child);
+             cancel_breakpoints ();
+
+             delete_breakpoint (event_child->exit_jump_pad_bkpt);
+             event_child->exit_jump_pad_bkpt = NULL;
+
+             unstop_all_lwps (1, event_child);
+
+             gdb_assert (event_child->suspended >= 0);
+           }
+       }
+
+      if (event_child->collecting_fast_tracepoint == 0)
        {
          if (debug_threads)
+           fprintf (stderr,
+                    "fast tracepoint finished "
+                    "collecting successfully.\n");
+
+         /* We may have a deferred signal to report.  */
+         if (dequeue_one_deferred_signal (event_child, &w))
            {
-             if (lwp->suspended)
-               fprintf (stderr, "already stopped/suspended LWP %ld\n",
-                        lwpid_of (lwp));
-             else
-               fprintf (stderr, "already stopped/not suspended LWP %ld\n",
-                        lwpid_of (lwp));
+             if (debug_threads)
+               fprintf (stderr, "dequeued one signal.\n");
            }
+         else
+           {
+             if (debug_threads)
+               fprintf (stderr, "no deferred signals.\n");
 
-         /* Make sure we leave the LWP suspended, so we don't try to
-            resume it without GDB telling us to.  FIXME: The LWP may
-            have been stopped in an internal event that was not meant
-            to be notified back to GDB (e.g., gdbserver breakpoint),
-            so we should be reporting a stop event in that case
-            too.  */
-         lwp->suspended = 1;
+             if (stabilizing_threads)
+               {
+                 ourstatus->kind = TARGET_WAITKIND_STOPPED;
+                 ourstatus->value.sig = TARGET_SIGNAL_0;
+                 return ptid_of (event_child);
+               }
+           }
        }
-
-      /* For stop requests, we're done.  */
-      lwp->resume = NULL;
-      return 0;
     }
-  else
-    lwp->suspended = 0;
-
-  /* If this thread which is about to be resumed has a pending status,
-     then don't resume any threads - we can just report the pending
-     status.  Make sure to queue any signals that would otherwise be
-     sent.  In all-stop mode, we do this decision based on if *any*
-     thread has a pending status.  */
-  if (non_stop)
-    resume_status_pending_p (&lwp->head, &pending_flag);
 
-  if (!pending_flag)
+  /* Check whether GDB would be interested in this event.  */
+
+  /* If GDB is not interested in this signal, don't stop other
+     threads, and don't report it to GDB.  Just resume the inferior
+     right away.  We do this for threading-related signals as well as
+     any that GDB specifically requested we ignore.  But never ignore
+     SIGSTOP if we sent it ourselves, and do not ignore signals when
+     stepping - they may require special handling to skip the signal
+     handler.  */
+  /* FIXME drow/2002-06-09: Get signal numbers from the inferior's
+     thread library?  */
+  if (WIFSTOPPED (w)
+      && current_inferior->last_resume_kind != resume_step
+      && (
+#if defined (USE_THREAD_DB) && !defined (__ANDROID__)
+         (current_process ()->private->thread_db != NULL
+          && (WSTOPSIG (w) == __SIGRTMIN
+              || WSTOPSIG (w) == __SIGRTMIN + 1))
+         ||
+#endif
+         (pass_signals[target_signal_from_host (WSTOPSIG (w))]
+          && !(WSTOPSIG (w) == SIGSTOP
+               && current_inferior->last_resume_kind == resume_stop))))
     {
+      siginfo_t info, *info_p;
+
       if (debug_threads)
-       fprintf (stderr, "resuming LWP %ld\n", lwpid_of (lwp));
+       fprintf (stderr, "Ignored signal %d for LWP %ld.\n",
+                WSTOPSIG (w), lwpid_of (event_child));
 
-      if (lwp->resume->thread == -1
-         && lwp->stepping
-         && lwp->pending_is_breakpoint)
-       step = 1;
+      if (ptrace (PTRACE_GETSIGINFO, lwpid_of (event_child), 0, &info) == 0)
+       info_p = &info;
       else
-       step = (lwp->resume->kind == resume_step);
-
-      linux_resume_one_lwp (&lwp->head, step, lwp->resume->sig, NULL);
+       info_p = NULL;
+      linux_resume_one_lwp (event_child, event_child->stepping,
+                           WSTOPSIG (w), info_p);
+      goto retry;
     }
-  else
+
+  /* If GDB wanted this thread to single step, we always want to
+     report the SIGTRAP, and let GDB handle it.  Watchpoints should
+     always be reported.  So should signals we can't explain.  A
+     SIGTRAP we can't explain could be a GDB breakpoint --- we may or
+     not support Z0 breakpoints.  If we do, we're be able to handle
+     GDB breakpoints on top of internal breakpoints, by handling the
+     internal breakpoint and still reporting the event to GDB.  If we
+     don't, we're out of luck, GDB won't see the breakpoint hit.  */
+  report_to_gdb = (!maybe_internal_trap
+                  || current_inferior->last_resume_kind == resume_step
+                  || event_child->stopped_by_watchpoint
+                  || (!step_over_finished
+                      && !bp_explains_trap && !trace_event)
+                  || (gdb_breakpoint_here (event_child->stop_pc)
+                  && gdb_condition_true_at_breakpoint (event_child->stop_pc)));
+
+  /* We found no reason GDB would want us to stop.  We either hit one
+     of our own breakpoints, or finished an internal step GDB
+     shouldn't know about.  */
+  if (!report_to_gdb)
     {
       if (debug_threads)
-       fprintf (stderr, "leaving LWP %ld stopped\n", lwpid_of (lwp));
-
-      /* If we have a new signal, enqueue the signal.  */
-      if (lwp->resume->sig != 0)
        {
-         struct pending_signals *p_sig;
-         p_sig = xmalloc (sizeof (*p_sig));
-         p_sig->prev = lwp->pending_signals;
-         p_sig->signal = lwp->resume->sig;
-         memset (&p_sig->info, 0, sizeof (siginfo_t));
+         if (bp_explains_trap)
+           fprintf (stderr, "Hit a gdbserver breakpoint.\n");
+         if (step_over_finished)
+           fprintf (stderr, "Step-over finished.\n");
+         if (trace_event)
+           fprintf (stderr, "Tracepoint event.\n");
+       }
 
-         /* If this is the same signal we were previously stopped by,
-            make sure to queue its siginfo.  We can ignore the return
-            value of ptrace; if it fails, we'll skip
-            PTRACE_SETSIGINFO.  */
-         if (WIFSTOPPED (lwp->last_status)
-             && WSTOPSIG (lwp->last_status) == lwp->resume->sig)
-           ptrace (PTRACE_GETSIGINFO, lwpid_of (lwp), 0, &p_sig->info);
+      /* We're not reporting this breakpoint to GDB, so apply the
+        decr_pc_after_break adjustment to the inferior's regcache
+        ourselves.  */
 
-         lwp->pending_signals = p_sig;
+      if (the_low_target.set_pc != NULL)
+       {
+         struct regcache *regcache
+           = get_thread_regcache (get_lwp_thread (event_child), 1);
+         (*the_low_target.set_pc) (regcache, event_child->stop_pc);
        }
-    }
-
-  lwp->resume = NULL;
-  return 0;
-}
 
-static void
-linux_resume (struct thread_resume *resume_info, size_t n)
-{
-  int pending_flag;
-  struct thread_resume_array array = { resume_info, n };
+      /* We may have finished stepping over a breakpoint.  If so,
+        we've stopped and suspended all LWPs momentarily except the
+        stepping one.  This is where we resume them all again.  We're
+        going to keep waiting, so use proceed, which handles stepping
+        over the next breakpoint.  */
+      if (debug_threads)
+       fprintf (stderr, "proceeding all threads.\n");
 
-  find_inferior (&all_threads, linux_set_resume_request, &array);
+      if (step_over_finished)
+       unsuspend_all_lwps (event_child);
 
-  /* If there is a thread which would otherwise be resumed, which
-     has a pending status, then don't resume any threads - we can just
-     report the pending status.  Make sure to queue any signals
-     that would otherwise be sent.  In non-stop mode, we'll apply this
-     logic to each thread individually.  */
-  pending_flag = 0;
-  if (!non_stop)
-    find_inferior (&all_lwps, resume_status_pending_p, &pending_flag);
+      proceed_all_lwps ();
+      goto retry;
+    }
 
   if (debug_threads)
     {
-      if (pending_flag)
-       fprintf (stderr, "Not resuming, pending status\n");
-      else
-       fprintf (stderr, "Resuming, no pending status\n");
+      if (current_inferior->last_resume_kind == resume_step)
+       fprintf (stderr, "GDB wanted to single-step, reporting event.\n");
+      if (event_child->stopped_by_watchpoint)
+       fprintf (stderr, "Stopped by watchpoint.\n");
+      if (gdb_breakpoint_here (event_child->stop_pc))
+       fprintf (stderr, "Stopped by GDB breakpoint.\n");
+      if (debug_threads)
+       fprintf (stderr, "Hit a non-gdbserver trap event.\n");
     }
 
-  find_inferior (&all_threads, linux_resume_one_thread, &pending_flag);
-}
+  /* Alright, we're going to report a stop.  */
 
-#ifdef HAVE_LINUX_USRREGS
+  if (!non_stop && !stabilizing_threads)
+    {
+      /* In all-stop, stop all threads.  */
+      stop_all_lwps (0, NULL);
+
+      /* If we're not waiting for a specific LWP, choose an event LWP
+        from among those that have had events.  Giving equal priority
+        to all LWPs that have had events helps prevent
+        starvation.  */
+      if (ptid_equal (ptid, minus_one_ptid))
+       {
+         event_child->status_pending_p = 1;
+         event_child->status_pending = w;
 
-int
-register_addr (int regnum)
-{
-  int addr;
+         select_event_lwp (&event_child);
 
-  if (regnum < 0 || regnum >= the_low_target.num_regs)
-    error ("Invalid register number %d.", regnum);
-
-  addr = the_low_target.regmap[regnum];
-
-  return addr;
-}
+         event_child->status_pending_p = 0;
+         w = event_child->status_pending;
+       }
 
-/* Fetch one register.  */
-static void
-fetch_register (int regno)
-{
-  CORE_ADDR regaddr;
-  int i, size;
-  char *buf;
+      /* 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.  */
+      find_inferior (&all_lwps, cancel_breakpoints_callback, event_child);
+
+      /* If we were going a step-over, all other threads but the stepping one
+        had been paused in start_step_over, with their suspend counts
+        incremented.  We don't want to do a full unstop/unpause, because we're
+        in all-stop mode (so we want threads stopped), but we still need to
+        unsuspend the other threads, to decrement their `suspended' count
+        back.  */
+      if (step_over_finished)
+       unsuspend_all_lwps (event_child);
+
+      /* Stabilize threads (move out of jump pads).  */
+      stabilize_threads ();
+    }
+  else
+    {
+      /* If we just finished a step-over, then all threads had been
+        momentarily paused.  In all-stop, that's fine, we want
+        threads stopped by now anyway.  In non-stop, we need to
+        re-resume threads that GDB wanted to be running.  */
+      if (step_over_finished)
+       unstop_all_lwps (1, event_child);
+    }
 
-  if (regno >= the_low_target.num_regs)
-    return;
-  if ((*the_low_target.cannot_fetch_register) (regno))
-    return;
+  ourstatus->kind = TARGET_WAITKIND_STOPPED;
 
-  regaddr = register_addr (regno);
-  if (regaddr == -1)
-    return;
-  size = ((register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1)
-         & - sizeof (PTRACE_XFER_TYPE));
-  buf = alloca (size);
-  for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
+  if (current_inferior->last_resume_kind == resume_stop
+      && WSTOPSIG (w) == SIGSTOP)
     {
-      errno = 0;
-      *(PTRACE_XFER_TYPE *) (buf + i) =
-       ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0);
-      regaddr += sizeof (PTRACE_XFER_TYPE);
-      if (errno != 0)
-       {
-         /* Warning, not error, in case we are attached; sometimes the
-            kernel doesn't let us at the registers.  */
-         char *err = strerror (errno);
-         char *msg = alloca (strlen (err) + 128);
-         sprintf (msg, "reading register %d: %s", regno, err);
-         error (msg);
-         goto error_exit;
-       }
+      /* A thread that has been requested to stop by GDB with vCont;t,
+        and it stopped cleanly, so report as SIG0.  The use of
+        SIGSTOP is an implementation detail.  */
+      ourstatus->value.sig = TARGET_SIGNAL_0;
+    }
+  else if (current_inferior->last_resume_kind == resume_stop
+          && WSTOPSIG (w) != SIGSTOP)
+    {
+      /* A thread that has been requested to stop by GDB with vCont;t,
+        but, it stopped for other reasons.  */
+      ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
     }
-
-  if (the_low_target.supply_ptrace_register)
-    the_low_target.supply_ptrace_register (regno, buf);
   else
-    supply_register (regno, buf);
+    {
+      ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
+    }
+
+  gdb_assert (ptid_equal (step_over_bkpt, null_ptid));
+
+  if (debug_threads)
+    fprintf (stderr, "linux_wait ret = %s, %d, %d\n",
+            target_pid_to_str (ptid_of (event_child)),
+            ourstatus->kind,
+            ourstatus->value.sig);
 
-error_exit:;
+  return ptid_of (event_child);
 }
 
-/* Fetch all registers, or just one, from the child process.  */
+/* Get rid of any pending event in the pipe.  */
 static void
-usr_fetch_inferior_registers (int regno)
+async_file_flush (void)
 {
-  if (regno == -1 || regno == 0)
-    for (regno = 0; regno < the_low_target.num_regs; regno++)
-      fetch_register (regno);
-  else
-    fetch_register (regno);
+  int ret;
+  char buf;
+
+  do
+    ret = read (linux_event_pipe[0], &buf, 1);
+  while (ret >= 0 || (ret == -1 && errno == EINTR));
 }
 
-/* Store our register values back into the inferior.
-   If REGNO is -1, do this for all registers.
-   Otherwise, REGNO specifies which register (so we can save time).  */
+/* Put something in the pipe, so the event loop wakes up.  */
 static void
-usr_store_inferior_registers (int regno)
+async_file_mark (void)
 {
-  CORE_ADDR regaddr;
-  int i, size;
-  char *buf;
+  int ret;
 
-  if (regno >= 0)
-    {
-      if (regno >= the_low_target.num_regs)
-       return;
+  async_file_flush ();
 
-      if ((*the_low_target.cannot_store_register) (regno) == 1)
-       return;
+  do
+    ret = write (linux_event_pipe[1], "+", 1);
+  while (ret == 0 || (ret == -1 && errno == EINTR));
 
-      regaddr = register_addr (regno);
-      if (regaddr == -1)
-       return;
-      errno = 0;
-      size = (register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1)
-            & - sizeof (PTRACE_XFER_TYPE);
-      buf = alloca (size);
-      memset (buf, 0, size);
+  /* Ignore EAGAIN.  If the pipe is full, the event loop will already
+     be awakened anyway.  */
+}
 
-      if (the_low_target.collect_ptrace_register)
-       the_low_target.collect_ptrace_register (regno, buf);
-      else
-       collect_register (regno, buf);
+static ptid_t
+linux_wait (ptid_t ptid,
+           struct target_waitstatus *ourstatus, int target_options)
+{
+  ptid_t event_ptid;
 
-      for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
-       {
-         errno = 0;
-         ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
-                 *(PTRACE_XFER_TYPE *) (buf + i));
-         if (errno != 0)
-           {
-             /* At this point, ESRCH should mean the process is
-                already gone, in which case we simply ignore attempts
-                to change its registers.  See also the related
-                comment in linux_resume_one_lwp.  */
-             if (errno == ESRCH)
-               return;
+  if (debug_threads)
+    fprintf (stderr, "linux_wait: [%s]\n", target_pid_to_str (ptid));
 
-             if ((*the_low_target.cannot_store_register) (regno) == 0)
-               {
-                 char *err = strerror (errno);
-                 char *msg = alloca (strlen (err) + 128);
-                 sprintf (msg, "writing register %d: %s",
-                          regno, err);
-                 error (msg);
-                 return;
-               }
-           }
-         regaddr += sizeof (PTRACE_XFER_TYPE);
-       }
-    }
-  else
-    for (regno = 0; regno < the_low_target.num_regs; regno++)
-      usr_store_inferior_registers (regno);
-}
-#endif /* HAVE_LINUX_USRREGS */
+  /* Flush the async file first.  */
+  if (target_is_async_p ())
+    async_file_flush ();
+
+  event_ptid = linux_wait_1 (ptid, ourstatus, target_options);
 
+  /* If at least one stop was reported, there may be more.  A single
+     SIGCHLD can signal more than one child stop.  */
+  if (target_is_async_p ()
+      && (target_options & TARGET_WNOHANG) != 0
+      && !ptid_equal (event_ptid, null_ptid))
+    async_file_mark ();
 
+  return event_ptid;
+}
 
-#ifdef HAVE_LINUX_REGSETS
+/* Send a signal to an LWP.  */
 
 static int
-regsets_fetch_inferior_registers ()
+kill_lwp (unsigned long lwpid, int signo)
 {
-  struct regset_info *regset;
-  int saw_general_regs = 0;
-
-  regset = target_regsets;
+  /* 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.  */
 
-  while (regset->size >= 0)
-    {
-      void *buf;
-      int res;
+#ifdef __NR_tkill
+  {
+    static int tkill_failed;
 
-      if (regset->size == 0 || disabled_regsets[regset - target_regsets])
-       {
-         regset ++;
-         continue;
-       }
+    if (!tkill_failed)
+      {
+       int ret;
 
-      buf = xmalloc (regset->size);
-#ifndef __sparc__
-      res = ptrace (regset->get_request, inferior_pid, 0, buf);
-#else
-      res = ptrace (regset->get_request, inferior_pid, buf, 0);
+       errno = 0;
+       ret = syscall (__NR_tkill, lwpid, signo);
+       if (errno != ENOSYS)
+         return ret;
+       tkill_failed = 1;
+      }
+  }
 #endif
-      if (res < 0)
-       {
-         if (errno == EIO)
-           {
-             /* If we get EIO on a regset, do not try it again for
-                this process.  */
-             disabled_regsets[regset - target_regsets] = 1;
-             continue;
-           }
-         else
-           {
-             char s[256];
-             sprintf (s, "ptrace(regsets_fetch_inferior_registers) PID=%ld",
-                      inferior_pid);
-             perror (s);
-           }
-       }
-      else if (regset->type == GENERAL_REGS)
-       saw_general_regs = 1;
-      regset->store_function (buf);
-      regset ++;
-    }
-  if (saw_general_regs)
-    return 0;
-  else
-    return 1;
+
+  return kill (lwpid, signo);
 }
 
-static int
-regsets_store_inferior_registers ()
+void
+linux_stop_lwp (struct lwp_info *lwp)
 {
-  struct regset_info *regset;
-  int saw_general_regs = 0;
+  send_sigstop (lwp);
+}
 
-  regset = target_regsets;
+static void
+send_sigstop (struct lwp_info *lwp)
+{
+  int pid;
 
-  while (regset->size >= 0)
+  pid = lwpid_of (lwp);
+
+  /* If we already have a pending stop signal for this process, don't
+     send another.  */
+  if (lwp->stop_expected)
     {
-      void *buf;
-      int res;
+      if (debug_threads)
+       fprintf (stderr, "Have pending sigstop for lwp %d\n", pid);
 
-      if (regset->size == 0 || disabled_regsets[regset - target_regsets])
-       {
-         regset ++;
-         continue;
-       }
+      return;
+    }
 
-      buf = xmalloc (regset->size);
+  if (debug_threads)
+    fprintf (stderr, "Sending sigstop to lwp %d\n", pid);
 
-      /* First fill the buffer with the current register set contents,
-        in case there are any items in the kernel's regset that are
-        not in gdbserver's regcache.  */
-#ifndef __sparc__
-      res = ptrace (regset->get_request, inferior_pid, 0, buf);
-#else
-      res = ptrace (regset->get_request, inferior_pid, buf, 0);
-#endif
+  lwp->stop_expected = 1;
+  kill_lwp (pid, SIGSTOP);
+}
 
-      if (res == 0)
-       {
-         /* Then overlay our cached registers on that.  */
-         regset->fill_function (buf);
+static int
+send_sigstop_callback (struct inferior_list_entry *entry, void *except)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
 
-         /* Only now do we write the register set.  */
-#ifndef __sparc__
-         res = ptrace (regset->set_request, inferior_pid, 0, buf);
-#else
-         res = ptrace (regset->set_request, inferior_pid, buf, 0);
-#endif
-       }
+  /* Ignore EXCEPT.  */
+  if (lwp == except)
+    return 0;
 
-      if (res < 0)
-       {
-         if (errno == EIO)
-           {
-             /* If we get EIO on a regset, do not try it again for
-                this process.  */
-             disabled_regsets[regset - target_regsets] = 1;
-             continue;
-           }
-         else if (errno == ESRCH)
-           {
-             /* At this point, ESRCH should mean the process is
-                already gone, in which case we simply ignore attempts
-                to change its registers.  See also the related
-                comment in linux_resume_one_lwp.  */
-             return 0;
-           }
-         else
-           {
-             perror ("Warning: ptrace(regsets_store_inferior_registers)");
-           }
-       }
-      else if (regset->type == GENERAL_REGS)
-       saw_general_regs = 1;
-      regset ++;
-      free (buf);
-    }
-  if (saw_general_regs)
+  if (lwp->stopped)
     return 0;
-  else
-    return 1;
+
+  send_sigstop (lwp);
   return 0;
 }
 
-#endif /* HAVE_LINUX_REGSETS */
+/* Increment the suspend count of an LWP, and stop it, if not stopped
+   yet.  */
+static int
+suspend_and_send_sigstop_callback (struct inferior_list_entry *entry,
+                                  void *except)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
 
+  /* Ignore EXCEPT.  */
+  if (lwp == except)
+    return 0;
 
-void
-linux_fetch_registers (int regno)
-{
-#ifdef HAVE_LINUX_REGSETS
-  if (regsets_fetch_inferior_registers () == 0)
-    return;
-#endif
-#ifdef HAVE_LINUX_USRREGS
-  usr_fetch_inferior_registers (regno);
-#endif
+  lwp->suspended++;
+
+  return send_sigstop_callback (entry, except);
 }
 
-void
-linux_store_registers (int regno)
+static void
+mark_lwp_dead (struct lwp_info *lwp, int wstat)
 {
-#ifdef HAVE_LINUX_REGSETS
-  if (regsets_store_inferior_registers () == 0)
-    return;
-#endif
-#ifdef HAVE_LINUX_USRREGS
-  usr_store_inferior_registers (regno);
-#endif
-}
+  /* It's dead, really.  */
+  lwp->dead = 1;
 
+  /* Store the exit status for later.  */
+  lwp->status_pending_p = 1;
+  lwp->status_pending = wstat;
 
-/* Copy LEN bytes from inferior's memory starting at MEMADDR
-   to debugger memory starting at MYADDR.  */
+  /* Prevent trying to stop it.  */
+  lwp->stopped = 1;
 
-static int
-linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
-{
-  register int i;
-  /* Round starting address down to longword boundary.  */
-  register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
-  /* Round ending address up; get number of longwords that makes.  */
-  register int count
-    = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
-      / sizeof (PTRACE_XFER_TYPE);
-  /* Allocate buffer of that many longwords.  */
-  register PTRACE_XFER_TYPE *buffer
-    = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
-  int fd;
-  char filename[64];
+  /* No further stops are expected from a dead lwp.  */
+  lwp->stop_expected = 0;
+}
 
-  /* Try using /proc.  Don't bother for one word.  */
-  if (len >= 3 * sizeof (long))
+static void
+wait_for_sigstop (struct inferior_list_entry *entry)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+  struct thread_info *saved_inferior;
+  int wstat;
+  ptid_t saved_tid;
+  ptid_t ptid;
+  int pid;
+
+  if (lwp->stopped)
     {
-      /* We could keep this file open and cache it - possibly one per
-        thread.  That requires some juggling, but is even faster.  */
-      sprintf (filename, "/proc/%ld/mem", inferior_pid);
-      fd = open (filename, O_RDONLY | O_LARGEFILE);
-      if (fd == -1)
-       goto no_proc;
+      if (debug_threads)
+       fprintf (stderr, "wait_for_sigstop: LWP %ld already stopped\n",
+                lwpid_of (lwp));
+      return;
+    }
 
-      /* If pread64 is available, use it.  It's faster if the kernel
-        supports it (only one syscall), and it's 64-bit safe even on
-        32-bit platforms (for instance, SPARC debugging a SPARC64
-        application).  */
-#ifdef HAVE_PREAD64
-      if (pread64 (fd, myaddr, len, memaddr) != len)
-#else
-      if (lseek (fd, memaddr, SEEK_SET) == -1 || read (fd, memaddr, len) != len)
-#endif
+  saved_inferior = current_inferior;
+  if (saved_inferior != NULL)
+    saved_tid = ((struct inferior_list_entry *) saved_inferior)->id;
+  else
+    saved_tid = null_ptid; /* avoid bogus unused warning */
+
+  ptid = lwp->head.id;
+
+  if (debug_threads)
+    fprintf (stderr, "wait_for_sigstop: pulling one event\n");
+
+  pid = linux_wait_for_event (ptid, &wstat, __WALL);
+
+  /* If we stopped with a non-SIGSTOP signal, save it for later
+     and record the pending SIGSTOP.  If the process exited, just
+     return.  */
+  if (WIFSTOPPED (wstat))
+    {
+      if (debug_threads)
+       fprintf (stderr, "LWP %ld stopped with signal %d\n",
+                lwpid_of (lwp), WSTOPSIG (wstat));
+
+      if (WSTOPSIG (wstat) != SIGSTOP)
        {
-         close (fd);
-         goto no_proc;
+         if (debug_threads)
+           fprintf (stderr, "LWP %ld stopped with non-sigstop status %06x\n",
+                    lwpid_of (lwp), wstat);
+
+         lwp->status_pending_p = 1;
+         lwp->status_pending = wstat;
        }
+    }
+  else
+    {
+      if (debug_threads)
+       fprintf (stderr, "Process %d exited while stopping LWPs\n", pid);
 
-      close (fd);
-      return 0;
+      lwp = find_lwp_pid (pid_to_ptid (pid));
+      if (lwp)
+       {
+         /* Leave this status pending for the next time we're able to
+            report it.  In the mean time, we'll report this lwp as
+            dead to GDB, so GDB doesn't try to read registers and
+            memory from it.  This can only happen if this was the
+            last thread of the process; otherwise, PID is removed
+            from the thread tables before linux_wait_for_event
+            returns.  */
+         mark_lwp_dead (lwp, wstat);
+       }
     }
 
- no_proc:
-  /* Read all the longwords */
-  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
+  if (saved_inferior == NULL || linux_thread_alive (saved_tid))
+    current_inferior = saved_inferior;
+  else
     {
-      errno = 0;
-      buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid,
-                         (PTRACE_ARG3_TYPE) addr, 0);
-      if (errno)
-       return errno;
+      if (debug_threads)
+       fprintf (stderr, "Previously current thread died.\n");
+
+      if (non_stop)
+       {
+         /* We can't change the current inferior behind GDB's back,
+            otherwise, a subsequent command may apply to the wrong
+            process.  */
+         current_inferior = NULL;
+       }
+      else
+       {
+         /* Set a valid thread as current.  */
+         set_desired_inferior (0);
+       }
     }
+}
 
-  /* Copy appropriate bytes out of the buffer.  */
-  memcpy (myaddr,
-         (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
-         len);
+/* Returns true if LWP ENTRY is stopped in a jump pad, and we can't
+   move it out, because we need to report the stop event to GDB.  For
+   example, if the user puts a breakpoint in the jump pad, it's
+   because she wants to debug it.  */
 
-  return 0;
+static int
+stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+  struct thread_info *thread = get_lwp_thread (lwp);
+
+  gdb_assert (lwp->suspended == 0);
+  gdb_assert (lwp->stopped);
+
+  /* Allow debugging the jump pad, gdb_collect, etc..  */
+  return (supports_fast_tracepoints ()
+         && agent_loaded_p ()
+         && (gdb_breakpoint_here (lwp->stop_pc)
+             || lwp->stopped_by_watchpoint
+             || thread->last_resume_kind == resume_step)
+         && linux_fast_tracepoint_collecting (lwp, NULL));
 }
 
-/* Copy LEN bytes of data from debugger memory at MYADDR
-   to inferior's memory at MEMADDR.
-   On failure (cannot write the inferior)
-   returns the value of errno.  */
+static void
+move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+  struct thread_info *thread = get_lwp_thread (lwp);
+  int *wstat;
+
+  gdb_assert (lwp->suspended == 0);
+  gdb_assert (lwp->stopped);
+
+  wstat = lwp->status_pending_p ? &lwp->status_pending : NULL;
+
+  /* Allow debugging the jump pad, gdb_collect, etc.  */
+  if (!gdb_breakpoint_here (lwp->stop_pc)
+      && !lwp->stopped_by_watchpoint
+      && thread->last_resume_kind != resume_step
+      && maybe_move_out_of_jump_pad (lwp, wstat))
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "LWP %ld needs stabilizing (in jump pad)\n",
+                lwpid_of (lwp));
+
+      if (wstat)
+       {
+         lwp->status_pending_p = 0;
+         enqueue_one_deferred_signal (lwp, wstat);
+
+         if (debug_threads)
+           fprintf (stderr,
+                    "Signal %d for LWP %ld deferred "
+                    "(in jump pad)\n",
+                    WSTOPSIG (*wstat), lwpid_of (lwp));
+       }
+
+      linux_resume_one_lwp (lwp, 0, 0, NULL);
+    }
+  else
+    lwp->suspended++;
+}
 
 static int
-linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
+lwp_running (struct inferior_list_entry *entry, void *data)
 {
-  register int i;
-  /* Round starting address down to longword boundary.  */
-  register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
-  /* Round ending address up; get number of longwords that makes.  */
-  register int count
-  = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE);
-  /* Allocate buffer of that many longwords.  */
-  register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+
+  if (lwp->dead)
+    return 0;
+  if (lwp->stopped)
+    return 0;
+  return 1;
+}
+
+/* Stop all lwps that aren't stopped yet, except EXCEPT, if not NULL.
+   If SUSPEND, then also increase the suspend count of every LWP,
+   except EXCEPT.  */
+
+static void
+stop_all_lwps (int suspend, struct lwp_info *except)
+{
+  stopping_threads = 1;
+
+  if (suspend)
+    find_inferior (&all_lwps, suspend_and_send_sigstop_callback, except);
+  else
+    find_inferior (&all_lwps, send_sigstop_callback, except);
+  for_each_inferior (&all_lwps, wait_for_sigstop);
+  stopping_threads = 0;
+}
+
+/* Resume execution of the inferior process.
+   If STEP is nonzero, single-step it.
+   If SIGNAL is nonzero, give it that signal.  */
+
+static void
+linux_resume_one_lwp (struct lwp_info *lwp,
+                     int step, int signal, siginfo_t *info)
+{
+  struct thread_info *saved_inferior;
+  int fast_tp_collecting;
+
+  if (lwp->stopped == 0)
+    return;
+
+  fast_tp_collecting = lwp->collecting_fast_tracepoint;
+
+  gdb_assert (!stabilizing_threads || fast_tp_collecting);
+
+  /* Cancel actions that rely on GDB not changing the PC (e.g., the
+     user used the "jump" command, or "set $pc = foo").  */
+  if (lwp->stop_pc != get_pc (lwp))
+    {
+      /* Collecting 'while-stepping' actions doesn't make sense
+        anymore.  */
+      release_while_stepping_state_list (get_lwp_thread (lwp));
+    }
+
+  /* If we have pending signals or status, and a new signal, enqueue the
+     signal.  Also enqueue the signal if we are waiting to reinsert a
+     breakpoint; it will be picked up again below.  */
+  if (signal != 0
+      && (lwp->status_pending_p
+         || lwp->pending_signals != NULL
+         || lwp->bp_reinsert != 0
+         || fast_tp_collecting))
+    {
+      struct pending_signals *p_sig;
+      p_sig = xmalloc (sizeof (*p_sig));
+      p_sig->prev = lwp->pending_signals;
+      p_sig->signal = signal;
+      if (info == NULL)
+       memset (&p_sig->info, 0, sizeof (siginfo_t));
+      else
+       memcpy (&p_sig->info, info, sizeof (siginfo_t));
+      lwp->pending_signals = p_sig;
+    }
+
+  if (lwp->status_pending_p)
+    {
+      if (debug_threads)
+       fprintf (stderr, "Not resuming lwp %ld (%s, signal %d, stop %s);"
+                " has pending status\n",
+                lwpid_of (lwp), step ? "step" : "continue", signal,
+                lwp->stop_expected ? "expected" : "not expected");
+      return;
+    }
+
+  saved_inferior = current_inferior;
+  current_inferior = get_lwp_thread (lwp);
 
   if (debug_threads)
+    fprintf (stderr, "Resuming lwp %ld (%s, signal %d, stop %s)\n",
+            lwpid_of (lwp), step ? "step" : "continue", signal,
+            lwp->stop_expected ? "expected" : "not expected");
+
+  /* This bit needs some thinking about.  If we get a signal that
+     we must report while a single-step reinsert is still pending,
+     we often end up resuming the thread.  It might be better to
+     (ew) allow a stack of pending events; then we could be sure that
+     the reinsert happened right away and not lose any signals.
+
+     Making this stack would also shrink the window in which breakpoints are
+     uninserted (see comment in linux_wait_for_lwp) but not enough for
+     complete correctness, so it won't solve that problem.  It may be
+     worthwhile just to solve this one, however.  */
+  if (lwp->bp_reinsert != 0)
+    {
+      if (debug_threads)
+       fprintf (stderr, "  pending reinsert at 0x%s\n",
+                paddress (lwp->bp_reinsert));
+
+      if (lwp->bp_reinsert != 0 && can_hardware_single_step ())
+       {
+         if (fast_tp_collecting == 0)
+           {
+             if (step == 0)
+               fprintf (stderr, "BAD - reinserting but not stepping.\n");
+             if (lwp->suspended)
+               fprintf (stderr, "BAD - reinserting and suspended(%d).\n",
+                        lwp->suspended);
+           }
+
+         step = 1;
+       }
+
+      /* Postpone any pending signal.  It was enqueued above.  */
+      signal = 0;
+    }
+
+  if (fast_tp_collecting == 1)
     {
-      fprintf (stderr, "Writing %02x to %08lx\n", (unsigned)myaddr[0], (long)memaddr);
+      if (debug_threads)
+       fprintf (stderr, "\
+lwp %ld wants to get out of fast tracepoint jump pad (exit-jump-pad-bkpt)\n",
+                lwpid_of (lwp));
+
+      /* Postpone any pending signal.  It was enqueued above.  */
+      signal = 0;
     }
+  else if (fast_tp_collecting == 2)
+    {
+      if (debug_threads)
+       fprintf (stderr, "\
+lwp %ld wants to get out of fast tracepoint jump pad single-stepping\n",
+                lwpid_of (lwp));
 
-  /* Fill start and end extra bytes of buffer with existing memory data.  */
+      if (can_hardware_single_step ())
+       step = 1;
+      else
+       fatal ("moving out of jump pad single-stepping"
+              " not implemented on this target");
+
+      /* Postpone any pending signal.  It was enqueued above.  */
+      signal = 0;
+    }
+
+  /* If we have while-stepping actions in this thread set it stepping.
+     If we have a signal to deliver, it may or may not be set to
+     SIG_IGN, we don't know.  Assume so, and allow collecting
+     while-stepping into a signal handler.  A possible smart thing to
+     do would be to set an internal breakpoint at the signal return
+     address, continue, and carry on catching this while-stepping
+     action only when that breakpoint is hit.  A future
+     enhancement.  */
+  if (get_lwp_thread (lwp)->while_stepping != NULL
+      && can_hardware_single_step ())
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "lwp %ld has a while-stepping action -> forcing step.\n",
+                lwpid_of (lwp));
+      step = 1;
+    }
+
+  if (debug_threads && the_low_target.get_pc != NULL)
+    {
+      struct regcache *regcache = get_thread_regcache (current_inferior, 1);
+      CORE_ADDR pc = (*the_low_target.get_pc) (regcache);
+      fprintf (stderr, "  resuming from pc 0x%lx\n", (long) pc);
+    }
+
+  /* If we have pending signals, consume one unless we are trying to
+     reinsert a breakpoint or we're trying to finish a fast tracepoint
+     collect.  */
+  if (lwp->pending_signals != NULL
+      && lwp->bp_reinsert == 0
+      && fast_tp_collecting == 0)
+    {
+      struct pending_signals **p_sig;
+
+      p_sig = &lwp->pending_signals;
+      while ((*p_sig)->prev != NULL)
+       p_sig = &(*p_sig)->prev;
+
+      signal = (*p_sig)->signal;
+      if ((*p_sig)->info.si_signo != 0)
+       ptrace (PTRACE_SETSIGINFO, lwpid_of (lwp), 0, &(*p_sig)->info);
+
+      free (*p_sig);
+      *p_sig = NULL;
+    }
 
-  buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid,
-                     (PTRACE_ARG3_TYPE) addr, 0);
+  if (the_low_target.prepare_to_resume != NULL)
+    the_low_target.prepare_to_resume (lwp);
+
+  regcache_invalidate_one ((struct inferior_list_entry *)
+                          get_lwp_thread (lwp));
+  errno = 0;
+  lwp->stopped = 0;
+  lwp->stopped_by_watchpoint = 0;
+  lwp->stepping = step;
+  ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, lwpid_of (lwp), 0,
+         /* Coerce to a uintptr_t first to avoid potential gcc warning
+            of coercing an 8 byte integer to a 4 byte pointer.  */
+         (PTRACE_ARG4_TYPE) (uintptr_t) signal);
+
+  current_inferior = saved_inferior;
+  if (errno)
+    {
+      /* ESRCH from ptrace either means that the thread was already
+        running (an error) or that it is gone (a race condition).  If
+        it's gone, we will get a notification the next time we wait,
+        so we can ignore the error.  We could differentiate these
+        two, but it's tricky without waiting; the thread still exists
+        as a zombie, so sending it signal 0 would succeed.  So just
+        ignore ESRCH.  */
+      if (errno == ESRCH)
+       return;
+
+      perror_with_name ("ptrace");
+    }
+}
+
+struct thread_resume_array
+{
+  struct thread_resume *resume;
+  size_t n;
+};
+
+/* This function is called once per thread.  We look up the thread
+   in RESUME_PTR, and mark the thread with a pointer to the appropriate
+   resume request.
+
+   This algorithm is O(threads * resume elements), but resume elements
+   is small (and will remain small at least until GDB supports thread
+   suspension).  */
+static int
+linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
+{
+  struct lwp_info *lwp;
+  struct thread_info *thread;
+  int ndx;
+  struct thread_resume_array *r;
+
+  thread = (struct thread_info *) entry;
+  lwp = get_thread_lwp (thread);
+  r = arg;
+
+  for (ndx = 0; ndx < r->n; ndx++)
+    {
+      ptid_t ptid = r->resume[ndx].thread;
+      if (ptid_equal (ptid, minus_one_ptid)
+         || ptid_equal (ptid, entry->id)
+         || (ptid_is_pid (ptid)
+             && (ptid_get_pid (ptid) == pid_of (lwp)))
+         || (ptid_get_lwp (ptid) == -1
+             && (ptid_get_pid (ptid) == pid_of (lwp))))
+       {
+         if (r->resume[ndx].kind == resume_stop
+             && thread->last_resume_kind == resume_stop)
+           {
+             if (debug_threads)
+               fprintf (stderr, "already %s LWP %ld at GDB's request\n",
+                        thread->last_status.kind == TARGET_WAITKIND_STOPPED
+                        ? "stopped"
+                        : "stopping",
+                        lwpid_of (lwp));
+
+             continue;
+           }
+
+         lwp->resume = &r->resume[ndx];
+         thread->last_resume_kind = lwp->resume->kind;
+
+         /* If we had a deferred signal to report, dequeue one now.
+            This can happen if LWP gets more than one signal while
+            trying to get out of a jump pad.  */
+         if (lwp->stopped
+             && !lwp->status_pending_p
+             && dequeue_one_deferred_signal (lwp, &lwp->status_pending))
+           {
+             lwp->status_pending_p = 1;
+
+             if (debug_threads)
+               fprintf (stderr,
+                        "Dequeueing deferred signal %d for LWP %ld, "
+                        "leaving status pending.\n",
+                        WSTOPSIG (lwp->status_pending), lwpid_of (lwp));
+           }
+
+         return 0;
+       }
+    }
+
+  /* No resume action for this thread.  */
+  lwp->resume = NULL;
+
+  return 0;
+}
+
+
+/* Set *FLAG_P if this lwp has an interesting status pending.  */
+static int
+resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+
+  /* LWPs which will not be resumed are not interesting, because
+     we might not wait for them next time through linux_wait.  */
+  if (lwp->resume == NULL)
+    return 0;
+
+  if (lwp->status_pending_p)
+    * (int *) flag_p = 1;
+
+  return 0;
+}
+
+/* Return 1 if this lwp that GDB wants running is stopped at an
+   internal breakpoint that we need to step over.  It assumes that any
+   required STOP_PC adjustment has already been propagated to the
+   inferior's regcache.  */
+
+static int
+need_step_over_p (struct inferior_list_entry *entry, void *dummy)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+  struct thread_info *thread;
+  struct thread_info *saved_inferior;
+  CORE_ADDR pc;
+
+  /* LWPs which will not be resumed are not interesting, because we
+     might not wait for them next time through linux_wait.  */
+
+  if (!lwp->stopped)
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "Need step over [LWP %ld]? Ignoring, not stopped\n",
+                lwpid_of (lwp));
+      return 0;
+    }
+
+  thread = get_lwp_thread (lwp);
+
+  if (thread->last_resume_kind == resume_stop)
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "Need step over [LWP %ld]? Ignoring, should remain stopped\n",
+                lwpid_of (lwp));
+      return 0;
+    }
+
+  gdb_assert (lwp->suspended >= 0);
+
+  if (lwp->suspended)
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "Need step over [LWP %ld]? Ignoring, suspended\n",
+                lwpid_of (lwp));
+      return 0;
+    }
+
+  if (!lwp->need_step_over)
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "Need step over [LWP %ld]? No\n", lwpid_of (lwp));
+    }
+
+  if (lwp->status_pending_p)
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "Need step over [LWP %ld]? Ignoring, has pending status.\n",
+                lwpid_of (lwp));
+      return 0;
+    }
+
+  /* Note: PC, not STOP_PC.  Either GDB has adjusted the PC already,
+     or we have.  */
+  pc = get_pc (lwp);
+
+  /* If the PC has changed since we stopped, then don't do anything,
+     and let the breakpoint/tracepoint be hit.  This happens if, for
+     instance, GDB handled the decr_pc_after_break subtraction itself,
+     GDB is OOL stepping this thread, or the user has issued a "jump"
+     command, or poked thread's registers herself.  */
+  if (pc != lwp->stop_pc)
+    {
+      if (debug_threads)
+       fprintf (stderr,
+                "Need step over [LWP %ld]? Cancelling, PC was changed.  "
+                "Old stop_pc was 0x%s, PC is now 0x%s\n",
+                lwpid_of (lwp), paddress (lwp->stop_pc), paddress (pc));
+
+      lwp->need_step_over = 0;
+      return 0;
+    }
+
+  saved_inferior = current_inferior;
+  current_inferior = thread;
+
+  /* We can only step over breakpoints we know about.  */
+  if (breakpoint_here (pc) || fast_tracepoint_jump_here (pc))
+    {
+      /* Don't step over a breakpoint that GDB expects to hit
+        though.  If the condition is being evaluated on the target's side
+        and it evaluate to false, step over this breakpoint as well.  */
+      if (gdb_breakpoint_here (pc)
+         && gdb_condition_true_at_breakpoint (pc))
+       {
+         if (debug_threads)
+           fprintf (stderr,
+                    "Need step over [LWP %ld]? yes, but found"
+                    " GDB breakpoint at 0x%s; skipping step over\n",
+                    lwpid_of (lwp), paddress (pc));
+
+         current_inferior = saved_inferior;
+         return 0;
+       }
+      else
+       {
+         if (debug_threads)
+           fprintf (stderr,
+                    "Need step over [LWP %ld]? yes, "
+                    "found breakpoint at 0x%s\n",
+                    lwpid_of (lwp), paddress (pc));
+
+         /* We've found an lwp that needs stepping over --- return 1 so
+            that find_inferior stops looking.  */
+         current_inferior = saved_inferior;
+
+         /* If the step over is cancelled, this is set again.  */
+         lwp->need_step_over = 0;
+         return 1;
+       }
+    }
+
+  current_inferior = saved_inferior;
+
+  if (debug_threads)
+    fprintf (stderr,
+            "Need step over [LWP %ld]? No, no breakpoint found at 0x%s\n",
+            lwpid_of (lwp), paddress (pc));
+
+  return 0;
+}
+
+/* Start a step-over operation on LWP.  When LWP stopped at a
+   breakpoint, to make progress, we need to remove the breakpoint out
+   of the way.  If we let other threads run while we do that, they may
+   pass by the breakpoint location and miss hitting it.  To avoid
+   that, a step-over momentarily stops all threads while LWP is
+   single-stepped while the breakpoint is temporarily uninserted from
+   the inferior.  When the single-step finishes, we reinsert the
+   breakpoint, and let all threads that are supposed to be running,
+   run again.
+
+   On targets that don't support hardware single-step, we don't
+   currently support full software single-stepping.  Instead, we only
+   support stepping over the thread event breakpoint, by asking the
+   low target where to place a reinsert breakpoint.  Since this
+   routine assumes the breakpoint being stepped over is a thread event
+   breakpoint, it usually assumes the return address of the current
+   function is a good enough place to set the reinsert breakpoint.  */
+
+static int
+start_step_over (struct lwp_info *lwp)
+{
+  struct thread_info *saved_inferior;
+  CORE_ADDR pc;
+  int step;
+
+  if (debug_threads)
+    fprintf (stderr,
+            "Starting step-over on LWP %ld.  Stopping all threads\n",
+            lwpid_of (lwp));
+
+  stop_all_lwps (1, lwp);
+  gdb_assert (lwp->suspended == 0);
+
+  if (debug_threads)
+    fprintf (stderr, "Done stopping all threads for step-over.\n");
+
+  /* Note, we should always reach here with an already adjusted PC,
+     either by GDB (if we're resuming due to GDB's request), or by our
+     caller, if we just finished handling an internal breakpoint GDB
+     shouldn't care about.  */
+  pc = get_pc (lwp);
+
+  saved_inferior = current_inferior;
+  current_inferior = get_lwp_thread (lwp);
+
+  lwp->bp_reinsert = pc;
+  uninsert_breakpoints_at (pc);
+  uninsert_fast_tracepoint_jumps_at (pc);
+
+  if (can_hardware_single_step ())
+    {
+      step = 1;
+    }
+  else
+    {
+      CORE_ADDR raddr = (*the_low_target.breakpoint_reinsert_addr) ();
+      set_reinsert_breakpoint (raddr);
+      step = 0;
+    }
+
+  current_inferior = saved_inferior;
+
+  linux_resume_one_lwp (lwp, step, 0, NULL);
+
+  /* Require next event from this LWP.  */
+  step_over_bkpt = lwp->head.id;
+  return 1;
+}
+
+/* Finish a step-over.  Reinsert the breakpoint we had uninserted in
+   start_step_over, if still there, and delete any reinsert
+   breakpoints we've set, on non hardware single-step targets.  */
+
+static int
+finish_step_over (struct lwp_info *lwp)
+{
+  if (lwp->bp_reinsert != 0)
+    {
+      if (debug_threads)
+       fprintf (stderr, "Finished step over.\n");
+
+      /* Reinsert any breakpoint at LWP->BP_REINSERT.  Note that there
+        may be no breakpoint to reinsert there by now.  */
+      reinsert_breakpoints_at (lwp->bp_reinsert);
+      reinsert_fast_tracepoint_jumps_at (lwp->bp_reinsert);
+
+      lwp->bp_reinsert = 0;
+
+      /* Delete any software-single-step reinsert breakpoints.  No
+        longer needed.  We don't have to worry about other threads
+        hitting this trap, and later not being able to explain it,
+        because we were stepping over a breakpoint, and we hold all
+        threads but LWP stopped while doing that.  */
+      if (!can_hardware_single_step ())
+       delete_reinsert_breakpoints ();
+
+      step_over_bkpt = null_ptid;
+      return 1;
+    }
+  else
+    return 0;
+}
+
+/* This function is called once per thread.  We check the thread's resume
+   request, which will tell us whether to resume, step, or leave the thread
+   stopped; and what signal, if any, it should be sent.
+
+   For threads which we aren't explicitly told otherwise, we preserve
+   the stepping flag; this is used for stepping over gdbserver-placed
+   breakpoints.
+
+   If pending_flags was set in any thread, we queue any needed
+   signals, since we won't actually resume.  We already have a pending
+   event to report, so we don't need to preserve any step requests;
+   they should be re-issued if necessary.  */
+
+static int
+linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
+{
+  struct lwp_info *lwp;
+  struct thread_info *thread;
+  int step;
+  int leave_all_stopped = * (int *) arg;
+  int leave_pending;
+
+  thread = (struct thread_info *) entry;
+  lwp = get_thread_lwp (thread);
+
+  if (lwp->resume == NULL)
+    return 0;
+
+  if (lwp->resume->kind == resume_stop)
+    {
+      if (debug_threads)
+       fprintf (stderr, "resume_stop request for LWP %ld\n", lwpid_of (lwp));
+
+      if (!lwp->stopped)
+       {
+         if (debug_threads)
+           fprintf (stderr, "stopping LWP %ld\n", lwpid_of (lwp));
+
+         /* Stop the thread, and wait for the event asynchronously,
+            through the event loop.  */
+         send_sigstop (lwp);
+       }
+      else
+       {
+         if (debug_threads)
+           fprintf (stderr, "already stopped LWP %ld\n",
+                    lwpid_of (lwp));
+
+         /* The LWP may have been stopped in an internal event that
+            was not meant to be notified back to GDB (e.g., gdbserver
+            breakpoint), so we should be reporting a stop event in
+            this case too.  */
+
+         /* If the thread already has a pending SIGSTOP, this is a
+            no-op.  Otherwise, something later will presumably resume
+            the thread and this will cause it to cancel any pending
+            operation, due to last_resume_kind == resume_stop.  If
+            the thread already has a pending status to report, we
+            will still report it the next time we wait - see
+            status_pending_p_callback.  */
+
+         /* If we already have a pending signal to report, then
+            there's no need to queue a SIGSTOP, as this means we're
+            midway through moving the LWP out of the jumppad, and we
+            will report the pending signal as soon as that is
+            finished.  */
+         if (lwp->pending_signals_to_report == NULL)
+           send_sigstop (lwp);
+       }
+
+      /* For stop requests, we're done.  */
+      lwp->resume = NULL;
+      thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+      return 0;
+    }
+
+  /* If this thread which is about to be resumed has a pending status,
+     then don't resume any threads - we can just report the pending
+     status.  Make sure to queue any signals that would otherwise be
+     sent.  In all-stop mode, we do this decision based on if *any*
+     thread has a pending status.  If there's a thread that needs the
+     step-over-breakpoint dance, then don't resume any other thread
+     but that particular one.  */
+  leave_pending = (lwp->status_pending_p || leave_all_stopped);
+
+  if (!leave_pending)
+    {
+      if (debug_threads)
+       fprintf (stderr, "resuming LWP %ld\n", lwpid_of (lwp));
+
+      step = (lwp->resume->kind == resume_step);
+      linux_resume_one_lwp (lwp, step, lwp->resume->sig, NULL);
+    }
+  else
+    {
+      if (debug_threads)
+       fprintf (stderr, "leaving LWP %ld stopped\n", lwpid_of (lwp));
+
+      /* If we have a new signal, enqueue the signal.  */
+      if (lwp->resume->sig != 0)
+       {
+         struct pending_signals *p_sig;
+         p_sig = xmalloc (sizeof (*p_sig));
+         p_sig->prev = lwp->pending_signals;
+         p_sig->signal = lwp->resume->sig;
+         memset (&p_sig->info, 0, sizeof (siginfo_t));
+
+         /* If this is the same signal we were previously stopped by,
+            make sure to queue its siginfo.  We can ignore the return
+            value of ptrace; if it fails, we'll skip
+            PTRACE_SETSIGINFO.  */
+         if (WIFSTOPPED (lwp->last_status)
+             && WSTOPSIG (lwp->last_status) == lwp->resume->sig)
+           ptrace (PTRACE_GETSIGINFO, lwpid_of (lwp), 0, &p_sig->info);
+
+         lwp->pending_signals = p_sig;
+       }
+    }
+
+  thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+  lwp->resume = NULL;
+  return 0;
+}
+
+static void
+linux_resume (struct thread_resume *resume_info, size_t n)
+{
+  struct thread_resume_array array = { resume_info, n };
+  struct lwp_info *need_step_over = NULL;
+  int any_pending;
+  int leave_all_stopped;
+
+  find_inferior (&all_threads, linux_set_resume_request, &array);
+
+  /* If there is a thread which would otherwise be resumed, which has
+     a pending status, then don't resume any threads - we can just
+     report the pending status.  Make sure to queue any signals that
+     would otherwise be sent.  In non-stop mode, we'll apply this
+     logic to each thread individually.  We consume all pending events
+     before considering to start a step-over (in all-stop).  */
+  any_pending = 0;
+  if (!non_stop)
+    find_inferior (&all_lwps, resume_status_pending_p, &any_pending);
+
+  /* If there is a thread which would otherwise be resumed, which is
+     stopped at a breakpoint that needs stepping over, then don't
+     resume any threads - have it step over the breakpoint with all
+     other threads stopped, then resume all threads again.  Make sure
+     to queue any signals that would otherwise be delivered or
+     queued.  */
+  if (!any_pending && supports_breakpoints ())
+    need_step_over
+      = (struct lwp_info *) find_inferior (&all_lwps,
+                                          need_step_over_p, NULL);
+
+  leave_all_stopped = (need_step_over != NULL || any_pending);
+
+  if (debug_threads)
+    {
+      if (need_step_over != NULL)
+       fprintf (stderr, "Not resuming all, need step over\n");
+      else if (any_pending)
+       fprintf (stderr,
+                "Not resuming, all-stop and found "
+                "an LWP with pending status\n");
+      else
+       fprintf (stderr, "Resuming, no pending status or step over needed\n");
+    }
+
+  /* Even if we're leaving threads stopped, queue all signals we'd
+     otherwise deliver.  */
+  find_inferior (&all_threads, linux_resume_one_thread, &leave_all_stopped);
+
+  if (need_step_over)
+    start_step_over (need_step_over);
+}
+
+/* This function is called once per thread.  We check the thread's
+   last resume request, which will tell us whether to resume, step, or
+   leave the thread stopped.  Any signal the client requested to be
+   delivered has already been enqueued at this point.
+
+   If any thread that GDB wants running is stopped at an internal
+   breakpoint that needs stepping over, we start a step-over operation
+   on that particular thread, and leave all others stopped.  */
+
+static int
+proceed_one_lwp (struct inferior_list_entry *entry, void *except)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+  struct thread_info *thread;
+  int step;
+
+  if (lwp == except)
+    return 0;
+
+  if (debug_threads)
+    fprintf (stderr,
+            "proceed_one_lwp: lwp %ld\n", lwpid_of (lwp));
+
+  if (!lwp->stopped)
+    {
+      if (debug_threads)
+       fprintf (stderr, "   LWP %ld already running\n", lwpid_of (lwp));
+      return 0;
+    }
+
+  thread = get_lwp_thread (lwp);
+
+  if (thread->last_resume_kind == resume_stop
+      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
+    {
+      if (debug_threads)
+       fprintf (stderr, "   client wants LWP to remain %ld stopped\n",
+                lwpid_of (lwp));
+      return 0;
+    }
+
+  if (lwp->status_pending_p)
+    {
+      if (debug_threads)
+       fprintf (stderr, "   LWP %ld has pending status, leaving stopped\n",
+                lwpid_of (lwp));
+      return 0;
+    }
+
+  gdb_assert (lwp->suspended >= 0);
+
+  if (lwp->suspended)
+    {
+      if (debug_threads)
+       fprintf (stderr, "   LWP %ld is suspended\n", lwpid_of (lwp));
+      return 0;
+    }
+
+  if (thread->last_resume_kind == resume_stop
+      && lwp->pending_signals_to_report == NULL
+      && lwp->collecting_fast_tracepoint == 0)
+    {
+      /* We haven't reported this LWP as stopped yet (otherwise, the
+        last_status.kind check above would catch it, and we wouldn't
+        reach here.  This LWP may have been momentarily paused by a
+        stop_all_lwps call while handling for example, another LWP's
+        step-over.  In that case, the pending expected SIGSTOP signal
+        that was queued at vCont;t handling time will have already
+        been consumed by wait_for_sigstop, and so we need to requeue
+        another one here.  Note that if the LWP already has a SIGSTOP
+        pending, this is a no-op.  */
+
+      if (debug_threads)
+       fprintf (stderr,
+                "Client wants LWP %ld to stop. "
+                "Making sure it has a SIGSTOP pending\n",
+                lwpid_of (lwp));
+
+      send_sigstop (lwp);
+    }
+
+  step = thread->last_resume_kind == resume_step;
+  linux_resume_one_lwp (lwp, step, 0, NULL);
+  return 0;
+}
+
+static int
+unsuspend_and_proceed_one_lwp (struct inferior_list_entry *entry, void *except)
+{
+  struct lwp_info *lwp = (struct lwp_info *) entry;
+
+  if (lwp == except)
+    return 0;
+
+  lwp->suspended--;
+  gdb_assert (lwp->suspended >= 0);
+
+  return proceed_one_lwp (entry, except);
+}
+
+/* When we finish a step-over, set threads running again.  If there's
+   another thread that may need a step-over, now's the time to start
+   it.  Eventually, we'll move all threads past their breakpoints.  */
+
+static void
+proceed_all_lwps (void)
+{
+  struct lwp_info *need_step_over;
+
+  /* If there is a thread which would otherwise be resumed, which is
+     stopped at a breakpoint that needs stepping over, then don't
+     resume any threads - have it step over the breakpoint with all
+     other threads stopped, then resume all threads again.  */
+
+  if (supports_breakpoints ())
+    {
+      need_step_over
+       = (struct lwp_info *) find_inferior (&all_lwps,
+                                            need_step_over_p, NULL);
+
+      if (need_step_over != NULL)
+       {
+         if (debug_threads)
+           fprintf (stderr, "proceed_all_lwps: found "
+                    "thread %ld needing a step-over\n",
+                    lwpid_of (need_step_over));
+
+         start_step_over (need_step_over);
+         return;
+       }
+    }
+
+  if (debug_threads)
+    fprintf (stderr, "Proceeding, no step-over needed\n");
+
+  find_inferior (&all_lwps, proceed_one_lwp, NULL);
+}
+
+/* Stopped LWPs that the client wanted to be running, that don't have
+   pending statuses, are set to run again, except for EXCEPT, if not
+   NULL.  This undoes a stop_all_lwps call.  */
+
+static void
+unstop_all_lwps (int unsuspend, struct lwp_info *except)
+{
+  if (debug_threads)
+    {
+      if (except)
+       fprintf (stderr,
+                "unstopping all lwps, except=(LWP %ld)\n", lwpid_of (except));
+      else
+       fprintf (stderr,
+                "unstopping all lwps\n");
+    }
+
+  if (unsuspend)
+    find_inferior (&all_lwps, unsuspend_and_proceed_one_lwp, except);
+  else
+    find_inferior (&all_lwps, proceed_one_lwp, except);
+}
+
+
+#ifdef HAVE_LINUX_REGSETS
+
+#define use_linux_regsets 1
+
+static int
+regsets_fetch_inferior_registers (struct regcache *regcache)
+{
+  struct regset_info *regset;
+  int saw_general_regs = 0;
+  int pid;
+  struct iovec iov;
+
+  regset = target_regsets;
+
+  pid = lwpid_of (get_thread_lwp (current_inferior));
+  while (regset->size >= 0)
+    {
+      void *buf, *data;
+      int nt_type, res;
+
+      if (regset->size == 0 || disabled_regsets[regset - target_regsets])
+       {
+         regset ++;
+         continue;
+       }
+
+      buf = xmalloc (regset->size);
+
+      nt_type = regset->nt_type;
+      if (nt_type)
+       {
+         iov.iov_base = buf;
+         iov.iov_len = regset->size;
+         data = (void *) &iov;
+       }
+      else
+       data = buf;
+
+#ifndef __sparc__
+      res = ptrace (regset->get_request, pid, nt_type, data);
+#else
+      res = ptrace (regset->get_request, pid, data, nt_type);
+#endif
+      if (res < 0)
+       {
+         if (errno == EIO)
+           {
+             /* If we get EIO on a regset, do not try it again for
+                this process.  */
+             disabled_regsets[regset - target_regsets] = 1;
+             free (buf);
+             continue;
+           }
+         else
+           {
+             char s[256];
+             sprintf (s, "ptrace(regsets_fetch_inferior_registers) PID=%d",
+                      pid);
+             perror (s);
+           }
+       }
+      else if (regset->type == GENERAL_REGS)
+       saw_general_regs = 1;
+      regset->store_function (regcache, buf);
+      regset ++;
+      free (buf);
+    }
+  if (saw_general_regs)
+    return 0;
+  else
+    return 1;
+}
+
+static int
+regsets_store_inferior_registers (struct regcache *regcache)
+{
+  struct regset_info *regset;
+  int saw_general_regs = 0;
+  int pid;
+  struct iovec iov;
+
+  regset = target_regsets;
+
+  pid = lwpid_of (get_thread_lwp (current_inferior));
+  while (regset->size >= 0)
+    {
+      void *buf, *data;
+      int nt_type, res;
+
+      if (regset->size == 0 || disabled_regsets[regset - target_regsets])
+       {
+         regset ++;
+         continue;
+       }
+
+      buf = xmalloc (regset->size);
+
+      /* First fill the buffer with the current register set contents,
+        in case there are any items in the kernel's regset that are
+        not in gdbserver's regcache.  */
+
+      nt_type = regset->nt_type;
+      if (nt_type)
+       {
+         iov.iov_base = buf;
+         iov.iov_len = regset->size;
+         data = (void *) &iov;
+       }
+      else
+       data = buf;
+
+#ifndef __sparc__
+      res = ptrace (regset->get_request, pid, nt_type, data);
+#else
+      res = ptrace (regset->get_request, pid, &iov, data);
+#endif
+
+      if (res == 0)
+       {
+         /* Then overlay our cached registers on that.  */
+         regset->fill_function (regcache, buf);
+
+         /* Only now do we write the register set.  */
+#ifndef __sparc__
+         res = ptrace (regset->set_request, pid, nt_type, data);
+#else
+         res = ptrace (regset->set_request, pid, data, nt_type);
+#endif
+       }
+
+      if (res < 0)
+       {
+         if (errno == EIO)
+           {
+             /* If we get EIO on a regset, do not try it again for
+                this process.  */
+             disabled_regsets[regset - target_regsets] = 1;
+             free (buf);
+             continue;
+           }
+         else if (errno == ESRCH)
+           {
+             /* At this point, ESRCH should mean the process is
+                already gone, in which case we simply ignore attempts
+                to change its registers.  See also the related
+                comment in linux_resume_one_lwp.  */
+             free (buf);
+             return 0;
+           }
+         else
+           {
+             perror ("Warning: ptrace(regsets_store_inferior_registers)");
+           }
+       }
+      else if (regset->type == GENERAL_REGS)
+       saw_general_regs = 1;
+      regset ++;
+      free (buf);
+    }
+  if (saw_general_regs)
+    return 0;
+  else
+    return 1;
+}
+
+#else /* !HAVE_LINUX_REGSETS */
+
+#define use_linux_regsets 0
+#define regsets_fetch_inferior_registers(regcache) 1
+#define regsets_store_inferior_registers(regcache) 1
+
+#endif
+
+/* Return 1 if register REGNO is supported by one of the regset ptrace
+   calls or 0 if it has to be transferred individually.  */
+
+static int
+linux_register_in_regsets (int regno)
+{
+  unsigned char mask = 1 << (regno % 8);
+  size_t index = regno / 8;
+
+  return (use_linux_regsets
+         && (the_low_target.regset_bitmap == NULL
+             || (the_low_target.regset_bitmap[index] & mask) != 0));
+}
+
+#ifdef HAVE_LINUX_USRREGS
+
+int
+register_addr (int regnum)
+{
+  int addr;
+
+  if (regnum < 0 || regnum >= the_low_target.num_regs)
+    error ("Invalid register number %d.", regnum);
+
+  addr = the_low_target.regmap[regnum];
+
+  return addr;
+}
+
+/* Fetch one register.  */
+static void
+fetch_register (struct regcache *regcache, int regno)
+{
+  CORE_ADDR regaddr;
+  int i, size;
+  char *buf;
+  int pid;
+
+  if (regno >= the_low_target.num_regs)
+    return;
+  if ((*the_low_target.cannot_fetch_register) (regno))
+    return;
+
+  regaddr = register_addr (regno);
+  if (regaddr == -1)
+    return;
+
+  size = ((register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1)
+         & -sizeof (PTRACE_XFER_TYPE));
+  buf = alloca (size);
+
+  pid = lwpid_of (get_thread_lwp (current_inferior));
+  for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
+    {
+      errno = 0;
+      *(PTRACE_XFER_TYPE *) (buf + i) =
+       ptrace (PTRACE_PEEKUSER, pid,
+               /* Coerce to a uintptr_t first to avoid potential gcc warning
+                  of coercing an 8 byte integer to a 4 byte pointer.  */
+               (PTRACE_ARG3_TYPE) (uintptr_t) regaddr, 0);
+      regaddr += sizeof (PTRACE_XFER_TYPE);
+      if (errno != 0)
+       error ("reading register %d: %s", regno, strerror (errno));
+    }
+
+  if (the_low_target.supply_ptrace_register)
+    the_low_target.supply_ptrace_register (regcache, regno, buf);
+  else
+    supply_register (regcache, regno, buf);
+}
+
+/* Store one register.  */
+static void
+store_register (struct regcache *regcache, int regno)
+{
+  CORE_ADDR regaddr;
+  int i, size;
+  char *buf;
+  int pid;
+
+  if (regno >= the_low_target.num_regs)
+    return;
+  if ((*the_low_target.cannot_store_register) (regno))
+    return;
+
+  regaddr = register_addr (regno);
+  if (regaddr == -1)
+    return;
+
+  size = ((register_size (regno) + sizeof (PTRACE_XFER_TYPE) - 1)
+         & -sizeof (PTRACE_XFER_TYPE));
+  buf = alloca (size);
+  memset (buf, 0, size);
+
+  if (the_low_target.collect_ptrace_register)
+    the_low_target.collect_ptrace_register (regcache, regno, buf);
+  else
+    collect_register (regcache, regno, buf);
+
+  pid = lwpid_of (get_thread_lwp (current_inferior));
+  for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
+    {
+      errno = 0;
+      ptrace (PTRACE_POKEUSER, pid,
+           /* Coerce to a uintptr_t first to avoid potential gcc warning
+              about coercing an 8 byte integer to a 4 byte pointer.  */
+             (PTRACE_ARG3_TYPE) (uintptr_t) regaddr,
+             (PTRACE_ARG4_TYPE) *(PTRACE_XFER_TYPE *) (buf + i));
+      if (errno != 0)
+       {
+         /* At this point, ESRCH should mean the process is
+            already gone, in which case we simply ignore attempts
+            to change its registers.  See also the related
+            comment in linux_resume_one_lwp.  */
+         if (errno == ESRCH)
+           return;
+
+         if ((*the_low_target.cannot_store_register) (regno) == 0)
+           error ("writing register %d: %s", regno, strerror (errno));
+       }
+      regaddr += sizeof (PTRACE_XFER_TYPE);
+    }
+}
+
+/* Fetch all registers, or just one, from the child process.
+   If REGNO is -1, do this for all registers, skipping any that are
+   assumed to have been retrieved by regsets_fetch_inferior_registers,
+   unless ALL is non-zero.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+static void
+usr_fetch_inferior_registers (struct regcache *regcache, int regno, int all)
+{
+  if (regno == -1)
+    {
+      for (regno = 0; regno < the_low_target.num_regs; regno++)
+       if (all || !linux_register_in_regsets (regno))
+         fetch_register (regcache, regno);
+    }
+  else
+    fetch_register (regcache, regno);
+}
+
+/* Store our register values back into the inferior.
+   If REGNO is -1, do this for all registers, skipping any that are
+   assumed to have been saved by regsets_store_inferior_registers,
+   unless ALL is non-zero.
+   Otherwise, REGNO specifies which register (so we can save time).  */
+static void
+usr_store_inferior_registers (struct regcache *regcache, int regno, int all)
+{
+  if (regno == -1)
+    {
+      for (regno = 0; regno < the_low_target.num_regs; regno++)
+       if (all || !linux_register_in_regsets (regno))
+         store_register (regcache, regno);
+    }
+  else
+    store_register (regcache, regno);
+}
+
+#else /* !HAVE_LINUX_USRREGS */
+
+#define usr_fetch_inferior_registers(regcache, regno, all) do {} while (0)
+#define usr_store_inferior_registers(regcache, regno, all) do {} while (0)
+
+#endif
+
+
+void
+linux_fetch_registers (struct regcache *regcache, int regno)
+{
+  int use_regsets;
+  int all = 0;
+
+  if (regno == -1)
+    {
+      all = regsets_fetch_inferior_registers (regcache);
+      usr_fetch_inferior_registers (regcache, regno, all);
+    }
+  else
+    {
+      use_regsets = linux_register_in_regsets (regno);
+      if (use_regsets)
+       all = regsets_fetch_inferior_registers (regcache);
+      if (!use_regsets || all)
+       usr_fetch_inferior_registers (regcache, regno, 1);
+    }
+}
+
+void
+linux_store_registers (struct regcache *regcache, int regno)
+{
+  int use_regsets;
+  int all = 0;
+
+  if (regno == -1)
+    {
+      all = regsets_store_inferior_registers (regcache);
+      usr_store_inferior_registers (regcache, regno, all);
+    }
+  else
+    {
+      use_regsets = linux_register_in_regsets (regno);
+      if (use_regsets)
+       all = regsets_store_inferior_registers (regcache);
+      if (!use_regsets || all)
+       usr_store_inferior_registers (regcache, regno, 1);
+    }
+}
+
+
+/* Copy LEN bytes from inferior's memory starting at MEMADDR
+   to debugger memory starting at MYADDR.  */
+
+static int
+linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+{
+  register int i;
+  /* Round starting address down to longword boundary.  */
+  register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
+  /* Round ending address up; get number of longwords that makes.  */
+  register int count
+    = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
+      / sizeof (PTRACE_XFER_TYPE);
+  /* Allocate buffer of that many longwords.  */
+  register PTRACE_XFER_TYPE *buffer
+    = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
+  int fd;
+  char filename[64];
+  int pid = lwpid_of (get_thread_lwp (current_inferior));
+
+  /* Try using /proc.  Don't bother for one word.  */
+  if (len >= 3 * sizeof (long))
+    {
+      /* We could keep this file open and cache it - possibly one per
+        thread.  That requires some juggling, but is even faster.  */
+      sprintf (filename, "/proc/%d/mem", pid);
+      fd = open (filename, O_RDONLY | O_LARGEFILE);
+      if (fd == -1)
+       goto no_proc;
+
+      /* If pread64 is available, use it.  It's faster if the kernel
+        supports it (only one syscall), and it's 64-bit safe even on
+        32-bit platforms (for instance, SPARC debugging a SPARC64
+        application).  */
+#ifdef HAVE_PREAD64
+      if (pread64 (fd, myaddr, len, memaddr) != len)
+#else
+      if (lseek (fd, memaddr, SEEK_SET) == -1 || read (fd, myaddr, len) != len)
+#endif
+       {
+         close (fd);
+         goto no_proc;
+       }
+
+      close (fd);
+      return 0;
+    }
+
+ no_proc:
+  /* Read all the longwords */
+  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
+    {
+      errno = 0;
+      /* Coerce the 3rd arg to a uintptr_t first to avoid potential gcc warning
+        about coercing an 8 byte integer to a 4 byte pointer.  */
+      buffer[i] = ptrace (PTRACE_PEEKTEXT, pid,
+                         (PTRACE_ARG3_TYPE) (uintptr_t) addr, 0);
+      if (errno)
+       return errno;
+    }
+
+  /* Copy appropriate bytes out of the buffer.  */
+  memcpy (myaddr,
+         (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
+         len);
+
+  return 0;
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
+   memory at MEMADDR.  On failure (cannot write to the inferior)
+   returns the value of errno.  */
+
+static int
+linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
+{
+  register int i;
+  /* Round starting address down to longword boundary.  */
+  register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
+  /* Round ending address up; get number of longwords that makes.  */
+  register int count
+    = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
+    / sizeof (PTRACE_XFER_TYPE);
+
+  /* Allocate buffer of that many longwords.  */
+  register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *)
+    alloca (count * sizeof (PTRACE_XFER_TYPE));
+
+  int pid = lwpid_of (get_thread_lwp (current_inferior));
+
+  if (debug_threads)
+    {
+      /* Dump up to four bytes.  */
+      unsigned int val = * (unsigned int *) myaddr;
+      if (len == 1)
+       val = val & 0xff;
+      else if (len == 2)
+       val = val & 0xffff;
+      else if (len == 3)
+       val = val & 0xffffff;
+      fprintf (stderr, "Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
+              val, (long)memaddr);
+    }
+
+  /* Fill start and end extra bytes of buffer with existing memory data.  */
+
+  errno = 0;
+  /* Coerce the 3rd arg to a uintptr_t first to avoid potential gcc warning
+     about coercing an 8 byte integer to a 4 byte pointer.  */
+  buffer[0] = ptrace (PTRACE_PEEKTEXT, pid,
+                     (PTRACE_ARG3_TYPE) (uintptr_t) addr, 0);
+  if (errno)
+    return errno;
+
+  if (count > 1)
+    {
+      errno = 0;
+      buffer[count - 1]
+       = ptrace (PTRACE_PEEKTEXT, pid,
+                 /* Coerce to a uintptr_t first to avoid potential gcc warning
+                    about coercing an 8 byte integer to a 4 byte pointer.  */
+                 (PTRACE_ARG3_TYPE) (uintptr_t) (addr + (count - 1)
+                                                 * sizeof (PTRACE_XFER_TYPE)),
+                 0);
+      if (errno)
+       return errno;
+    }
+
+  /* Copy data to be written over corresponding part of buffer.  */
+
+  memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
+         myaddr, len);
+
+  /* Write the entire buffer.  */
+
+  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
+    {
+      errno = 0;
+      ptrace (PTRACE_POKETEXT, pid,
+             /* Coerce to a uintptr_t first to avoid potential gcc warning
+                about coercing an 8 byte integer to a 4 byte pointer.  */
+             (PTRACE_ARG3_TYPE) (uintptr_t) addr,
+             (PTRACE_ARG4_TYPE) buffer[i]);
+      if (errno)
+       return errno;
+    }
+
+  return 0;
+}
+
+/* Non-zero if the kernel supports PTRACE_O_TRACEFORK.  */
+static int linux_supports_tracefork_flag;
+
+static void
+linux_enable_event_reporting (int pid)
+{
+  if (!linux_supports_tracefork_flag)
+    return;
+
+  ptrace (PTRACE_SETOPTIONS, pid, 0, (PTRACE_ARG4_TYPE) PTRACE_O_TRACECLONE);
+}
+
+/* Helper functions for linux_test_for_tracefork, called via clone ().  */
+
+static int
+linux_tracefork_grandchild (void *arg)
+{
+  _exit (0);
+}
+
+#define STACK_SIZE 4096
+
+static int
+linux_tracefork_child (void *arg)
+{
+  ptrace (PTRACE_TRACEME, 0, 0, 0);
+  kill (getpid (), SIGSTOP);
+
+#if !(defined(__UCLIBC__) && defined(HAS_NOMMU))
+
+  if (fork () == 0)
+    linux_tracefork_grandchild (NULL);
+
+#else /* defined(__UCLIBC__) && defined(HAS_NOMMU) */
+
+#ifdef __ia64__
+  __clone2 (linux_tracefork_grandchild, arg, STACK_SIZE,
+           CLONE_VM | SIGCHLD, NULL);
+#else
+  clone (linux_tracefork_grandchild, (char *) arg + STACK_SIZE,
+        CLONE_VM | SIGCHLD, NULL);
+#endif
+
+#endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */
+
+  _exit (0);
+}
+
+/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events.  Make
+   sure that we can enable the option, and that it had the desired
+   effect.  */
+
+static void
+linux_test_for_tracefork (void)
+{
+  int child_pid, ret, status;
+  long second_pid;
+#if defined(__UCLIBC__) && defined(HAS_NOMMU)
+  char *stack = xmalloc (STACK_SIZE * 4);
+#endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */
+
+  linux_supports_tracefork_flag = 0;
+
+#if !(defined(__UCLIBC__) && defined(HAS_NOMMU))
+
+  child_pid = fork ();
+  if (child_pid == 0)
+    linux_tracefork_child (NULL);
+
+#else /* defined(__UCLIBC__) && defined(HAS_NOMMU) */
+
+  /* Use CLONE_VM instead of fork, to support uClinux (no MMU).  */
+#ifdef __ia64__
+  child_pid = __clone2 (linux_tracefork_child, stack, STACK_SIZE,
+                       CLONE_VM | SIGCHLD, stack + STACK_SIZE * 2);
+#else /* !__ia64__ */
+  child_pid = clone (linux_tracefork_child, stack + STACK_SIZE,
+                    CLONE_VM | SIGCHLD, stack + STACK_SIZE * 2);
+#endif /* !__ia64__ */
+
+#endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */
+
+  if (child_pid == -1)
+    perror_with_name ("clone");
+
+  ret = my_waitpid (child_pid, &status, 0);
+  if (ret == -1)
+    perror_with_name ("waitpid");
+  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);
+
+  ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0,
+               (PTRACE_ARG4_TYPE) PTRACE_O_TRACEFORK);
+  if (ret != 0)
+    {
+      ret = ptrace (PTRACE_KILL, child_pid, 0, 0);
+      if (ret != 0)
+       {
+         warning ("linux_test_for_tracefork: failed to kill child");
+         return;
+       }
+
+      ret = my_waitpid (child_pid, &status, 0);
+      if (ret != child_pid)
+       warning ("linux_test_for_tracefork: failed to wait for killed child");
+      else if (!WIFSIGNALED (status))
+       warning ("linux_test_for_tracefork: unexpected wait status 0x%x from "
+                "killed child", status);
+
+      return;
+    }
+
+  ret = ptrace (PTRACE_CONT, child_pid, 0, 0);
+  if (ret != 0)
+    warning ("linux_test_for_tracefork: failed to resume child");
+
+  ret = my_waitpid (child_pid, &status, 0);
+
+  if (ret == child_pid && WIFSTOPPED (status)
+      && status >> 16 == PTRACE_EVENT_FORK)
+    {
+      second_pid = 0;
+      ret = ptrace (PTRACE_GETEVENTMSG, child_pid, 0, &second_pid);
+      if (ret == 0 && second_pid != 0)
+       {
+         int second_status;
+
+         linux_supports_tracefork_flag = 1;
+         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");
+         my_waitpid (second_pid, &status, 0);
+       }
+    }
+  else
+    warning ("linux_test_for_tracefork: unexpected result from waitpid "
+            "(%d, status 0x%x)", ret, status);
+
+  do
+    {
+      ret = ptrace (PTRACE_KILL, child_pid, 0, 0);
+      if (ret != 0)
+       warning ("linux_test_for_tracefork: failed to kill child");
+      my_waitpid (child_pid, &status, 0);
+    }
+  while (WIFSTOPPED (status));
+
+#if defined(__UCLIBC__) && defined(HAS_NOMMU)
+  free (stack);
+#endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */
+}
+
+
+static void
+linux_look_up_symbols (void)
+{
+#ifdef USE_THREAD_DB
+  struct process_info *proc = current_process ();
+
+  if (proc->private->thread_db != NULL)
+    return;
+
+  /* If the kernel supports tracing forks then it also supports tracing
+     clones, and then we don't need to use the magic thread event breakpoint
+     to learn about threads.  */
+  thread_db_init (!linux_supports_tracefork_flag);
+#endif
+}
+
+static void
+linux_request_interrupt (void)
+{
+  extern unsigned long signal_pid;
+
+  if (!ptid_equal (cont_thread, null_ptid)
+      && !ptid_equal (cont_thread, minus_one_ptid))
+    {
+      struct lwp_info *lwp;
+      int lwpid;
+
+      lwp = get_thread_lwp (current_inferior);
+      lwpid = lwpid_of (lwp);
+      kill_lwp (lwpid, SIGINT);
+    }
+  else
+    kill_lwp (signal_pid, SIGINT);
+}
+
+/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
+   to debugger memory starting at MYADDR.  */
+
+static int
+linux_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
+{
+  char filename[PATH_MAX];
+  int fd, n;
+  int pid = lwpid_of (get_thread_lwp (current_inferior));
+
+  xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid);
+
+  fd = open (filename, O_RDONLY);
+  if (fd < 0)
+    return -1;
+
+  if (offset != (CORE_ADDR) 0
+      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
+    n = -1;
+  else
+    n = read (fd, myaddr, len);
+
+  close (fd);
+
+  return n;
+}
+
+/* These breakpoint and watchpoint related wrapper functions simply
+   pass on the function call if the target has registered a
+   corresponding function.  */
+
+static int
+linux_insert_point (char type, CORE_ADDR addr, int len)
+{
+  if (the_low_target.insert_point != NULL)
+    return the_low_target.insert_point (type, addr, len);
+  else
+    /* Unsupported (see target.h).  */
+    return 1;
+}
+
+static int
+linux_remove_point (char type, CORE_ADDR addr, int len)
+{
+  if (the_low_target.remove_point != NULL)
+    return the_low_target.remove_point (type, addr, len);
+  else
+    /* Unsupported (see target.h).  */
+    return 1;
+}
+
+static int
+linux_stopped_by_watchpoint (void)
+{
+  struct lwp_info *lwp = get_thread_lwp (current_inferior);
+
+  return lwp->stopped_by_watchpoint;
+}
+
+static CORE_ADDR
+linux_stopped_data_address (void)
+{
+  struct lwp_info *lwp = get_thread_lwp (current_inferior);
+
+  return lwp->stopped_data_address;
+}
+
+#if defined(__UCLIBC__) && defined(HAS_NOMMU)
+#if defined(__mcoldfire__)
+/* These should really be defined in the kernel's ptrace.h header.  */
+#define PT_TEXT_ADDR 49*4
+#define PT_DATA_ADDR 50*4
+#define PT_TEXT_END_ADDR  51*4
+#elif defined(BFIN)
+#define PT_TEXT_ADDR 220
+#define PT_TEXT_END_ADDR 224
+#define PT_DATA_ADDR 228
+#elif defined(__TMS320C6X__)
+#define PT_TEXT_ADDR     (0x10000*4)
+#define PT_DATA_ADDR     (0x10004*4)
+#define PT_TEXT_END_ADDR (0x10008*4)
+#endif
+
+/* Under uClinux, programs are loaded at non-zero offsets, which we need
+   to tell gdb about.  */
+
+static int
+linux_read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p)
+{
+#if defined(PT_TEXT_ADDR) && defined(PT_DATA_ADDR) && defined(PT_TEXT_END_ADDR)
+  unsigned long text, text_end, data;
+  int pid = lwpid_of (get_thread_lwp (current_inferior));
+
+  errno = 0;
+
+  text = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_ADDR, 0);
+  text_end = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_END_ADDR, 0);
+  data = ptrace (PTRACE_PEEKUSER, pid, (long)PT_DATA_ADDR, 0);
+
+  if (errno == 0)
+    {
+      /* Both text and data offsets produced at compile-time (and so
+        used by gdb) are relative to the beginning of the program,
+        with the data segment immediately following the text segment.
+        However, the actual runtime layout in memory may put the data
+        somewhere else, so when we send gdb a data base-address, we
+        use the real data base address and subtract the compile-time
+        data base-address from it (which is just the length of the
+        text segment).  BSS immediately follows data in both
+        cases.  */
+      *text_p = text;
+      *data_p = data - (text_end - text);
+
+      return 1;
+    }
+#endif
+ return 0;
+}
+#endif
+
+static int
+linux_qxfer_osdata (const char *annex,
+                   unsigned char *readbuf, unsigned const char *writebuf,
+                   CORE_ADDR offset, int len)
+{
+  return linux_common_xfer_osdata (annex, readbuf, offset, len);
+}
+
+/* Convert a native/host siginfo object, into/from the siginfo in the
+   layout of the inferiors' architecture.  */
+
+static void
+siginfo_fixup (struct siginfo *siginfo, void *inf_siginfo, int direction)
+{
+  int done = 0;
+
+  if (the_low_target.siginfo_fixup != NULL)
+    done = the_low_target.siginfo_fixup (siginfo, inf_siginfo, direction);
+
+  /* If there was no callback, or the callback didn't do anything,
+     then just do a straight memcpy.  */
+  if (!done)
+    {
+      if (direction == 1)
+       memcpy (siginfo, inf_siginfo, sizeof (struct siginfo));
+      else
+       memcpy (inf_siginfo, siginfo, sizeof (struct siginfo));
+    }
+}
+
+static int
+linux_xfer_siginfo (const char *annex, unsigned char *readbuf,
+                   unsigned const char *writebuf, CORE_ADDR offset, int len)
+{
+  int pid;
+  struct siginfo siginfo;
+  char inf_siginfo[sizeof (struct siginfo)];
+
+  if (current_inferior == NULL)
+    return -1;
+
+  pid = lwpid_of (get_thread_lwp (current_inferior));
+
+  if (debug_threads)
+    fprintf (stderr, "%s siginfo for lwp %d.\n",
+            readbuf != NULL ? "Reading" : "Writing",
+            pid);
+
+  if (offset >= sizeof (siginfo))
+    return -1;
+
+  if (ptrace (PTRACE_GETSIGINFO, pid, 0, &siginfo) != 0)
+    return -1;
+
+  /* When GDBSERVER is built as a 64-bit application, ptrace writes into
+     SIGINFO an object with 64-bit layout.  Since debugging a 32-bit
+     inferior with a 64-bit GDBSERVER should look the same as debugging it
+     with a 32-bit GDBSERVER, we need to convert it.  */
+  siginfo_fixup (&siginfo, inf_siginfo, 0);
+
+  if (offset + len > sizeof (siginfo))
+    len = sizeof (siginfo) - offset;
+
+  if (readbuf != NULL)
+    memcpy (readbuf, inf_siginfo + offset, len);
+  else
+    {
+      memcpy (inf_siginfo + offset, writebuf, len);
+
+      /* Convert back to ptrace layout before flushing it out.  */
+      siginfo_fixup (&siginfo, inf_siginfo, 1);
+
+      if (ptrace (PTRACE_SETSIGINFO, pid, 0, &siginfo) != 0)
+       return -1;
+    }
+
+  return len;
+}
+
+/* SIGCHLD handler that serves two purposes: In non-stop/async mode,
+   so we notice when children change state; as the handler for the
+   sigsuspend in my_waitpid.  */
+
+static void
+sigchld_handler (int signo)
+{
+  int old_errno = errno;
+
+  if (debug_threads)
+    {
+      do
+       {
+         /* fprintf is not async-signal-safe, so call write
+            directly.  */
+         if (write (2, "sigchld_handler\n",
+                    sizeof ("sigchld_handler\n") - 1) < 0)
+           break; /* just ignore */
+       } while (0);
+    }
+
+  if (target_is_async_p ())
+    async_file_mark (); /* trigger a linux_wait */
+
+  errno = old_errno;
+}
+
+static int
+linux_supports_non_stop (void)
+{
+  return 1;
+}
+
+static int
+linux_async (int enable)
+{
+  int previous = (linux_event_pipe[0] != -1);
+
+  if (debug_threads)
+    fprintf (stderr, "linux_async (%d), previous=%d\n",
+            enable, previous);
+
+  if (previous != enable)
+    {
+      sigset_t mask;
+      sigemptyset (&mask);
+      sigaddset (&mask, SIGCHLD);
+
+      sigprocmask (SIG_BLOCK, &mask, NULL);
+
+      if (enable)
+       {
+         if (pipe (linux_event_pipe) == -1)
+           fatal ("creating event pipe failed.");
 
-  if (count > 1)
-    {
-      buffer[count - 1]
-       = ptrace (PTRACE_PEEKTEXT, inferior_pid,
-                 (PTRACE_ARG3_TYPE) (addr + (count - 1)
-                                     * sizeof (PTRACE_XFER_TYPE)),
-                 0);
-    }
+         fcntl (linux_event_pipe[0], F_SETFL, O_NONBLOCK);
+         fcntl (linux_event_pipe[1], F_SETFL, O_NONBLOCK);
 
-  /* Copy data to be written over corresponding part of buffer */
+         /* Register the event loop handler.  */
+         add_file_handler (linux_event_pipe[0],
+                           handle_target_event, NULL);
 
-  memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
+         /* Always trigger a linux_wait.  */
+         async_file_mark ();
+       }
+      else
+       {
+         delete_file_handler (linux_event_pipe[0]);
 
-  /* Write the entire buffer.  */
+         close (linux_event_pipe[0]);
+         close (linux_event_pipe[1]);
+         linux_event_pipe[0] = -1;
+         linux_event_pipe[1] = -1;
+       }
 
-  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
-    {
-      errno = 0;
-      ptrace (PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
-      if (errno)
-       return errno;
+      sigprocmask (SIG_UNBLOCK, &mask, NULL);
     }
 
-  return 0;
+  return previous;
 }
 
-static int linux_supports_tracefork_flag;
-
-/* Helper functions for linux_test_for_tracefork, called via clone ().  */
-
 static int
-linux_tracefork_grandchild (void *arg)
+linux_start_non_stop (int nonstop)
 {
-  _exit (0);
+  /* Register or unregister from event-loop accordingly.  */
+  linux_async (nonstop);
+  return 0;
 }
 
-#define STACK_SIZE 4096
+static int
+linux_supports_multi_process (void)
+{
+  return 1;
+}
 
 static int
-linux_tracefork_child (void *arg)
+linux_supports_disable_randomization (void)
 {
-  ptrace (PTRACE_TRACEME, 0, 0, 0);
-  kill (getpid (), SIGSTOP);
-#ifdef __ia64__
-  __clone2 (linux_tracefork_grandchild, arg, STACK_SIZE,
-           CLONE_VM | SIGCHLD, NULL);
+#ifdef HAVE_PERSONALITY
+  return 1;
 #else
-  clone (linux_tracefork_grandchild, arg + STACK_SIZE,
-        CLONE_VM | SIGCHLD, NULL);
+  return 0;
 #endif
-  _exit (0);
 }
 
-/* Wrapper function for waitpid which handles EINTR, and emulates
-   __WALL for systems where that is not available.  */
-
 static int
-my_waitpid (int pid, int *status, int flags)
+linux_supports_agent (void)
 {
-  int ret, out_errno;
+  return 1;
+}
 
-  if (debug_threads)
-    fprintf (stderr, "my_waitpid (%d, 0x%x)\n", pid, flags);
+/* Enumerate spufs IDs for process PID.  */
+static int
+spu_enumerate_spu_ids (long pid, unsigned char *buf, CORE_ADDR offset, int len)
+{
+  int pos = 0;
+  int written = 0;
+  char path[128];
+  DIR *dir;
+  struct dirent *entry;
+
+  sprintf (path, "/proc/%ld/fd", pid);
+  dir = opendir (path);
+  if (!dir)
+    return -1;
 
-  if (flags & __WALL)
+  rewinddir (dir);
+  while ((entry = readdir (dir)) != NULL)
     {
-      sigset_t block_mask, org_mask, wake_mask;
-      int wnohang;
-
-      wnohang = (flags & WNOHANG) != 0;
-      flags &= ~(__WALL | __WCLONE);
-      flags |= WNOHANG;
-
-      /* Block all signals while here.  This avoids knowing about
-        LinuxThread's signals.  */
-      sigfillset (&block_mask);
-      sigprocmask (SIG_BLOCK, &block_mask, &org_mask);
-
-      /* ... except during the sigsuspend below.  */
-      sigemptyset (&wake_mask);
-
-      while (1)
-       {
-         /* Since all signals are blocked, there's no need to check
-            for EINTR here.  */
-         ret = waitpid (pid, status, flags);
-         out_errno = errno;
+      struct stat st;
+      struct statfs stfs;
+      int fd;
+
+      fd = atoi (entry->d_name);
+      if (!fd)
+        continue;
+
+      sprintf (path, "/proc/%ld/fd/%d", pid, fd);
+      if (stat (path, &st) != 0)
+        continue;
+      if (!S_ISDIR (st.st_mode))
+        continue;
+
+      if (statfs (path, &stfs) != 0)
+        continue;
+      if (stfs.f_type != SPUFS_MAGIC)
+        continue;
+
+      if (pos >= offset && pos + 4 <= offset + len)
+        {
+          *(unsigned int *)(buf + pos - offset) = fd;
+          written += 4;
+        }
+      pos += 4;
+    }
 
-         if (ret == -1 && out_errno != ECHILD)
-           break;
-         else if (ret > 0)
-           break;
+  closedir (dir);
+  return written;
+}
 
-         if (flags & __WCLONE)
-           {
-             /* We've tried both flavors now.  If WNOHANG is set,
-                there's nothing else to do, just bail out.  */
-             if (wnohang)
-               break;
+/* Implements the to_xfer_partial interface for the TARGET_OBJECT_SPU
+   object type, using the /proc file system.  */
+static int
+linux_qxfer_spu (const char *annex, unsigned char *readbuf,
+                unsigned const char *writebuf,
+                CORE_ADDR offset, int len)
+{
+  long pid = lwpid_of (get_thread_lwp (current_inferior));
+  char buf[128];
+  int fd = 0;
+  int ret = 0;
 
-             if (debug_threads)
-               fprintf (stderr, "blocking\n");
+  if (!writebuf && !readbuf)
+    return -1;
 
-             /* Block waiting for signals.  */
-             sigsuspend (&wake_mask);
-           }
+  if (!*annex)
+    {
+      if (!readbuf)
+       return -1;
+      else
+       return spu_enumerate_spu_ids (pid, readbuf, offset, len);
+    }
 
-         flags ^= __WCLONE;
-       }
+  sprintf (buf, "/proc/%ld/fd/%s", pid, annex);
+  fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
+  if (fd <= 0)
+    return -1;
 
-      sigprocmask (SIG_SETMASK, &org_mask, NULL);
-    }
-  else
+  if (offset != 0
+      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
     {
-      do
-       ret = waitpid (pid, status, flags);
-      while (ret == -1 && errno == EINTR);
-      out_errno = errno;
+      close (fd);
+      return 0;
     }
 
-  if (debug_threads)
-    fprintf (stderr, "my_waitpid (%d, 0x%x): status(%x), %d\n",
-            pid, flags, status ? *status : -1, ret);
+  if (writebuf)
+    ret = write (fd, writebuf, (size_t) len);
+  else
+    ret = read (fd, readbuf, (size_t) len);
 
-  errno = out_errno;
+  close (fd);
   return ret;
 }
 
-/* Determine if PTRACE_O_TRACEFORK can be used to follow fork events.  Make
-   sure that we can enable the option, and that it had the desired
-   effect.  */
-
-static void
-linux_test_for_tracefork (void)
+#if defined PT_GETDSBT || defined PTRACE_GETFDPIC
+struct target_loadseg
 {
-  int child_pid, ret, status;
-  long second_pid;
-  char *stack = xmalloc (STACK_SIZE * 4);
-
-  linux_supports_tracefork_flag = 0;
-
-  /* Use CLONE_VM instead of fork, to support uClinux (no MMU).  */
-#ifdef __ia64__
-  child_pid = __clone2 (linux_tracefork_child, stack, STACK_SIZE,
-                       CLONE_VM | SIGCHLD, stack + STACK_SIZE * 2);
-#else
-  child_pid = clone (linux_tracefork_child, stack + STACK_SIZE,
-                    CLONE_VM | SIGCHLD, stack + STACK_SIZE * 2);
-#endif
-  if (child_pid == -1)
-    perror_with_name ("clone");
+  /* Core address to which the segment is mapped.  */
+  Elf32_Addr addr;
+  /* VMA recorded in the program header.  */
+  Elf32_Addr p_vaddr;
+  /* Size of this segment in memory.  */
+  Elf32_Word p_memsz;
+};
 
-  ret = my_waitpid (child_pid, &status, 0);
-  if (ret == -1)
-    perror_with_name ("waitpid");
-  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);
+# if defined PT_GETDSBT
+struct target_loadmap
+{
+  /* Protocol version number, must be zero.  */
+  Elf32_Word version;
+  /* Pointer to the DSBT table, its size, and the DSBT index.  */
+  unsigned *dsbt_table;
+  unsigned dsbt_size, dsbt_index;
+  /* Number of segments in this map.  */
+  Elf32_Word nsegs;
+  /* The actual memory map.  */
+  struct target_loadseg segs[/*nsegs*/];
+};
+#  define LINUX_LOADMAP                PT_GETDSBT
+#  define LINUX_LOADMAP_EXEC   PTRACE_GETDSBT_EXEC
+#  define LINUX_LOADMAP_INTERP PTRACE_GETDSBT_INTERP
+# else
+struct target_loadmap
+{
+  /* Protocol version number, must be zero.  */
+  Elf32_Half version;
+  /* Number of segments in this map.  */
+  Elf32_Half nsegs;
+  /* The actual memory map.  */
+  struct target_loadseg segs[/*nsegs*/];
+};
+#  define LINUX_LOADMAP                PTRACE_GETFDPIC
+#  define LINUX_LOADMAP_EXEC   PTRACE_GETFDPIC_EXEC
+#  define LINUX_LOADMAP_INTERP PTRACE_GETFDPIC_INTERP
+# endif
 
-  ret = ptrace (PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACEFORK);
-  if (ret != 0)
-    {
-      ret = ptrace (PTRACE_KILL, child_pid, 0, 0);
-      if (ret != 0)
-       {
-         warning ("linux_test_for_tracefork: failed to kill child");
-         return;
-       }
+static int
+linux_read_loadmap (const char *annex, CORE_ADDR offset,
+                   unsigned char *myaddr, unsigned int len)
+{
+  int pid = lwpid_of (get_thread_lwp (current_inferior));
+  int addr = -1;
+  struct target_loadmap *data = NULL;
+  unsigned int actual_length, copy_length;
+
+  if (strcmp (annex, "exec") == 0)
+    addr = (int) LINUX_LOADMAP_EXEC;
+  else if (strcmp (annex, "interp") == 0)
+    addr = (int) LINUX_LOADMAP_INTERP;
+  else
+    return -1;
 
-      ret = my_waitpid (child_pid, &status, 0);
-      if (ret != child_pid)
-       warning ("linux_test_for_tracefork: failed to wait for killed child");
-      else if (!WIFSIGNALED (status))
-       warning ("linux_test_for_tracefork: unexpected wait status 0x%x from "
-                "killed child", status);
+  if (ptrace (LINUX_LOADMAP, pid, addr, &data) != 0)
+    return -1;
 
-      return;
-    }
+  if (data == NULL)
+    return -1;
 
-  ret = ptrace (PTRACE_CONT, child_pid, 0, 0);
-  if (ret != 0)
-    warning ("linux_test_for_tracefork: failed to resume child");
+  actual_length = sizeof (struct target_loadmap)
+    + sizeof (struct target_loadseg) * data->nsegs;
 
-  ret = my_waitpid (child_pid, &status, 0);
+  if (offset < 0 || offset > actual_length)
+    return -1;
 
-  if (ret == child_pid && WIFSTOPPED (status)
-      && status >> 16 == PTRACE_EVENT_FORK)
-    {
-      second_pid = 0;
-      ret = ptrace (PTRACE_GETEVENTMSG, child_pid, 0, &second_pid);
-      if (ret == 0 && second_pid != 0)
-       {
-         int second_status;
+  copy_length = actual_length - offset < len ? actual_length - offset : len;
+  memcpy (myaddr, (char *) data + offset, copy_length);
+  return copy_length;
+}
+#else
+# define linux_read_loadmap NULL
+#endif /* defined PT_GETDSBT || defined PTRACE_GETFDPIC */
 
-         linux_supports_tracefork_flag = 1;
-         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");
-         my_waitpid (second_pid, &status, 0);
-       }
-    }
-  else
-    warning ("linux_test_for_tracefork: unexpected result from waitpid "
-            "(%d, status 0x%x)", ret, status);
+static void
+linux_process_qsupported (const char *query)
+{
+  if (the_low_target.process_qsupported != NULL)
+    the_low_target.process_qsupported (query);
+}
 
-  do
-    {
-      ret = ptrace (PTRACE_KILL, child_pid, 0, 0);
-      if (ret != 0)
-       warning ("linux_test_for_tracefork: failed to kill child");
-      my_waitpid (child_pid, &status, 0);
-    }
-  while (WIFSTOPPED (status));
+static int
+linux_supports_tracepoints (void)
+{
+  if (*the_low_target.supports_tracepoints == NULL)
+    return 0;
 
-  free (stack);
+  return (*the_low_target.supports_tracepoints) ();
 }
 
-
-static void
-linux_look_up_symbols (void)
+static CORE_ADDR
+linux_read_pc (struct regcache *regcache)
 {
-#ifdef USE_THREAD_DB
-  if (thread_db_active)
-    return;
+  if (the_low_target.get_pc == NULL)
+    return 0;
 
-  thread_db_active = thread_db_init (!linux_supports_tracefork_flag);
-#endif
+  return (*the_low_target.get_pc) (regcache);
 }
 
 static void
-linux_request_interrupt (void)
+linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  extern unsigned long signal_pid;
-
-  if (cont_thread != 0 && cont_thread != -1)
-    {
-      struct lwp_info *lwp;
-      int lwpid;
-
-      lwp = get_thread_lwp (current_inferior);
-      lwpid = lwpid_of (lwp);
-      kill_lwp (lwpid, SIGINT);
-    }
-  else
-    kill_lwp (signal_pid, SIGINT);
-}
+  gdb_assert (the_low_target.set_pc != NULL);
 
-/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
-   to debugger memory starting at MYADDR.  */
+  (*the_low_target.set_pc) (regcache, pc);
+}
 
 static int
-linux_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
+linux_thread_stopped (struct thread_info *thread)
 {
-  char filename[PATH_MAX];
-  int fd, n;
-
-  snprintf (filename, sizeof filename, "/proc/%ld/auxv", inferior_pid);
+  return get_thread_lwp (thread)->stopped;
+}
 
-  fd = open (filename, O_RDONLY);
-  if (fd < 0)
-    return -1;
+/* This exposes stop-all-threads functionality to other modules.  */
 
-  if (offset != (CORE_ADDR) 0
-      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
-    n = -1;
-  else
-    n = read (fd, myaddr, len);
+static void
+linux_pause_all (int freeze)
+{
+  stop_all_lwps (freeze, NULL);
+}
 
-  close (fd);
+/* This exposes unstop-all-threads functionality to other gdbserver
+   modules.  */
 
-  return n;
+static void
+linux_unpause_all (int unfreeze)
+{
+  unstop_all_lwps (unfreeze, NULL);
 }
 
-/* These watchpoint related wrapper functions simply pass on the function call
-   if the target has registered a corresponding function.  */
-
 static int
-linux_insert_watchpoint (char type, CORE_ADDR addr, int len)
+linux_prepare_to_access_memory (void)
 {
-  if (the_low_target.insert_watchpoint != NULL)
-    return the_low_target.insert_watchpoint (type, addr, len);
-  else
-    /* Unsupported (see target.h).  */
-    return 1;
+  /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
+     running LWP.  */
+  if (non_stop)
+    linux_pause_all (1);
+  return 0;
 }
 
-static int
-linux_remove_watchpoint (char type, CORE_ADDR addr, int len)
+static void
+linux_done_accessing_memory (void)
 {
-  if (the_low_target.remove_watchpoint != NULL)
-    return the_low_target.remove_watchpoint (type, addr, len);
-  else
-    /* Unsupported (see target.h).  */
-    return 1;
+  /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
+     running LWP.  */
+  if (non_stop)
+    linux_unpause_all (1);
 }
 
 static int
-linux_stopped_by_watchpoint (void)
+linux_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint, CORE_ADDR tpaddr,
+                                       CORE_ADDR collector,
+                                       CORE_ADDR lockaddr,
+                                       ULONGEST orig_size,
+                                       CORE_ADDR *jump_entry,
+                                       CORE_ADDR *trampoline,
+                                       ULONGEST *trampoline_size,
+                                       unsigned char *jjump_pad_insn,
+                                       ULONGEST *jjump_pad_insn_size,
+                                       CORE_ADDR *adjusted_insn_addr,
+                                       CORE_ADDR *adjusted_insn_addr_end,
+                                       char *err)
 {
-  if (the_low_target.stopped_by_watchpoint != NULL)
-    return the_low_target.stopped_by_watchpoint ();
-  else
-    return 0;
+  return (*the_low_target.install_fast_tracepoint_jump_pad)
+    (tpoint, tpaddr, collector, lockaddr, orig_size,
+     jump_entry, trampoline, trampoline_size,
+     jjump_pad_insn, jjump_pad_insn_size,
+     adjusted_insn_addr, adjusted_insn_addr_end,
+     err);
 }
 
-static CORE_ADDR
-linux_stopped_data_address (void)
+static struct emit_ops *
+linux_emit_ops (void)
 {
-  if (the_low_target.stopped_data_address != NULL)
-    return the_low_target.stopped_data_address ();
+  if (the_low_target.emit_ops != NULL)
+    return (*the_low_target.emit_ops) ();
   else
-    return 0;
+    return NULL;
 }
 
-#if defined(__UCLIBC__) && defined(HAS_NOMMU)
-#if defined(__mcoldfire__)
-/* These should really be defined in the kernel's ptrace.h header.  */
-#define PT_TEXT_ADDR 49*4
-#define PT_DATA_ADDR 50*4
-#define PT_TEXT_END_ADDR  51*4
-#endif
+static int
+linux_get_min_fast_tracepoint_insn_len (void)
+{
+  return (*the_low_target.get_min_fast_tracepoint_insn_len) ();
+}
 
-/* Under uClinux, programs are loaded at non-zero offsets, which we need
-   to tell gdb about.  */
+/* Extract &phdr and num_phdr in the inferior.  Return 0 on success.  */
 
 static int
-linux_read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p)
+get_phdr_phnum_from_proc_auxv (const int pid, const int is_elf64,
+                              CORE_ADDR *phdr_memaddr, int *num_phdr)
 {
-#if defined(PT_TEXT_ADDR) && defined(PT_DATA_ADDR) && defined(PT_TEXT_END_ADDR)
-  unsigned long text, text_end, data;
-  int pid = lwpid_of (get_thread_lwp (current_inferior));
+  char filename[PATH_MAX];
+  int fd;
+  const int auxv_size = is_elf64
+    ? sizeof (Elf64_auxv_t) : sizeof (Elf32_auxv_t);
+  char buf[sizeof (Elf64_auxv_t)];  /* The larger of the two.  */
 
-  errno = 0;
+  xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid);
 
-  text = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_ADDR, 0);
-  text_end = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_END_ADDR, 0);
-  data = ptrace (PTRACE_PEEKUSER, pid, (long)PT_DATA_ADDR, 0);
+  fd = open (filename, O_RDONLY);
+  if (fd < 0)
+    return 1;
 
-  if (errno == 0)
+  *phdr_memaddr = 0;
+  *num_phdr = 0;
+  while (read (fd, buf, auxv_size) == auxv_size
+        && (*phdr_memaddr == 0 || *num_phdr == 0))
     {
-      /* Both text and data offsets produced at compile-time (and so
-        used by gdb) are relative to the beginning of the program,
-        with the data segment immediately following the text segment.
-        However, the actual runtime layout in memory may put the data
-        somewhere else, so when we send gdb a data base-address, we
-        use the real data base address and subtract the compile-time
-        data base-address from it (which is just the length of the
-        text segment).  BSS immediately follows data in both
-        cases.  */
-      *text_p = text;
-      *data_p = data - (text_end - text);
+      if (is_elf64)
+       {
+         Elf64_auxv_t *const aux = (Elf64_auxv_t *) buf;
 
-      return 1;
+         switch (aux->a_type)
+           {
+           case AT_PHDR:
+             *phdr_memaddr = aux->a_un.a_val;
+             break;
+           case AT_PHNUM:
+             *num_phdr = aux->a_un.a_val;
+             break;
+           }
+       }
+      else
+       {
+         Elf32_auxv_t *const aux = (Elf32_auxv_t *) buf;
+
+         switch (aux->a_type)
+           {
+           case AT_PHDR:
+             *phdr_memaddr = aux->a_un.a_val;
+             break;
+           case AT_PHNUM:
+             *num_phdr = aux->a_un.a_val;
+             break;
+           }
+       }
     }
-#endif
- return 0;
+
+  close (fd);
+
+  if (*phdr_memaddr == 0 || *num_phdr == 0)
+    {
+      warning ("Unexpected missing AT_PHDR and/or AT_PHNUM: "
+              "phdr_memaddr = %ld, phdr_num = %d",
+              (long) *phdr_memaddr, *num_phdr);
+      return 2;
+    }
+
+  return 0;
 }
-#endif
 
-static int
-linux_qxfer_osdata (const char *annex,
-                   unsigned char *readbuf, unsigned const char *writebuf,
-                   CORE_ADDR offset, int len)
-{
-  /* We make the process list snapshot when the object starts to be
-     read.  */
-  static const char *buf;
-  static long len_avail = -1;
-  static struct buffer buffer;
+/* Return &_DYNAMIC (via PT_DYNAMIC) in the inferior, or 0 if not present.  */
 
-  DIR *dirp;
+static CORE_ADDR
+get_dynamic (const int pid, const int is_elf64)
+{
+  CORE_ADDR phdr_memaddr, relocation;
+  int num_phdr, i;
+  unsigned char *phdr_buf;
+  const int phdr_size = is_elf64 ? sizeof (Elf64_Phdr) : sizeof (Elf32_Phdr);
 
-  if (strcmp (annex, "processes") != 0)
+  if (get_phdr_phnum_from_proc_auxv (pid, is_elf64, &phdr_memaddr, &num_phdr))
     return 0;
 
-  if (!readbuf || writebuf)
+  gdb_assert (num_phdr < 100);  /* Basic sanity check.  */
+  phdr_buf = alloca (num_phdr * phdr_size);
+
+  if (linux_read_memory (phdr_memaddr, phdr_buf, num_phdr * phdr_size))
     return 0;
 
-  if (offset == 0)
-    {
-      if (len_avail != -1 && len_avail != 0)
-       buffer_free (&buffer);
-      len_avail = 0;
-      buf = NULL;
-      buffer_init (&buffer);
-      buffer_grow_str (&buffer, "<osdata type=\"processes\">");
-
-      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])
-                || strlen (dp->d_name) > sizeof ("4294967295") - 1)
-              continue;
-
-            sprintf (procentry, "/proc/%s", dp->d_name);
-            if (stat (procentry, &statbuf) == 0
-                && S_ISDIR (statbuf.st_mode))
-              {
-                char pathname[128];
-                FILE *f;
-                char cmd[MAXPATHLEN + 1];
-                struct passwd *entry;
-
-                sprintf (pathname, "/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';
-
-                        buffer_xml_printf (
-                          &buffer,
-                          "<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);
-                  }
-              }
-          }
-
-        closedir (dirp);
-       }
-      buffer_grow_str0 (&buffer, "</osdata>\n");
-      buf = buffer_finish (&buffer);
-      len_avail = strlen (buf);
-    }
-
-  if (offset >= len_avail)
-    {
-      /* Done.  Get rid of the data.  */
-      buffer_free (&buffer);
-      buf = NULL;
-      len_avail = 0;
+  /* Compute relocation: it is expected to be 0 for "regular" executables,
+     non-zero for PIE ones.  */
+  relocation = -1;
+  for (i = 0; relocation == -1 && i < num_phdr; i++)
+    if (is_elf64)
+      {
+       Elf64_Phdr *const p = (Elf64_Phdr *) (phdr_buf + i * phdr_size);
+
+       if (p->p_type == PT_PHDR)
+         relocation = phdr_memaddr - p->p_vaddr;
+      }
+    else
+      {
+       Elf32_Phdr *const p = (Elf32_Phdr *) (phdr_buf + i * phdr_size);
+
+       if (p->p_type == PT_PHDR)
+         relocation = phdr_memaddr - p->p_vaddr;
+      }
+
+  if (relocation == -1)
+    {
+      /* PT_PHDR is optional, but necessary for PIE in general.  Fortunately
+        any real world executables, including PIE executables, have always
+        PT_PHDR present.  PT_PHDR is not present in some shared libraries or
+        in fpc (Free Pascal 2.4) binaries but neither of those have a need for
+        or present DT_DEBUG anyway (fpc binaries are statically linked).
+
+        Therefore if there exists DT_DEBUG there is always also PT_PHDR.
+
+        GDB could find RELOCATION also from AT_ENTRY - e_entry.  */
+
       return 0;
     }
 
-  if (len > len_avail - offset)
-    len = len_avail - offset;
-  memcpy (readbuf, buf + offset, len);
+  for (i = 0; i < num_phdr; i++)
+    {
+      if (is_elf64)
+       {
+         Elf64_Phdr *const p = (Elf64_Phdr *) (phdr_buf + i * phdr_size);
 
-  return len;
+         if (p->p_type == PT_DYNAMIC)
+           return p->p_vaddr + relocation;
+       }
+      else
+       {
+         Elf32_Phdr *const p = (Elf32_Phdr *) (phdr_buf + i * phdr_size);
+
+         if (p->p_type == PT_DYNAMIC)
+           return p->p_vaddr + relocation;
+       }
+    }
+
+  return 0;
 }
 
-static int
-linux_xfer_siginfo (const char *annex, unsigned char *readbuf,
-                   unsigned const char *writebuf, CORE_ADDR offset, int len)
+/* Return &_r_debug in the inferior, or -1 if not present.  Return value
+   can be 0 if the inferior does not yet have the library list initialized.  */
+
+static CORE_ADDR
+get_r_debug (const int pid, const int is_elf64)
 {
-  struct siginfo siginfo;
-  long pid = -1;
+  CORE_ADDR dynamic_memaddr;
+  const int dyn_size = is_elf64 ? sizeof (Elf64_Dyn) : sizeof (Elf32_Dyn);
+  unsigned char buf[sizeof (Elf64_Dyn)];  /* The larger of the two.  */
 
-  if (current_inferior == NULL)
-    return -1;
+  dynamic_memaddr = get_dynamic (pid, is_elf64);
+  if (dynamic_memaddr == 0)
+    return (CORE_ADDR) -1;
 
-  pid = lwpid_of (get_thread_lwp (current_inferior));
+  while (linux_read_memory (dynamic_memaddr, buf, dyn_size) == 0)
+    {
+      if (is_elf64)
+       {
+         Elf64_Dyn *const dyn = (Elf64_Dyn *) buf;
 
-  if (debug_threads)
-    fprintf (stderr, "%s siginfo for lwp %ld.\n",
-            readbuf != NULL ? "Reading" : "Writing",
-            pid);
+         if (dyn->d_tag == DT_DEBUG)
+           return dyn->d_un.d_val;
 
-  if (offset > sizeof (siginfo))
-    return -1;
+         if (dyn->d_tag == DT_NULL)
+           break;
+       }
+      else
+       {
+         Elf32_Dyn *const dyn = (Elf32_Dyn *) buf;
 
-  if (ptrace (PTRACE_GETSIGINFO, pid, 0, &siginfo) != 0)
-    return -1;
+         if (dyn->d_tag == DT_DEBUG)
+           return dyn->d_un.d_val;
 
-  if (offset + len > sizeof (siginfo))
-    len = sizeof (siginfo) - offset;
+         if (dyn->d_tag == DT_NULL)
+           break;
+       }
 
-  if (readbuf != NULL)
-    memcpy (readbuf, (char *) &siginfo + offset, len);
-  else
-    {
-      memcpy ((char *) &siginfo + offset, writebuf, len);
-      if (ptrace (PTRACE_SETSIGINFO, pid, 0, &siginfo) != 0)
-       return -1;
+      dynamic_memaddr += dyn_size;
     }
 
-  return len;
+  return (CORE_ADDR) -1;
 }
 
-/* SIGCHLD handler that serves two purposes: In non-stop/async mode,
-   so we notice when children change state; as the handler for the
-   sigsuspend in my_waitpid.  */
+/* Read one pointer from MEMADDR in the inferior.  */
 
-static void
-sigchld_handler (int signo)
+static int
+read_one_ptr (CORE_ADDR memaddr, CORE_ADDR *ptr, int ptr_size)
 {
-  int old_errno = errno;
+  *ptr = 0;
+  return linux_read_memory (memaddr, (unsigned char *) ptr, ptr_size);
+}
 
-  if (debug_threads)
-    /* fprintf is not async-signal-safe, so call write directly.  */
-    write (2, "sigchld_handler\n", sizeof ("sigchld_handler\n") - 1);
+struct link_map_offsets
+  {
+    /* Offset and size of r_debug.r_version.  */
+    int r_version_offset;
 
-  if (target_is_async_p ())
-    async_file_mark (); /* trigger a linux_wait */
+    /* Offset and size of r_debug.r_map.  */
+    int r_map_offset;
 
-  errno = old_errno;
-}
+    /* Offset to l_addr field in struct link_map.  */
+    int l_addr_offset;
 
-static int
-linux_supports_non_stop (void)
-{
-  return 1;
-}
+    /* Offset to l_name field in struct link_map.  */
+    int l_name_offset;
+
+    /* Offset to l_ld field in struct link_map.  */
+    int l_ld_offset;
+
+    /* Offset to l_next field in struct link_map.  */
+    int l_next_offset;
+
+    /* Offset to l_prev field in struct link_map.  */
+    int l_prev_offset;
+  };
+
+/* Construct qXfer:libraries:read reply.  */
 
 static int
-linux_async (int enable)
+linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
+                           unsigned const char *writebuf,
+                           CORE_ADDR offset, int len)
 {
-  int previous = (linux_event_pipe[0] != -1);
+  char *document;
+  unsigned document_len;
+  struct process_info_private *const priv = current_process ()->private;
+  char filename[PATH_MAX];
+  int pid, is_elf64;
 
-  if (previous != enable)
+  static const struct link_map_offsets lmo_32bit_offsets =
     {
-      sigset_t mask;
-      sigemptyset (&mask);
-      sigaddset (&mask, SIGCHLD);
-
-      sigprocmask (SIG_BLOCK, &mask, NULL);
+      0,     /* r_version offset. */
+      4,     /* r_debug.r_map offset.  */
+      0,     /* l_addr offset in link_map.  */
+      4,     /* l_name offset in link_map.  */
+      8,     /* l_ld offset in link_map.  */
+      12,    /* l_next offset in link_map.  */
+      16     /* l_prev offset in link_map.  */
+    };
+
+  static const struct link_map_offsets lmo_64bit_offsets =
+    {
+      0,     /* r_version offset. */
+      8,     /* r_debug.r_map offset.  */
+      0,     /* l_addr offset in link_map.  */
+      8,     /* l_name offset in link_map.  */
+      16,    /* l_ld offset in link_map.  */
+      24,    /* l_next offset in link_map.  */
+      32     /* l_prev offset in link_map.  */
+    };
+  const struct link_map_offsets *lmo;
+
+  if (writebuf != NULL)
+    return -2;
+  if (readbuf == NULL)
+    return -1;
 
-      if (enable)
-       {
-         if (pipe (linux_event_pipe) == -1)
-           fatal ("creating event pipe failed.");
+  pid = lwpid_of (get_thread_lwp (current_inferior));
+  xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
+  is_elf64 = elf_64_file_p (filename);
+  lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
 
-         fcntl (linux_event_pipe[0], F_SETFL, O_NONBLOCK);
-         fcntl (linux_event_pipe[1], F_SETFL, O_NONBLOCK);
+  if (priv->r_debug == 0)
+    priv->r_debug = get_r_debug (pid, is_elf64);
 
-         /* Register the event loop handler.  */
-         add_file_handler (linux_event_pipe[0],
-                           handle_target_event, NULL);
+  if (priv->r_debug == (CORE_ADDR) -1 || priv->r_debug == 0)
+    {
+      document = xstrdup ("<library-list-svr4 version=\"1.0\"/>\n");
+    }
+  else
+    {
+      int allocated = 1024;
+      char *p;
+      const int ptr_size = is_elf64 ? 8 : 4;
+      CORE_ADDR lm_addr, lm_prev, l_name, l_addr, l_ld, l_next, l_prev;
+      int r_version, header_done = 0;
+
+      document = xmalloc (allocated);
+      strcpy (document, "<library-list-svr4 version=\"1.0\"");
+      p = document + strlen (document);
+
+      r_version = 0;
+      if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
+                            (unsigned char *) &r_version,
+                            sizeof (r_version)) != 0
+         || r_version != 1)
+       {
+         warning ("unexpected r_debug version %d", r_version);
+         goto done;
+       }
 
-         /* Always trigger a linux_wait.  */
-         async_file_mark ();
+      if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
+                       &lm_addr, ptr_size) != 0)
+       {
+         warning ("unable to read r_map from 0x%lx",
+                  (long) priv->r_debug + lmo->r_map_offset);
+         goto done;
        }
-      else
+
+      lm_prev = 0;
+      while (read_one_ptr (lm_addr + lmo->l_name_offset,
+                          &l_name, ptr_size) == 0
+            && read_one_ptr (lm_addr + lmo->l_addr_offset,
+                             &l_addr, ptr_size) == 0
+            && read_one_ptr (lm_addr + lmo->l_ld_offset,
+                             &l_ld, ptr_size) == 0
+            && read_one_ptr (lm_addr + lmo->l_prev_offset,
+                             &l_prev, ptr_size) == 0
+            && read_one_ptr (lm_addr + lmo->l_next_offset,
+                             &l_next, ptr_size) == 0)
        {
-         delete_file_handler (linux_event_pipe[0]);
+         unsigned char libname[PATH_MAX];
 
-         close (linux_event_pipe[0]);
-         close (linux_event_pipe[1]);
-         linux_event_pipe[0] = -1;
-         linux_event_pipe[1] = -1;
-       }
+         if (lm_prev != l_prev)
+           {
+             warning ("Corrupted shared library list: 0x%lx != 0x%lx",
+                      (long) lm_prev, (long) l_prev);
+             break;
+           }
 
-      sigprocmask (SIG_UNBLOCK, &mask, NULL);
+         /* Not checking for error because reading may stop before
+            we've got PATH_MAX worth of characters.  */
+         libname[0] = '\0';
+         linux_read_memory (l_name, libname, sizeof (libname) - 1);
+         libname[sizeof (libname) - 1] = '\0';
+         if (libname[0] != '\0')
+           {
+             /* 6x the size for xml_escape_text below.  */
+             size_t len = 6 * strlen ((char *) libname);
+             char *name;
+
+             if (!header_done)
+               {
+                 /* Terminate `<library-list-svr4'.  */
+                 *p++ = '>';
+                 header_done = 1;
+               }
+
+             while (allocated < p - document + len + 200)
+               {
+                 /* Expand to guarantee sufficient storage.  */
+                 uintptr_t document_len = p - document;
+
+                 document = xrealloc (document, 2 * allocated);
+                 allocated *= 2;
+                 p = document + document_len;
+               }
+
+             name = xml_escape_text ((char *) libname);
+             p += sprintf (p, "<library name=\"%s\" lm=\"0x%lx\" "
+                              "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
+                           name, (unsigned long) lm_addr,
+                           (unsigned long) l_addr, (unsigned long) l_ld);
+             free (name);
+           }
+         else if (lm_prev == 0)
+           {
+             sprintf (p, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
+             p = p + strlen (p);
+           }
+
+         if (l_next == 0)
+           break;
+
+         lm_prev = lm_addr;
+         lm_addr = l_next;
+       }
+    done:
+      strcpy (p, "</library-list-svr4>");
     }
 
-  return previous;
-}
+  document_len = strlen (document);
+  if (offset < document_len)
+    document_len -= offset;
+  else
+    document_len = 0;
+  if (len > document_len)
+    len = document_len;
 
-static int
-linux_start_non_stop (int nonstop)
-{
-  /* Register or unregister from event-loop accordingly.  */
-  linux_async (nonstop);
-  return 0;
+  memcpy (readbuf, document + offset, len);
+  xfree (document);
+
+  return len;
 }
 
 static struct target_ops linux_target_ops = {
@@ -2638,19 +5625,22 @@ static struct target_ops linux_target_ops = {
   linux_attach,
   linux_kill,
   linux_detach,
+  linux_mourn,
   linux_join,
   linux_thread_alive,
   linux_resume,
   linux_wait,
   linux_fetch_registers,
   linux_store_registers,
+  linux_prepare_to_access_memory,
+  linux_done_accessing_memory,
   linux_read_memory,
   linux_write_memory,
   linux_look_up_symbols,
   linux_request_interrupt,
   linux_read_auxv,
-  linux_insert_watchpoint,
-  linux_remove_watchpoint,
+  linux_insert_point,
+  linux_remove_point,
   linux_stopped_by_watchpoint,
   linux_stopped_data_address,
 #if defined(__UCLIBC__) && defined(HAS_NOMMU)
@@ -2663,13 +5653,37 @@ static struct target_ops linux_target_ops = {
 #else
   NULL,
 #endif
-  NULL,
+  linux_qxfer_spu,
   hostio_last_error_from_errno,
   linux_qxfer_osdata,
   linux_xfer_siginfo,
   linux_supports_non_stop,
   linux_async,
   linux_start_non_stop,
+  linux_supports_multi_process,
+#ifdef USE_THREAD_DB
+  thread_db_handle_monitor_command,
+#else
+  NULL,
+#endif
+  linux_common_core_of_thread,
+  linux_read_loadmap,
+  linux_process_qsupported,
+  linux_supports_tracepoints,
+  linux_read_pc,
+  linux_write_pc,
+  linux_thread_stopped,
+  NULL,
+  linux_pause_all,
+  linux_unpause_all,
+  linux_cancel_breakpoints,
+  linux_stabilize_threads,
+  linux_install_fast_tracepoint_jump_pad,
+  linux_emit_ops,
+  linux_supports_disable_randomization,
+  linux_get_min_fast_tracepoint_insn_len,
+  linux_qxfer_libraries_svr4,
+  linux_supports_agent,
 };
 
 static void
@@ -2677,7 +5691,9 @@ linux_init_signals ()
 {
   /* FIXME drow/2002-06-09: As above, we should check with LinuxThreads
      to find what the cancel signal actually is.  */
+#ifndef __ANDROID__ /* Bionic doesn't use SIGRTMIN the way glibc does.  */
   signal (__SIGRTMIN+1, SIG_IGN);
+#endif
 }
 
 void
@@ -2685,7 +5701,6 @@ initialize_low (void)
 {
   struct sigaction sigchld_action;
   memset (&sigchld_action, 0, sizeof (sigchld_action));
-  thread_db_active = 0;
   set_target_ops (&linux_target_ops);
   set_breakpoint_data (the_low_target.breakpoint,
                       the_low_target.breakpoint_len);
This page took 0.095228 seconds and 4 git commands to generate.