diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index fe0a75e..3691772 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -41,6 +41,11 @@ struct thread_info
   /* True if LAST_STATUS hasn't been reported to GDB yet.  */
   int status_pending_p;
 
+  /* This is used to remember when a fork or vfork event was caught by
+     a catchpoint, and thus the event is to be followed at the next
+     resume of the thread, and not immediately.  */
+  struct target_waitstatus pending_follow;
+
   /* Given `while-stepping', a thread may be collecting data for more
      than one tracepoint simultaneously.  E.g.:
 
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 2a346d9..9382141 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -20,6 +20,7 @@
 #include "linux-low.h"
 #include "nat/linux-osdata.h"
 #include "agent.h"
+#include "tdesc.h"
 
 #include "nat/linux-nat.h"
 #include "nat/linux-waitpid.h"
@@ -368,17 +369,17 @@ linux_add_process (int pid, int attached)
 }
 
 /* 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).  */
+   event, we need to add the new LWP to our list (and return 0 so as
+   not to report the trap to higher layers).  */
 
-static void
+static int
 handle_extended_wait (struct lwp_info *event_child, int wstat)
 {
   int event = linux_ptrace_get_extended_event (wstat);
   struct thread_info *event_thr = get_lwp_thread (event_child);
   struct lwp_info *new_lwp;
 
-  if (event == PTRACE_EVENT_CLONE)
+  if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_CLONE)
     {
       ptid_t ptid;
       unsigned long new_pid;
@@ -403,6 +404,54 @@ handle_extended_wait (struct lwp_info *event_child, int wstat)
 	    warning ("wait returned unexpected status 0x%x", status);
 	}
 
+      if (event == PTRACE_EVENT_FORK)
+       {
+         struct process_info *parent_proc;
+         struct process_info *child_proc;
+         struct lwp_info *child_lwp;
+         struct target_desc *tdesc;
+
+         ptid = ptid_build (new_pid, new_pid, 0);
+
+         if (debug_threads)
+           debug_printf ("HEW: Got fork event "
+                         "from LWP %ld, new child is %d\n",
+                         ptid_get_lwp (ptid_of (event_thr)),
+                         ptid_get_pid (ptid));
+
+         /* Add the new process to the tables and clone the breakpoint
+            lists of the parent.  We need to do this even if the new process
+            will be detached, since we will need the process object and the
+            breakpoints to remove any breakpoints from memory when we
+            detach, and the host side will access registers.  */
+         child_proc = linux_add_process (new_pid, 0);
+         gdb_assert (child_proc != NULL);
+         child_lwp = add_lwp (ptid);
+         gdb_assert (child_lwp != NULL);
+         child_lwp->stopped = 1;
+         parent_proc = get_thread_process (current_inferior);
+         child_proc->attached = parent_proc->attached;
+         clone_all_breakpoints (&child_proc->breakpoints,
+                                &child_proc->raw_breakpoints,
+                                parent_proc->breakpoints);
+
+         tdesc = xmalloc (sizeof (struct target_desc));
+         copy_target_description (tdesc, parent_proc->tdesc);
+         child_proc->tdesc = tdesc;
+         child_lwp->must_set_ptrace_flags = 1;
+
+         /* Save fork info for target processing.  */
+         current_inferior->pending_follow.kind = TARGET_WAITKIND_FORKED;
+         current_inferior->pending_follow.value.related_pid = ptid;
+
+         /* Save fork info for reporting to GDB.  */
+         event_child->waitstatus.kind = TARGET_WAITKIND_FORKED;
+         event_child->waitstatus.value.related_pid = ptid;
+
+         /* Report the event.  */
+         return 0;
+       }
+
       if (debug_threads)
 	debug_printf ("HEW: Got clone event "
 		      "from LWP %ld, new child is LWP %ld\n",
@@ -452,7 +501,12 @@ handle_extended_wait (struct lwp_info *event_child, int wstat)
 	 threads, it will have a pending SIGSTOP; we may as well
 	 collect it now.  */
       linux_resume_one_lwp (event_child, event_child->stepping, 0, NULL);
+
+      /* Don't report the event.  */
+      return 1;
     }
+
+  internal_error (__FILE__, __LINE__, _("unknown ptrace event %d"), event);
 }
 
 /* Return the PC as read from the regcache of LWP, without any
@@ -1191,7 +1245,8 @@ linux_enable_extended_features (void)
     {
       /* There is no process yet, so include extended options in the
 	 base options for subsequent ptrace configuration.  */
-      linux_ptrace_set_desired_options (PTRACE_O_TRACECLONE, 0);
+      linux_ptrace_set_desired_options (PTRACE_O_TRACECLONE
+					| PTRACE_O_TRACEFORK, 0);
     }
   else
     {
@@ -1201,6 +1256,110 @@ linux_enable_extended_features (void)
     }
 }
 
+/* Target routine to determine if follow-fork is supported.  */
+
+static int
+linux_supports_follow_fork (void)
+{
+  /* Always returns true, although follow-fork is not supported unless
+     using the extended protocol.  Since we may not know yet if we are
+     going to use the extended protocol, we assume that we will and
+     leave it to GDB and internal error checking to determine whether
+     we are in extended mode.  */
+  return 1;
+}
+
+/* Callback used to find the parent process of a fork.  */
+
+static int
+is_parent_callback (struct inferior_list_entry *entry, void *ignore)
+{
+  struct thread_info *thread = (struct thread_info *) entry;
+  
+  if (thread->pending_follow.kind == TARGET_WAITKIND_FORKED
+      || thread->pending_follow.kind == TARGET_WAITKIND_VFORKED)
+    return 1;
+
+  return 0;
+}
+
+/* Handle a fork in the inferior process.  Mainly this consists of
+   handling the case where we are detaching the new child process by
+   cleaning up its state so it can proceed.  Note that if we are
+   detaching the parent process, GDB has already done that via
+   target_detach.  */
+
+int
+linux_follow_fork (int follow_child, int detach_fork)
+{
+  struct inferior_list_entry *parent_inf;
+  struct thread_info *parent_thread;
+  
+  parent_inf = find_inferior (&all_threads, is_parent_callback, NULL);
+
+  /* If we can't find the parent, we are following the child and the
+     parent has already been detached.  Nothing to do, so return OK.  */
+  if (parent_inf == NULL)
+    return 0;
+
+  parent_thread = (struct thread_info *)parent_inf;
+  parent_thread->pending_follow.kind = TARGET_WAITKIND_IGNORE;
+
+  if (!follow_child)
+    {
+      if (detach_fork)
+	{
+	  int status;
+	  ptid_t child_ptid = parent_thread->pending_follow.value.related_pid;
+	  pid_t child_pid = ptid_get_pid (child_ptid);
+	  struct lwp_info *child_lwp = find_lwp_pid (child_ptid);
+
+	  if (the_low_target.prepare_to_resume != NULL)
+	    the_low_target.prepare_to_resume (child_lwp);
+
+	  /* When debugging an inferior in an architecture that supports
+	     hardware single stepping on a kernel without commit
+	     6580807da14c423f0d0a708108e6df6ebc8bc83d, the vfork child
+	     process starts with the TIF_SINGLESTEP/X86_EFLAGS_TF bits
+	     set if the parent process had them set.
+	     To work around this, single step the child process
+	     once before detaching to clear the flags.  */
+
+	  if (can_hardware_single_step ())
+	    {
+	      linux_disable_event_reporting (child_pid);
+	      if (ptrace (PTRACE_SINGLESTEP, child_pid, 0, 0) < 0)
+		perror_with_name (_("Couldn't do single step"));
+	      if (my_waitpid (child_pid, &status, 0) < 0)
+		perror_with_name (_("Couldn't wait vfork process"));
+	    }
+
+	  if (WIFSTOPPED (status))
+	    {
+	      int signo;
+	      struct process_info *child_proc;
+
+	      signo = WSTOPSIG (status);
+	      if (signo == SIGSTOP
+		  || (signo != 0
+		      && !pass_signals[gdb_signal_from_host (signo)]))
+		signo = 0;
+
+	      ptrace (PTRACE_DETACH, child_pid, 0, signo);
+	      
+	      /* Deallocate all process-related storage.  */
+	      child_proc = find_process_pid (child_pid);
+	      if (child_proc != NULL)
+		the_target->mourn (child_proc);
+
+	      current_inferior = NULL;
+	    }
+	}
+    }
+
+  return 0;
+}
+
 /* Remove all LWPs that belong to process PROC from the lwp list.  */
 
 static int
@@ -1899,8 +2058,10 @@ linux_low_filter_event (ptid_t filter_ptid, int lwpid, int wstat)
   if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGTRAP
       && linux_is_extended_waitstatus (wstat))
     {
-      handle_extended_wait (child, wstat);
-      return NULL;
+      if (handle_extended_wait (child, wstat))
+	return NULL;
+      else
+	return child;
     }
 
   if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGSTOP
@@ -2500,6 +2661,19 @@ linux_stabilize_threads (void)
     }
 }
 
+/* Return non-zero if WAITSTATUS reflects an extended linux
+   event that gdbserver supports.  Otherwise, return zero.  */
+
+static int
+extended_event_reported (const struct target_waitstatus *waitstatus)
+{
+
+  if (waitstatus == NULL)
+    return 0;
+
+  return (waitstatus->kind == TARGET_WAITKIND_FORKED);
+}
+
 /* Wait for process, returns status.  */
 
 static ptid_t
@@ -2863,7 +3037,8 @@ retry:
 		       && !bp_explains_trap && !trace_event)
 		   || (gdb_breakpoint_here (event_child->stop_pc)
 		       && gdb_condition_true_at_breakpoint (event_child->stop_pc)
-		       && gdb_no_commands_at_breakpoint (event_child->stop_pc)));
+		       && gdb_no_commands_at_breakpoint (event_child->stop_pc))
+		   || extended_event_reported (&event_child->waitstatus));
 
   run_breakpoint_commands (event_child->stop_pc);
 
@@ -2885,6 +3060,13 @@ retry:
 			  paddress (event_child->stop_pc),
 			  paddress (event_child->step_range_start),
 			  paddress (event_child->step_range_end));
+	  if (extended_event_reported (&event_child->waitstatus))
+	    {
+	      char *str = target_waitstatus_to_string (ourstatus);
+	      debug_printf ("LWP %ld: extended event with waitstatus %s\n",
+			    lwpid_of (get_lwp_thread (event_child)), str);
+	      xfree (str);
+	    }
 	}
 
       /* We're not reporting this breakpoint to GDB, so apply the
@@ -2983,7 +3165,19 @@ retry:
 	unstop_all_lwps (1, event_child);
     }
 
-  ourstatus->kind = TARGET_WAITKIND_STOPPED;
+  if (extended_event_reported (&event_child->waitstatus))
+    {
+      /* If the reported event is a fork, vfork or exec, let GDB
+        know.  */
+      ourstatus->kind = event_child->waitstatus.kind;
+      ourstatus->value = event_child->waitstatus.value;
+
+      /* Reset the event child's waitstatus since we handled it
+         already.  */
+      event_child->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+    }
+  else
+    ourstatus->kind = TARGET_WAITKIND_STOPPED;
 
   if (current_inferior->last_resume_kind == resume_stop
       && WSTOPSIG (w) == SIGSTOP)
@@ -3000,7 +3194,7 @@ retry:
 	 but, it stopped for other reasons.  */
       ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
     }
-  else
+  else if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
     {
       ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
     }
@@ -4789,8 +4983,8 @@ linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 	val = val & 0xffff;
       else if (len == 3)
 	val = val & 0xffffff;
-      debug_printf ("Writing %0*x to 0x%08lx\n", 2 * ((len < 4) ? len : 4),
-		    val, (long)memaddr);
+      debug_printf ("Writing %0*x to 0x%08lx in process %d\n",
+		    2 * ((len < 4) ? len : 4), val, (long)memaddr, pid);
     }
 
   /* Fill start and end extra bytes of buffer with existing memory data.  */
@@ -6043,6 +6237,8 @@ static struct target_ops linux_target_ops = {
   linux_kill,
   linux_detach,
   linux_enable_extended_features,
+  linux_supports_follow_fork,
+  linux_follow_fork,
   linux_mourn,
   linux_join,
   linux_thread_alive,
@@ -6158,5 +6354,5 @@ initialize_low (void)
 
   initialize_low_arch ();
 
-  linux_ptrace_set_desired_options (PTRACE_O_TRACECLONE, 0);
+  linux_ptrace_set_desired_options (PTRACE_O_TRACECLONE, PTRACE_O_TRACEFORK);
 }
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index 4820929..bcdb713 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -266,6 +266,11 @@ struct lwp_info
      status_pending).  */
   int dead;
 
+  /* If WAITSTATUS->KIND != TARGET_WAITKIND_IGNORE, the waitstatus for
+     this LWP's last event.  This may correspond to LAST_STATUS above,
+     or to the current status during event processing.  */
+  struct target_waitstatus waitstatus;
+
   /* When stopped is set, the last wait status recorded for this lwp.  */
   int last_status;
 
diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c
index 750503d..0234051 100644
--- a/gdb/gdbserver/lynx-low.c
+++ b/gdb/gdbserver/lynx-low.c
@@ -723,6 +723,8 @@ static struct target_ops lynx_target_ops = {
   lynx_kill,
   lynx_detach,
   NULL,  /* enable_extended_features */
+  NULL,  /* supports_follow_fork */
+  NULL,  /* follow_fork */
   lynx_mourn,
   lynx_join,
   lynx_thread_alive,
diff --git a/gdb/gdbserver/nto-low.c b/gdb/gdbserver/nto-low.c
index 729328f..ec9ad97 100644
--- a/gdb/gdbserver/nto-low.c
+++ b/gdb/gdbserver/nto-low.c
@@ -930,6 +930,8 @@ static struct target_ops nto_target_ops = {
   nto_kill,
   nto_detach,
   NULL, /* enable_extended_features */
+  NULL, /* supports_follow_fork */
+  NULL, /* follow_fork */
   nto_mourn,
   NULL, /* nto_join */
   nto_thread_alive,
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index 4fcafa0..a3b12dd 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -1111,12 +1111,24 @@ prepare_resume_reply (char *buf, ptid_t ptid,
   switch (status->kind)
     {
     case TARGET_WAITKIND_STOPPED:
+    case TARGET_WAITKIND_FORKED:
       {
 	struct thread_info *saved_inferior;
 	const char **regp;
 	struct regcache *regcache;
+ 
+	if (status->kind == TARGET_WAITKIND_FORKED && multi_process)
+	  {
+	    enum gdb_signal signal = GDB_SIGNAL_TRAP;
+	    const char *event = "fork";
+
+	    sprintf (buf, "T%02x%s:p%x.%lx;", signal, event,
+		      ptid_get_pid (status->value.related_pid),
+		      ptid_get_lwp (status->value.related_pid));
+	  }
+	else
+	  sprintf (buf, "T%02x", status->value.sig);
 
-	sprintf (buf, "T%02x", status->value.sig);
 	buf += strlen (buf);
 
 	saved_inferior = current_inferior;
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index e42e596..eb95dbf 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -1916,6 +1916,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 
       strcat (own_buf, ";qXfer:threads:read+");
 
+      if (target_supports_follow_fork ())
+	strcat (own_buf, ";vFollowFork+");
+
       if (target_supports_tracepoints ())
 	{
 	  strcat (own_buf, ";ConditionalTracepoints+");
@@ -2540,6 +2543,29 @@ handle_v_kill (char *own_buf)
     }
 }
 
+/* Handle forked process.  */
+
+static void
+handle_v_follow_fork (char *own_buf)
+{
+  int follow_child;
+  int detach_fork;
+  char *p = &own_buf[12];
+  int ret;
+
+  gdb_assert (extended_protocol);
+
+  follow_child = strtol (p, NULL, 16);
+  p = strchr (p, ';') + 1;
+  detach_fork = strtol (p, NULL, 16);
+
+  ret = target_follow_fork (follow_child, detach_fork);
+  if (ret == 0)
+    write_ok (own_buf);
+  else
+    write_enn (own_buf);
+}
+
 /* Handle all of the extended 'v' packets.  */
 void
 handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
@@ -2605,6 +2631,24 @@ handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
       return;
     }
 
+  if (strncmp (own_buf, "vFollowFork;", 6) == 0)
+    {
+      if (!target_running ())
+       {
+	 fprintf (stderr, "No process to follow\n");
+	 write_enn (own_buf);
+	 return;
+       }
+      if (!extended_protocol || !multi_process)
+       {
+	 fprintf (stderr, "Target doesn't support follow-fork\n");
+	 write_enn (own_buf);
+	 return;
+       }
+      handle_v_follow_fork (own_buf);
+      return;
+    }
+
   if (handle_notif_ack (own_buf, packet_len))
     return;
 
diff --git a/gdb/gdbserver/spu-low.c b/gdb/gdbserver/spu-low.c
index cfd33b0..38d0bd2 100644
--- a/gdb/gdbserver/spu-low.c
+++ b/gdb/gdbserver/spu-low.c
@@ -646,6 +646,8 @@ static struct target_ops spu_target_ops = {
   spu_kill,
   spu_detach,
   NULL, /* enable_extended_features */
+  NULL, /* supports_follow_fork */
+  NULL, /* follow_fork */
   spu_mourn,
   spu_join,
   spu_thread_alive,
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index e09e885..7369eb0 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -96,6 +96,14 @@ struct target_ops
 
   void (*enable_extended_features) (void);
 
+  /* Returns true if follow fork is supported.  */
+  int (*supports_follow_fork) (void);
+
+  /* Handle a call to fork as specified by follow-fork-mode and
+     detach-on-fork.  */
+
+  int (*follow_fork) (int follow_child, int detach_fork);
+
   /* The inferior process has died.  Do what is right.  */
 
   void (*mourn) (struct process_info *proc);
@@ -422,6 +430,14 @@ int kill_inferior (int);
   (the_target->supports_multi_process ? \
    (*the_target->supports_multi_process) () : 0)
 
+#define target_supports_follow_fork() \
+ (the_target->supports_follow_fork ? \
+  (*the_target->supports_follow_fork) () : 0)
+
+#define target_follow_fork(follow_child, detach_fork) \
+  (the_target->follow_fork ? \
+   (*the_target->follow_fork) (follow_child, detach_fork) : 0)
+
 #define target_process_qsupported(query)		\
   do							\
     {							\
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index d09cec3..fb920f4 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -1769,6 +1769,8 @@ static struct target_ops win32_target_ops = {
   win32_kill,
   win32_detach,
   NULL, /* enable_extended_features */
+  NULL, /* supports_follow_fork */
+  NULL, /* follow_fork */
   win32_mourn,
   win32_join,
   win32_thread_alive,
diff --git a/gdb/remote.c b/gdb/remote.c
index fcddd1c..d9989db 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -25,6 +25,7 @@
 #include <fcntl.h>
 #include "inferior.h"
 #include "infrun.h"
+#include "inf-child.h"
 #include "bfd.h"
 #include "symfile.h"
 #include "exceptions.h"
@@ -111,6 +112,9 @@ static void remote_mourn (struct target_ops *ops);
 
 static void extended_remote_restart (void);
 
+static int extended_remote_follow_fork (struct target_ops *ops,
+					int follow_child, int detach_fork);
+
 static void extended_remote_mourn (struct target_ops *);
 
 static void remote_mourn_1 (struct target_ops *);
@@ -1277,6 +1281,7 @@ enum {
   PACKET_vRun,
   PACKET_QStartNoAckMode,
   PACKET_vKill,
+  PACKET_vFollowFork,
   PACKET_qXfer_siginfo_read,
   PACKET_qXfer_siginfo_write,
   PACKET_qAttached,
@@ -3886,6 +3891,8 @@ static const struct protocol_feature remote_protocol_features[] = {
     PACKET_QStartNoAckMode },
   { "multiprocess", PACKET_DISABLE, remote_supported_packet,
     PACKET_multiprocess_feature },
+  { "vFollowFork", PACKET_DISABLE, remote_supported_packet,
+    PACKET_vFollowFork },
   { "QNonStop", PACKET_DISABLE, remote_supported_packet, PACKET_QNonStop },
   { "qXfer:siginfo:read", PACKET_DISABLE, remote_supported_packet,
     PACKET_qXfer_siginfo_read },
@@ -4286,10 +4293,12 @@ remote_open_1 (const char *name, int from_tty,
    die when it hits one.  */
 
 static void
-remote_detach_1 (const char *args, int from_tty, int extended)
+remote_detach_1 (struct target_ops *ops, const char *args,
+		 int from_tty, int extended)
 {
   int pid = ptid_get_pid (inferior_ptid);
   struct remote_state *rs = get_remote_state ();
+  struct thread_info *tp = first_thread_of_process (pid);
 
   if (args)
     error (_("Argument given to \"detach\" when remotely debugging."));
@@ -4326,19 +4335,28 @@ remote_detach_1 (const char *args, int from_tty, int extended)
   if (from_tty && !extended)
     puts_filtered (_("Ending remote debugging.\n"));
 
-  target_mourn_inferior ();
+  /* If doing detach-on-fork, we don't mourn, because that will delete
+     breakpoints that should be available for the child.  */
+  if (tp->pending_follow.kind != TARGET_WAITKIND_FORKED)
+    target_mourn_inferior ();
+  else
+    {
+      inferior_ptid = null_ptid;
+      detach_inferior (pid);
+      inf_child_maybe_unpush_target (ops);
+    }
 }
 
 static void
 remote_detach (struct target_ops *ops, const char *args, int from_tty)
 {
-  remote_detach_1 (args, from_tty, 0);
+  remote_detach_1 (ops, args, from_tty, 0);
 }
 
 static void
 extended_remote_detach (struct target_ops *ops, const char *args, int from_tty)
 {
-  remote_detach_1 (args, from_tty, 1);
+  remote_detach_1 (ops, args, from_tty, 1);
 }
 
 /* Same as remote_detach, but don't send the "D" packet; just disconnect.  */
@@ -5434,7 +5452,8 @@ remote_parse_stop_reply (char *buf, struct stop_reply *event)
 	     as a register number.  */
 
 	  if (strncmp (p, "awatch", strlen("awatch")) != 0
-	      && strncmp (p, "core", strlen ("core") != 0))
+	      && strncmp (p, "core", strlen ("core") != 0)
+	      && strncmp (p, "fork", strlen ("fork") != 0))
 	    {
 	      /* Read the ``P'' register number.  */
 	      pnum = strtol (p, &p_temp, 16);
@@ -5486,6 +5505,11 @@ Packet: '%s'\n"),
 		  p = unpack_varlen_hex (++p1, &c);
 		  event->core = c;
 		}
+	      else if (strncmp (p, "fork", p1 - p) == 0)
+		{
+		  event->ws.value.related_pid = read_ptid (++p1, &p);
+		  event->ws.kind = TARGET_WAITKIND_FORKED;
+		}
 	      else
 		{
 		  /* Silently skip unknown optional info.  */
@@ -7773,6 +7797,32 @@ extended_remote_kill (struct target_ops *ops)
   target_mourn_inferior ();
 }
 
+/* Target routine for follow-fork.  */
+
+static int
+extended_remote_follow_fork (struct target_ops *ops, int follow_child,
+			     int detach_fork)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  if (remote_protocol_packets[PACKET_vFollowFork].support != PACKET_DISABLE)
+    {
+      char *p = rs->buf;
+      char *endbuf = rs->buf + get_remote_packet_size ();
+
+      xsnprintf (rs->buf, get_remote_packet_size (), "vFollowFork;%d;%d",
+		 follow_child, detach_fork);
+
+      putpkt (rs->buf);
+      getpkt (&rs->buf, &rs->buf_size, 0);
+
+      if (rs->buf[0] == 'E')
+	return 1;
+    }
+
+  return 0;
+}
+
 static void
 remote_mourn (struct target_ops *ops)
 {
@@ -9299,8 +9349,11 @@ remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
       if (ptid_equal (magic_null_ptid, ptid))
 	xsnprintf (buf, sizeof buf, "Thread <main>");
       else if (rs->extended && remote_multi_process_p (rs))
-	xsnprintf (buf, sizeof buf, "Thread %d.%ld",
-		   ptid_get_pid (ptid), ptid_get_lwp (ptid));
+	if (ptid_get_lwp (ptid) == 0)
+	  return normal_pid_to_str (ptid);
+	else
+	  xsnprintf (buf, sizeof buf, "Thread %d.%ld",
+		     ptid_get_pid (ptid), ptid_get_lwp (ptid));
       else
 	xsnprintf (buf, sizeof buf, "Thread %ld",
 		   ptid_get_lwp (ptid));
@@ -11541,6 +11594,7 @@ init_extended_remote_ops (void)
 Specify the serial device it is connected to (e.g. /dev/ttya).";
   extended_remote_ops.to_open = extended_remote_open;
   extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
+  extended_remote_ops.to_follow_fork = extended_remote_follow_fork;
   extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
   extended_remote_ops.to_detach = extended_remote_detach;
   extended_remote_ops.to_attach = extended_remote_attach;
@@ -12057,6 +12111,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vKill],
 			 "vKill", "kill", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFollowFork],
+			 "vFollowFork", "follow-fork", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qAttached],
 			 "qAttached", "query-attached", 0);
 
