]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/gnu-nat.c
Consolidate target_mourn_inferior between GDB and gdbserver
[thirdparty/binutils-gdb.git] / gdb / gnu-nat.c
index 36932a764762ad2fe23815a897c7ccc42e9f0680..927ee5c6f17833e7f2ca4d5f6ab0f4a4d5cf035c 100644 (file)
@@ -1,6 +1,5 @@
 /* Interface GDB to the GNU Hurd.
-   Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+   Copyright (C) 1992-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -10,7 +9,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.
- */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
 
 #include <ctype.h>
-#include <errno.h>
 #include <limits.h>
 #include <setjmp.h>
 #include <signal.h>
-#include <stdio.h>
-#include "gdb_string.h"
 #include <sys/ptrace.h>
 
 #include <mach.h>
 #include <hurd/msg.h>
 #include <hurd/msg_request.h>
 #include <hurd/process.h>
+/* Defined in <hurd/process.h>, but we need forward declarations from
+   <hurd/process_request.h> as well.  */
+#undef _process_user_
 #include <hurd/process_request.h>
 #include <hurd/signal.h>
 #include <hurd/sigpreempt.h>
 
 #include <portinfo.h>
 
-#include "defs.h"
 #include "inferior.h"
 #include "symtab.h"
 #include "value.h"
 #include "gdbcmd.h"
 #include "gdbcore.h"
 #include "gdbthread.h"
-#include "gdb_assert.h"
 #include "gdb_obstack.h"
 
 #include "gnu-nat.h"
+#include "inf-child.h"
 
 #include "exc_request_S.h"
 #include "notify_S.h"
@@ -86,9 +83,7 @@ int gnu_debug_flag = 0;
 
 /* Forward decls */
 
-extern struct target_ops gnu_ops;
-
-struct inf *make_inf ();
+static struct inf *make_inf ();
 void inf_clear_wait (struct inf *inf);
 void inf_cleanup (struct inf *inf);
 void inf_startup (struct inf *inf, int pid);
@@ -97,7 +92,6 @@ void inf_set_pid (struct inf *inf, pid_t pid);
 void inf_validate_procs (struct inf *inf);
 void inf_steal_exc_ports (struct inf *inf);
 void inf_restore_exc_ports (struct inf *inf);
-struct proc *inf_tid_to_proc (struct inf *inf, int tid);
 void inf_set_threads_resume_sc (struct inf *inf,
                                struct proc *run_thread,
                                int run_others);
@@ -107,12 +101,13 @@ void inf_resume (struct inf *inf);
 void inf_set_step_thread (struct inf *inf, struct proc *proc);
 void inf_detach (struct inf *inf);
 void inf_attach (struct inf *inf, int pid);
-void inf_signal (struct inf *inf, enum target_signal sig);
+void inf_signal (struct inf *inf, enum gdb_signal sig);
 void inf_continue (struct inf *inf);
 
 #define inf_debug(_inf, msg, args...) \
   do { struct inf *__inf = (_inf); \
-       debug ("{inf %d %p}: " msg, __inf->pid, __inf , ##args); } while (0)
+       debug ("{inf %d %s}: " msg, __inf->pid, \
+       host_address_to_string (__inf) , ##args); } while (0)
 
 void proc_abort (struct proc *proc, int force);
 struct proc *make_proc (struct inf *inf, mach_port_t port, int tid);
@@ -149,17 +144,17 @@ int proc_trace (struct proc *proc, int set);
 /* The state passed by an exception message.  */
 struct exc_state
   {
-    int exception;             /* The exception code */
+    int exception;             /* The exception code */
     int code, subcode;
-    mach_port_t handler;       /* The real exception port to handle this. */
-    mach_port_t reply;         /* The reply port from the exception call. */
+    mach_port_t handler;       /* The real exception port to handle this.  */
+    mach_port_t reply;         /* The reply port from the exception call.  */
   };
 
-/* The results of the last wait an inf did. */
+/* The results of the last wait an inf did.  */
 struct inf_wait
   {
     struct target_waitstatus status;   /* The status returned to gdb.  */
-    struct exc_state exc;      /* The exception that caused us to return. */
+    struct exc_state exc;      /* The exception that caused us to return.  */
     struct proc *thread;       /* The thread in question.  */
     int suppress;              /* Something trivial happened.  */
   };
@@ -172,17 +167,18 @@ struct inf
     struct proc *task;         /* The mach task.   */
     struct proc *threads;      /* A linked list of all threads in TASK.  */
 
-    /* True if THREADS needn't be validated by querying the task.  We assume that
-       we and the task in question are the only ones frobbing the thread list,
-       so as long as we don't let any code run, we don't have to worry about
-       THREADS changing.  */
+    /* True if THREADS needn't be validated by querying the task.  We
+       assume that we and the task in question are the only ones
+       frobbing the thread list, so as long as we don't let any code
+       run, we don't have to worry about THREADS changing.  */
     int threads_up_to_date;
 
-    pid_t pid;                 /* The real system PID. */
+    pid_t pid;                 /* The real system PID.  */
 
     struct inf_wait wait;      /* What to return from target_wait.  */
 
-    /* One thread proc in INF may be in `single-stepping mode'.  This is it.  */
+    /* One thread proc in INF may be in `single-stepping mode'.  This
+       is it.  */
     struct proc *step_thread;
 
     /* The thread we think is the signal thread.  */
@@ -210,11 +206,11 @@ struct inf
     unsigned int no_wait:1;
 
     /* When starting a new inferior, we don't try to validate threads until all
-       the proper execs have been done.  This is a count of how many execs we
+       the proper execs have been done, which this flag states we still
        expect to happen.  */
-    unsigned pending_execs;
+    unsigned int pending_execs:1;
 
-    /* Fields describing global state */
+    /* Fields describing global state */
 
     /* The task suspend count used when gdb has control.  This is normally 1 to
        make things easier for us, but sometimes (like when attaching to vital
@@ -262,7 +258,7 @@ proc_update_sc (struct proc *proc)
     proc_debug (proc, "sc: %d --> %d", proc->cur_sc, proc->sc);
 
   if (proc->sc == 0 && proc->state_changed)
-    /* Since PROC may start running, we must write back any state changes. */
+    /* Since PROC may start running, we must write back any state changes.  */
     {
       gdb_assert (proc_is_thread (proc));
       proc_debug (proc, "storing back changed thread state");
@@ -372,8 +368,9 @@ proc_get_state (struct proc *proc, int will_modify)
     {
       mach_msg_type_number_t state_size = THREAD_STATE_SIZE;
       error_t err =
-      thread_get_state (proc->port, THREAD_STATE_FLAVOR,
-                       (thread_state_t) &proc->state, &state_size);
+       thread_get_state (proc->port, THREAD_STATE_FLAVOR,
+                         (thread_state_t) &proc->state, &state_size);
+
       proc_debug (proc, "getting thread state");
       proc->state_valid = !err;
     }
@@ -403,7 +400,7 @@ proc_get_exception_port (struct proc * proc, mach_port_t * port)
 error_t
 proc_set_exception_port (struct proc * proc, mach_port_t port)
 {
-  proc_debug (proc, "setting exception port: %d", port);
+  proc_debug (proc, "setting exception port: %lu", port);
   if (proc_is_task (proc))
     return task_set_exception_port (proc->port, port);
   else
@@ -431,8 +428,9 @@ _proc_get_exc_port (struct proc *proc)
   return exc_port;
 }
 
-/* Replace PROC's exception port with EXC_PORT, unless it's already been
-   done.  Stash away any existing exception port so we can restore it later. */
+/* Replace PROC's exception port with EXC_PORT, unless it's already
+   been done.  Stash away any existing exception port so we can
+   restore it later.  */
 void
 proc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
 {
@@ -442,7 +440,7 @@ proc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
     {
       error_t err = 0;
 
-      proc_debug (proc, "inserting exception port: %d", exc_port);
+      proc_debug (proc, "inserting exception port: %lu", exc_port);
 
       if (cur_exc_port != exc_port)
        /* Put in our exception port.  */
@@ -456,14 +454,14 @@ proc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
            mach_port_deallocate (mach_task_self (), cur_exc_port);
        }
       else
-       /* Keep a copy of PROC's old exception port so it can be restored. */
+       /* Keep a copy of PROC's old exception port so it can be restored.  */
        {
          if (proc->saved_exc_port)
            mach_port_deallocate (mach_task_self (), proc->saved_exc_port);
          proc->saved_exc_port = cur_exc_port;
        }
 
-      proc_debug (proc, "saved exception port: %d", proc->saved_exc_port);
+      proc_debug (proc, "saved exception port: %lu", proc->saved_exc_port);
 
       if (!err)
        proc->exc_port = exc_port;
@@ -512,14 +510,14 @@ proc_trace (struct proc *proc, int set)
   thread_state_t state = proc_get_state (proc, 1);
 
   if (!state)
-    return 0;                  /* the thread must be dead.  */
+    return 0;                  /* The thread must be dead.  */
 
   proc_debug (proc, "tracing %s", set ? "on" : "off");
 
   if (set)
     {
       /* XXX We don't get the exception unless the thread has its own
-         exception port???? */
+         exception port????  */
       if (proc->exc_port == MACH_PORT_NULL)
        proc_steal_exc_port (proc, proc->inf->event_port);
       THREAD_STATE_SET_TRACED (state);
@@ -541,7 +539,7 @@ make_proc (struct inf *inf, mach_port_t port, int tid)
 {
   error_t err;
   mach_port_t prev_port = MACH_PORT_NULL;
-  struct proc *proc = xmalloc (sizeof (struct proc));
+  struct proc *proc = XNEW (struct proc);
 
   proc->port = port;
   proc->tid = tid;
@@ -575,11 +573,11 @@ make_proc (struct inf *inf, mach_port_t port, int tid)
                                    MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                    &prev_port);
   if (err)
-    warning (_("Couldn't request notification for port %d: %s"),
+    warning (_("Couldn't request notification for port %lu: %s"),
             port, safe_strerror (err));
   else
     {
-      proc_debug (proc, "notifications to: %d", inf->event_port);
+      proc_debug (proc, "notifications to: %lu", inf->event_port);
       if (prev_port != MACH_PORT_NULL)
        mach_port_deallocate (mach_task_self (), prev_port);
     }
@@ -635,10 +633,10 @@ _proc_free (struct proc *proc)
 }
 
 \f
-struct inf *
+static struct inf *
 make_inf (void)
 {
-  struct inf *inf = xmalloc (sizeof (struct inf));
+  struct inf *inf = XNEW (struct inf);
 
   inf->task = 0;
   inf->threads = 0;
@@ -748,11 +746,13 @@ inf_set_pid (struct inf *inf, pid_t pid)
   else
     {
       error_t err = proc_pid2task (proc_server, pid, &task_port);
+
       if (err)
-       error (_("Error getting task for pid %d: %s"), pid, safe_strerror (err));
+       error (_("Error getting task for pid %d: %s"),
+              pid, safe_strerror (err));
     }
 
-  inf_debug (inf, "setting task: %d", task_port);
+  inf_debug (inf, "setting task: %lu", task_port);
 
   if (inf->pause_sc)
     task_suspend (task_port);
@@ -760,8 +760,8 @@ inf_set_pid (struct inf *inf, pid_t pid)
   if (task && task->port != task_port)
     {
       inf->task = 0;
-      inf_validate_procs (inf);        /* Trash all the threads. */
-      _proc_free (task);       /* And the task. */
+      inf_validate_procs (inf);        /* Trash all the threads.  */
+      _proc_free (task);       /* And the task.  */
     }
 
   if (task_port != MACH_PORT_NULL)
@@ -795,8 +795,8 @@ inf_validate_procinfo (struct inf *inf)
   mach_msg_type_number_t pi_len = 0;
   int info_flags = 0;
   error_t err =
-  proc_getprocinfo (proc_server, inf->pid, &info_flags,
-                   (procinfo_t *) &pi, &pi_len, &noise, &noise_len);
+    proc_getprocinfo (proc_server, inf->pid, &info_flags,
+                     (procinfo_t *) &pi, &pi_len, &noise, &noise_len);
 
   if (!err)
     {
@@ -804,7 +804,8 @@ inf_validate_procinfo (struct inf *inf)
       inf->nomsg = !!(pi->state & PI_NOMSG);
       if (inf->nomsg)
        inf->traced = !!(pi->state & PI_TRACED);
-      vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
+      vm_deallocate (mach_task_self (), (vm_address_t) pi,
+                    pi_len * sizeof (*(procinfo_t) 0));
       if (noise_len > 0)
        vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len);
     }
@@ -844,21 +845,16 @@ inf_validate_task_sc (struct inf *inf)
 
   suspend_count = pi->taskinfo.suspend_count;
 
-  vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
+  vm_deallocate (mach_task_self (), (vm_address_t) pi,
+                pi_len * sizeof (*(procinfo_t) 0));
   if (noise_len > 0)
-    vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
+    vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len);
 
   if (inf->task->cur_sc < suspend_count)
     {
-      int abort;
-
-      target_terminal_ours (); /* Allow I/O.  */
-      abort = !query ("Pid %d has an additional task suspend count of %d;"
-                     " clear it? ", inf->pid,
-                     suspend_count - inf->task->cur_sc);
-      target_terminal_inferior ();     /* Give it back to the child.  */
-
-      if (abort)
+      if (!query (_("Pid %d has an additional task suspend count of %d;"
+                   " clear it? "), inf->pid,
+                 suspend_count - inf->task->cur_sc))
        error (_("Additional task suspend count left untouched."));
 
       inf->task->cur_sc = suspend_count;
@@ -869,7 +865,7 @@ inf_validate_task_sc (struct inf *inf)
    is.  If INF is running, the resume_sc count of INF's threads will
    be modified, and the signal thread will briefly be run to change
    the trace state.  */
-void
+static void
 inf_set_traced (struct inf *inf, int on)
 {
   if (on == inf->traced)
@@ -882,6 +878,7 @@ inf_set_traced (struct inf *inf, int on)
       error_t err =
        INF_RESUME_MSGPORT_RPC (inf, msg_set_init_int (msgport, refport,
                                                       INIT_TRACEMASK, mask));
+
       if (err == EIEIO)
        {
          if (on)
@@ -903,15 +900,15 @@ inf_set_traced (struct inf *inf, int on)
 /* Makes all the real suspend count deltas of all the procs in INF
    match the desired values.  Careful to always do thread/task suspend
    counts in the safe order.  Returns true if at least one thread is
-   thought to be running. */
+   thought to be running.  */
 int
 inf_update_suspends (struct inf *inf)
 {
   struct proc *task = inf->task;
+
   /* We don't have to update INF->threads even though we're iterating over it
      because we'll change a thread only if it already has an existing proc
      entry.  */
-
   inf_debug (inf, "updating suspend counts");
 
   if (task)
@@ -969,10 +966,11 @@ inf_tid_to_thread (struct inf *inf, int tid)
 }
 
 /* Converts a thread port to a struct proc.  */
-struct proc *
+static struct proc *
 inf_port_to_thread (struct inf *inf, mach_port_t port)
 {
   struct proc *thread = inf->threads;
+
   while (thread)
     if (thread->port == port)
       return thread;
@@ -981,6 +979,17 @@ inf_port_to_thread (struct inf *inf, mach_port_t port)
   return 0;
 }
 
+/* See gnu-nat.h.  */
+
+void
+inf_threads (struct inf *inf, inf_threads_ftype *f, void *arg)
+{
+  struct proc *thread;
+
+  for (thread = inf->threads; thread; thread = thread->next)
+    f (thread, arg);
+}
+
 \f
 /* Make INF's list of threads be consistent with reality of TASK.  */
 void
@@ -999,6 +1008,7 @@ inf_validate_procs (struct inf *inf)
   if (task)
     {
       error_t err = task_threads (task->port, &threads, &num_threads);
+
       inf_debug (inf, "fetching threads");
       if (err)
        /* TASK must be dead.  */
@@ -1021,7 +1031,7 @@ inf_validate_procs (struct inf *inf)
     struct proc *matched[num_threads + 1];
     /* The last thread in INF->threads, so we can add to the end.  */
     struct proc *last = 0;
-    /* The current thread we're considering. */
+    /* The current thread we're considering.  */
     struct proc *thread = inf->threads;
 
     memset (matched, 0, sizeof (matched));
@@ -1050,7 +1060,10 @@ inf_validate_procs (struct inf *inf)
            proc_debug (thread, "died!");
            thread->port = MACH_PORT_NULL;
            thread = _proc_free (thread);       /* THREAD is dead.  */
-           (last ? last->next : inf->threads) = thread;
+           if (last)
+             last->next = thread;
+           else
+             inf->threads = thread;
          }
       }
 
@@ -1062,11 +1075,29 @@ inf_validate_procs (struct inf *inf)
        else
          /* THREADS[I] is a thread we don't know about yet!  */
          {
+           ptid_t ptid;
+
            thread = make_proc (inf, threads[i], next_thread_id++);
-           (last ? last->next : inf->threads) = thread;
+           if (last)
+             last->next = thread;
+           else
+             inf->threads = thread;
            last = thread;
-           proc_debug (thread, "new thread: %d", threads[i]);
-           add_thread (pid_to_ptid (thread->tid));     /* Tell GDB's generic thread code.  */
+           proc_debug (thread, "new thread: %lu", threads[i]);
+
+           ptid = ptid_build (inf->pid, thread->tid, 0);
+
+           /* Tell GDB's generic thread code.  */
+
+           if (ptid_equal (inferior_ptid, pid_to_ptid (inf->pid)))
+             /* This is the first time we're hearing about thread
+                ids, after a fork-child.  */
+             thread_change_ptid (inferior_ptid, ptid);
+           else if (inf->pending_execs != 0)
+             /* This is a shell thread.  */
+             add_thread_silent (ptid);
+           else
+             add_thread (ptid);
          }
       }
 
@@ -1095,6 +1126,7 @@ inf_set_threads_resume_sc (struct inf *inf,
                           struct proc *run_thread, int run_others)
 {
   struct proc *thread;
+
   inf_update_procs (inf);
   for (thread = inf->threads; thread; thread = thread->next)
     if (thread == run_thread)
@@ -1223,7 +1255,7 @@ inf_detach (struct inf *inf)
          if (inf->nomsg)
            inf_continue (inf);
          else
-           inf_signal (inf, TARGET_SIGNAL_0);
+           inf_signal (inf, GDB_SIGNAL_0);
        }
 
       proc_restore_exc_port (task);
@@ -1255,7 +1287,7 @@ inf_attach (struct inf *inf, int pid)
 }
 
 \f
-/* Makes sure that we've got our exception ports entrenched in the process. */
+/* Makes sure that we've got our exception ports entrenched in the process.  */
 void
 inf_steal_exc_ports (struct inf *inf)
 {
@@ -1263,7 +1295,7 @@ inf_steal_exc_ports (struct inf *inf)
 
   inf_debug (inf, "stealing exception ports");
 
-  inf_set_step_thread (inf, 0);        /* The step thread is special. */
+  inf_set_step_thread (inf, 0);        /* The step thread is special.  */
 
   proc_steal_exc_port (inf->task, inf->event_port);
   for (thread = inf->threads; thread; thread = thread->next)
@@ -1278,7 +1310,7 @@ inf_restore_exc_ports (struct inf *inf)
 
   inf_debug (inf, "restoring exception ports");
 
-  inf_set_step_thread (inf, 0);        /* The step thread is special. */
+  inf_set_step_thread (inf, 0);        /* The step thread is special.  */
 
   proc_restore_exc_port (inf->task);
   for (thread = inf->threads; thread; thread = thread->next)
@@ -1290,12 +1322,12 @@ inf_restore_exc_ports (struct inf *inf)
    signal 0, will continue it.  INF is assumed to be in a paused state, and
    the resume_sc's of INF's threads may be affected.  */
 void
-inf_signal (struct inf *inf, enum target_signal sig)
+inf_signal (struct inf *inf, enum gdb_signal sig)
 {
   error_t err = 0;
-  int host_sig = target_signal_to_host (sig);
+  int host_sig = gdb_signal_to_host (sig);
 
-#define NAME target_signal_to_name (sig)
+#define NAME gdb_signal_to_name (sig)
 
   if (host_sig >= _NSIG)
     /* A mach exception.  Exceptions are encoded in the signal space by
@@ -1303,6 +1335,7 @@ inf_signal (struct inf *inf, enum target_signal sig)
        extremely large)!  */
     {
       struct inf_wait *w = &inf->wait;
+
       if (w->status.kind == TARGET_WAITKIND_STOPPED
          && w->status.value.sig == sig
          && w->thread && !w->thread->aborted)
@@ -1313,8 +1346,9 @@ inf_signal (struct inf *inf, enum target_signal sig)
           i.e., we pretend it's global.  */
        {
          struct exc_state *e = &w->exc;
+
          inf_debug (inf, "passing through exception:"
-                    " task = %d, thread = %d, exc = %d"
+                    " task = %lu, thread = %lu, exc = %d"
                     ", code = %d, subcode = %d",
                     w->thread->port, inf->task->port,
                     e->exception, e->code, e->subcode);
@@ -1353,7 +1387,7 @@ inf_signal (struct inf *inf, enum target_signal sig)
        run, and wait for it to get into a reasonable state before we
        can continue the rest of the process.  When we finally resume the
        process the signal we request will be the very first thing that
-       happens. */
+       happens.  */
     {
       inf_debug (inf, "sending %s to unstopped process"
                 " (so resuming signal thread)", NAME);
@@ -1364,7 +1398,7 @@ inf_signal (struct inf *inf, enum target_signal sig)
     }
 
   if (err == EIEIO)
-    /* Can't do too much... */
+    /* Can't do too much...  */
     warning (_("Can't deliver signal %s: No signal thread."), NAME);
   else if (err)
     warning (_("Delivering signal %s: %s"), NAME, safe_strerror (err));
@@ -1403,15 +1437,16 @@ inf_continue (struct inf *inf)
 
 \f
 /* The inferior used for all gdb target ops.  */
-struct inf *current_inferior = 0;
+struct inf *gnu_current_inf = 0;
 
 /* The inferior being waited for by gnu_wait.  Since GDB is decidely not
    multi-threaded, we don't bother to lock this.  */
 struct inf *waiting_inf;
 
-/* Wait for something to happen in the inferior, returning what in STATUS. */
+/* Wait for something to happen in the inferior, returning what in STATUS.  */
 static ptid_t
-gnu_wait (ptid_t tid, struct target_waitstatus *status)
+gnu_wait (struct target_ops *ops,
+         ptid_t ptid, struct target_waitstatus *status, int options)
 {
   struct msg
     {
@@ -1421,7 +1456,7 @@ gnu_wait (ptid_t tid, struct target_waitstatus *status)
     } msg;
   error_t err;
   struct proc *thread;
-  struct inf *inf = current_inferior;
+  struct inf *inf = gnu_current_inf;
 
   extern int exc_server (mach_msg_header_t *, mach_msg_header_t *);
   extern int msg_reply_server (mach_msg_header_t *, mach_msg_header_t *);
@@ -1442,7 +1477,7 @@ gnu_wait (ptid_t tid, struct target_waitstatus *status)
 
   waiting_inf = inf;
 
-  inf_debug (inf, "waiting for: %d", PIDGET (tid));
+  inf_debug (inf, "waiting for: %s", target_pid_to_str (ptid));
 
 rewait:
   if (proc_wait_pid != inf->pid && !inf->no_wait)
@@ -1452,7 +1487,7 @@ rewait:
 
       if (proc_wait_pid)
        /* The proc server is single-threaded, and only allows a single
-          outstanding wait request, so we have to cancel the previous one. */
+          outstanding wait request, so we have to cancel the previous one.  */
        {
          inf_debug (inf, "cancelling previous wait on pid %d", proc_wait_pid);
          interrupt_operation (proc_server, 0);
@@ -1470,7 +1505,7 @@ rewait:
             get any other replies, because it was either from a
             different INF, or a different process attached to INF --
             and the event port, which is the wait reply port, changes
-            when you switch processes. */
+            when you switch processes.  */
          proc_waits_pending = 1;
        }
     }
@@ -1536,24 +1571,14 @@ rewait:
           while execing.  */
        {
          w->suppress = 1;
-         inf_debug (inf, "pending_execs = %d, ignoring minor event",
-                    inf->pending_execs);
+         inf_debug (inf, "pending_execs, ignoring minor event");
        }
       else if (kind == TARGET_WAITKIND_STOPPED
-              && w->status.value.sig == TARGET_SIGNAL_TRAP)
+              && w->status.value.sig == GDB_SIGNAL_TRAP)
        /* Ah hah!  A SIGTRAP from the inferior while starting up probably
           means we've succesfully completed an exec!  */
        {
-         if (--inf->pending_execs == 0)
-           /* We're done!  */
-           {
-#if 0                          /* do we need this? */
-             prune_threads (1);        /* Get rid of the old shell threads */
-             renumber_threads (0);     /* Give our threads reasonable names. */
-#endif
-           }
-         inf_debug (inf, "pending exec completed, pending_execs => %d",
-                    inf->pending_execs);
+         inf_debug (inf, "one pending exec completed");
        }
       else if (kind == TARGET_WAITKIND_STOPPED)
        /* It's possible that this signal is because of a crashed process
@@ -1578,20 +1603,26 @@ rewait:
 
   thread = inf->wait.thread;
   if (thread)
-    tid = pid_to_ptid (thread->tid);
+    ptid = ptid_build (inf->pid, thread->tid, 0);
+  else if (ptid_equal (ptid, minus_one_ptid))
+    thread = inf_tid_to_thread (inf, -1);
   else
-    thread = inf_tid_to_thread (inf, PIDGET (tid));
+    thread = inf_tid_to_thread (inf, ptid_get_lwp (ptid));
 
   if (!thread || thread->port == MACH_PORT_NULL)
     {
       /* TID is dead; try and find a new thread.  */
       if (inf_update_procs (inf) && inf->threads)
-       tid = pid_to_ptid (inf->threads->tid); /* The first available thread.  */
+       ptid = ptid_build (inf->pid, inf->threads->tid, 0); /* The first
+                                                              available
+                                                              thread.  */
       else
-       tid = inferior_ptid;    /* let wait_for_inferior handle exit case */
+       ptid = inferior_ptid;   /* let wait_for_inferior handle exit case */
     }
 
-  if (thread && PIDGET (tid) >= 0 && status->kind != TARGET_WAITKIND_SPURIOUS
+  if (thread
+      && !ptid_equal (ptid, minus_one_ptid)
+      && status->kind != TARGET_WAITKIND_SPURIOUS
       && inf->pause_sc == 0 && thread->pause_sc == 0)
     /* If something actually happened to THREAD, make sure we
        suspend it.  */
@@ -1600,7 +1631,8 @@ rewait:
       inf_update_suspends (inf);
     }
 
-  inf_debug (inf, "returning tid = %d, status = %s (%d)", PIDGET (tid),
+  inf_debug (inf, "returning ptid = %s, status = %s (%d)",
+            target_pid_to_str (ptid),
             status->kind == TARGET_WAITKIND_EXITED ? "EXITED"
             : status->kind == TARGET_WAITKIND_STOPPED ? "STOPPED"
             : status->kind == TARGET_WAITKIND_SIGNALLED ? "SIGNALLED"
@@ -1609,7 +1641,7 @@ rewait:
             : "?",
             status->value.integer);
 
-  return tid;
+  return ptid;
 }
 
 \f
@@ -1623,7 +1655,7 @@ S_exception_raise_request (mach_port_t port, mach_port_t reply_port,
   struct proc *thread = inf_port_to_thread (inf, thread_port);
 
   inf_debug (waiting_inf,
-            "thread = %d, task = %d, exc = %d, code = %d, subcode = %d",
+            "thread = %lu, task = %lu, exc = %d, code = %d, subcode = %d",
             thread_port, task_port, exception, code, subcode);
 
   if (!thread)
@@ -1651,7 +1683,7 @@ S_exception_raise_request (mach_port_t port, mach_port_t reply_port,
       if (exception == EXC_BREAKPOINT)
        /* GDB likes to get SIGTRAP for breakpoints.  */
        {
-         inf->wait.status.value.sig = TARGET_SIGNAL_TRAP;
+         inf->wait.status.value.sig = GDB_SIGNAL_TRAP;
          mach_port_deallocate (mach_task_self (), reply_port);
        }
       else
@@ -1659,19 +1691,19 @@ S_exception_raise_request (mach_port_t port, mach_port_t reply_port,
        {
          if (thread->exc_port == port)
            {
-             inf_debug (waiting_inf, "Handler is thread exception port <%d>",
+             inf_debug (waiting_inf, "Handler is thread exception port <%lu>",
                         thread->saved_exc_port);
              inf->wait.exc.handler = thread->saved_exc_port;
            }
          else
            {
-             inf_debug (waiting_inf, "Handler is task exception port <%d>",
+             inf_debug (waiting_inf, "Handler is task exception port <%lu>",
                         inf->task->saved_exc_port);
              inf->wait.exc.handler = inf->task->saved_exc_port;
              gdb_assert (inf->task->exc_port == port);
            }
          if (inf->wait.exc.handler != MACH_PORT_NULL)
-           /* Add a reference to the exception handler. */
+           /* Add a reference to the exception handler.  */
            mach_port_mod_refs (mach_task_self (),
                                inf->wait.exc.handler, MACH_PORT_RIGHT_SEND,
                                1);
@@ -1681,10 +1713,11 @@ S_exception_raise_request (mach_port_t port, mach_port_t reply_port,
          inf->wait.exc.subcode = subcode;
          inf->wait.exc.reply = reply_port;
 
-         /* Exceptions are encoded in the signal space by putting them after
-            _NSIG; this assumes they're positive (and not extremely large)! */
+         /* Exceptions are encoded in the signal space by putting
+            them after _NSIG; this assumes they're positive (and not
+            extremely large)!  */
          inf->wait.status.value.sig =
-           target_signal_from_host (_NSIG + exception);
+           gdb_signal_from_host (_NSIG + exception);
        }
     }
   else
@@ -1700,12 +1733,13 @@ S_exception_raise_request (mach_port_t port, mach_port_t reply_port,
 \f
 /* Fill in INF's wait field after a task has died without giving us more
    detailed information.  */
-void
+static void
 inf_task_died_status (struct inf *inf)
 {
-  warning (_("Pid %d died with unknown exit status, using SIGKILL."), inf->pid);
+  warning (_("Pid %d died with unknown exit status, using SIGKILL."),
+          inf->pid);
   inf->wait.status.kind = TARGET_WAITKIND_SIGNALLED;
-  inf->wait.status.value.sig = TARGET_SIGNAL_KILL;
+  inf->wait.status.value.sig = GDB_SIGNAL_KILL;
 }
 
 /* Notify server routines.  The only real one is dead name notification.  */
@@ -1714,7 +1748,7 @@ do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port)
 {
   struct inf *inf = waiting_inf;
 
-  inf_debug (waiting_inf, "port = %d", dead_port);
+  inf_debug (waiting_inf, "port = %lu", dead_port);
 
   if (inf->task && inf->task->port == dead_port)
     {
@@ -1732,6 +1766,7 @@ do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port)
   else
     {
       struct proc *thread = inf_port_to_thread (inf, dead_port);
+
       if (thread)
        {
          proc_debug (thread, "is dead");
@@ -1744,49 +1779,30 @@ do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port)
     }
 
   mach_port_deallocate (mach_task_self (), dead_port);
-  inf->threads_up_to_date = 0; /* Just in case */
+  inf->threads_up_to_date = 0; /* Just in case */
 
   return 0;
 }
 
 \f
-static error_t
-ill_rpc (char *fun)
-{
-  warning (_("illegal rpc: %s"), fun);
-  return 0;
-}
-
-error_t
-do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t count)
-{
-  return ill_rpc ("do_mach_notify_no_senders");
-}
-
-error_t
-do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name)
-{
-  return ill_rpc ("do_mach_notify_port_deleted");
-}
-
-error_t
-do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name)
-{
-  return ill_rpc ("do_mach_notify_msg_accepted");
-}
-
-error_t
-do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t name)
-{
-  return ill_rpc ("do_mach_notify_port_destroyed");
-}
-
-error_t
-do_mach_notify_send_once (mach_port_t notify)
-{
-  return ill_rpc ("do_mach_notify_send_once");
-}
+#define ILL_RPC(fun, ...) \
+  extern kern_return_t fun (__VA_ARGS__); \
+  kern_return_t fun (__VA_ARGS__) \
+  { \
+    warning (_("illegal rpc: %s"), #fun); \
+    return 0; \
+  }
 
+ILL_RPC (do_mach_notify_no_senders,
+        mach_port_t notify, mach_port_mscount_t count)
+ILL_RPC (do_mach_notify_port_deleted,
+        mach_port_t notify, mach_port_t name)
+ILL_RPC (do_mach_notify_msg_accepted,
+        mach_port_t notify, mach_port_t name)
+ILL_RPC (do_mach_notify_port_destroyed,
+        mach_port_t notify, mach_port_t name)
+ILL_RPC (do_mach_notify_send_once,
+        mach_port_t notify)
 \f
 /* Process_reply server routines.  We only use process_wait_reply.  */
 
@@ -1818,7 +1834,8 @@ S_proc_wait_reply (mach_port_t reply, error_t err,
     {
       if (err != EINTR)
        {
-         warning (_("Can't wait for pid %d: %s"), inf->pid, safe_strerror (err));
+         warning (_("Can't wait for pid %d: %s"),
+                  inf->pid, safe_strerror (err));
          inf->no_wait = 1;
 
          /* Since we can't see the inferior's signals, don't trap them.  */
@@ -1842,19 +1859,66 @@ S_proc_wait_reply (mach_port_t reply, error_t err,
   return 0;
 }
 
-error_t
-S_proc_setmsgport_reply (mach_port_t reply, error_t err,
-                        mach_port_t old_msg_port)
-{
-  return ill_rpc ("S_proc_setmsgport_reply");
-}
-
-error_t
-S_proc_getmsgport_reply (mach_port_t reply, error_t err, mach_port_t msg_port)
-{
-  return ill_rpc ("S_proc_getmsgport_reply");
-}
-
+ILL_RPC (S_proc_setmsgport_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        mach_port_t oldmsgport)
+ILL_RPC (S_proc_getmsgport_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        mach_port_t msgports)
+ILL_RPC (S_proc_pid2task_reply,
+        mach_port_t reply_port, kern_return_t return_code, mach_port_t task)
+ILL_RPC (S_proc_task2pid_reply,
+        mach_port_t reply_port, kern_return_t return_code, pid_t pid)
+ILL_RPC (S_proc_task2proc_reply,
+        mach_port_t reply_port, kern_return_t return_code, mach_port_t proc)
+ILL_RPC (S_proc_proc2task_reply,
+        mach_port_t reply_port, kern_return_t return_code, mach_port_t task)
+ILL_RPC (S_proc_pid2proc_reply,
+        mach_port_t reply_port, kern_return_t return_code, mach_port_t proc)
+ILL_RPC (S_proc_getprocinfo_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        int flags, procinfo_t procinfo, mach_msg_type_number_t procinfoCnt,
+        data_t threadwaits, mach_msg_type_number_t threadwaitsCnt)
+ILL_RPC (S_proc_getprocargs_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        data_t procargs, mach_msg_type_number_t procargsCnt)
+ILL_RPC (S_proc_getprocenv_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        data_t procenv, mach_msg_type_number_t procenvCnt)
+ILL_RPC (S_proc_getloginid_reply,
+        mach_port_t reply_port, kern_return_t return_code, pid_t login_id)
+ILL_RPC (S_proc_getloginpids_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        pidarray_t pids, mach_msg_type_number_t pidsCnt)
+ILL_RPC (S_proc_getlogin_reply,
+        mach_port_t reply_port, kern_return_t return_code, string_t logname)
+ILL_RPC (S_proc_getsid_reply,
+        mach_port_t reply_port, kern_return_t return_code, pid_t sid)
+ILL_RPC (S_proc_getsessionpgids_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        pidarray_t pgidset, mach_msg_type_number_t pgidsetCnt)
+ILL_RPC (S_proc_getsessionpids_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        pidarray_t pidset, mach_msg_type_number_t pidsetCnt)
+ILL_RPC (S_proc_getsidport_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        mach_port_t sessport)
+ILL_RPC (S_proc_getpgrp_reply,
+        mach_port_t reply_port, kern_return_t return_code, pid_t pgrp)
+ILL_RPC (S_proc_getpgrppids_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        pidarray_t pidset, mach_msg_type_number_t pidsetCnt)
+ILL_RPC (S_proc_get_tty_reply,
+        mach_port_t reply_port, kern_return_t return_code, mach_port_t tty)
+ILL_RPC (S_proc_getnports_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        mach_msg_type_number_t nports)
+ILL_RPC (S_proc_is_important_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        boolean_t essential)
+ILL_RPC (S_proc_get_code_reply,
+        mach_port_t reply_port, kern_return_t return_code,
+        vm_address_t start_code, vm_address_t end_code)
 \f
 /* Msg_reply server routines.  We only use msg_sig_post_untraced_reply.  */
 
@@ -1871,7 +1935,7 @@ S_msg_sig_post_untraced_reply (mach_port_t reply, error_t err)
        server should like).  */
     {
       inf->wait.status.kind = TARGET_WAITKIND_STOPPED;
-      inf->wait.status.value.sig = TARGET_SIGNAL_0;
+      inf->wait.status.value.sig = GDB_SIGNAL_0;
     }
   else if (err)
     warning (_("Signal delivery failed: %s"), safe_strerror (err));
@@ -1888,12 +1952,8 @@ S_msg_sig_post_untraced_reply (mach_port_t reply, error_t err)
   return 0;
 }
 
-error_t
-S_msg_sig_post_reply (mach_port_t reply, error_t err)
-{
-  return ill_rpc ("S_msg_sig_post_reply");
-}
-
+ILL_RPC (S_msg_sig_post_reply,
+        mach_port_t reply, error_t err)
 \f
 /* Returns the number of messages queued for the receive right PORT.  */
 static mach_port_msgcount_t
@@ -1901,7 +1961,7 @@ port_msgs_queued (mach_port_t port)
 {
   struct mach_port_status status;
   error_t err =
-  mach_port_get_receive_status (mach_task_self (), port, &status);
+    mach_port_get_receive_status (mach_task_self (), port, &status);
 
   if (err)
     return 0;
@@ -1924,21 +1984,24 @@ port_msgs_queued (mach_port_t port)
 
    Note that a resume may not `take' if there are pending exceptions/&c
    still unprocessed from the last resume we did (any given resume may result
-   in multiple events returned by wait).
- */
+   in multiple events returned by wait).  */
+
 static void
-gnu_resume (ptid_t tid, int step, enum target_signal sig)
+gnu_resume (struct target_ops *ops,
+           ptid_t ptid, int step, enum gdb_signal sig)
 {
   struct proc *step_thread = 0;
-  struct inf *inf = current_inferior;
+  int resume_all;
+  struct inf *inf = gnu_current_inf;
 
-  inf_debug (inf, "tid = %d, step = %d, sig = %d", PIDGET (tid), step, sig);
+  inf_debug (inf, "ptid = %s, step = %d, sig = %d",
+            target_pid_to_str (ptid), step, sig);
 
   inf_validate_procinfo (inf);
 
-  if (sig != TARGET_SIGNAL_0 || inf->stopped)
+  if (sig != GDB_SIGNAL_0 || inf->stopped)
     {
-      if (sig == TARGET_SIGNAL_0 && inf->nomsg)
+      if (sig == GDB_SIGNAL_0 && inf->nomsg)
        inf_continue (inf);
       else
        inf_signal (inf, sig);
@@ -1950,40 +2013,47 @@ gnu_resume (ptid_t tid, int step, enum target_signal sig)
       proc_abort (inf->wait.thread, 1);
       warning (_("Aborting %s with unforwarded exception %s."),
               proc_string (inf->wait.thread),
-              target_signal_to_name (inf->wait.status.value.sig));
+              gdb_signal_to_name (inf->wait.status.value.sig));
     }
 
   if (port_msgs_queued (inf->event_port))
     /* If there are still messages in our event queue, don't bother resuming
-       the process, as we're just going to stop it right away anyway. */
+       the process, as we're just going to stop it right away anyway.  */
     return;
 
   inf_update_procs (inf);
 
-  if (PIDGET (tid) < 0)
+  /* A specific PTID means `step only this process id'.  */
+  resume_all = ptid_equal (ptid, minus_one_ptid);
+
+  if (resume_all)
     /* Allow all threads to run, except perhaps single-stepping one.  */
     {
-      inf_debug (inf, "running all threads; tid = %d", PIDGET (inferior_ptid));
-      tid = inferior_ptid;     /* What to step. */
+      inf_debug (inf, "running all threads; tid = %d",
+                ptid_get_pid (inferior_ptid));
+      ptid = inferior_ptid;    /* What to step.  */
       inf_set_threads_resume_sc (inf, 0, 1);
     }
   else
     /* Just allow a single thread to run.  */
     {
-      struct proc *thread = inf_tid_to_thread (inf, PIDGET (tid));
+      struct proc *thread = inf_tid_to_thread (inf, ptid_get_lwp (ptid));
+
       if (!thread)
-       error (_("Can't run single thread id %d: no such thread!"));
-      inf_debug (inf, "running one thread: %d/%d", inf->pid, thread->tid);
+       error (_("Can't run single thread id %s: no such thread!"),
+              target_pid_to_str (ptid));
+      inf_debug (inf, "running one thread: %s", target_pid_to_str (ptid));
       inf_set_threads_resume_sc (inf, thread, 0);
     }
 
   if (step)
     {
-      step_thread = inf_tid_to_thread (inf, PIDGET (tid));
+      step_thread = inf_tid_to_thread (inf, ptid_get_lwp (ptid));
       if (!step_thread)
-       warning (_("Can't step thread id %d: no such thread."), PIDGET (tid));
+       warning (_("Can't step thread id %s: no such thread."),
+                target_pid_to_str (ptid));
       else
-       inf_debug (inf, "stepping thread: %d/%d", inf->pid, step_thread->tid);
+       inf_debug (inf, "stepping thread: %s", target_pid_to_str (ptid));
     }
   if (step_thread != inf->step_thread)
     inf_set_step_thread (inf, step_thread);
@@ -1994,26 +2064,26 @@ gnu_resume (ptid_t tid, int step, enum target_signal sig)
 
 \f
 static void
-gnu_kill_inferior (void)
+gnu_kill_inferior (struct target_ops *ops)
 {
-  struct proc *task = current_inferior->task;
+  struct proc *task = gnu_current_inf->task;
+
   if (task)
     {
       proc_debug (task, "terminating...");
       task_terminate (task->port);
-      inf_set_pid (current_inferior, -1);
+      inf_set_pid (gnu_current_inf, -1);
     }
-  target_mourn_inferior ();
+  target_mourn_inferior (inferior_ptid);
 }
 
 /* Clean up after the inferior dies.  */
 static void
-gnu_mourn_inferior (void)
+gnu_mourn_inferior (struct target_ops *ops)
 {
-  inf_debug (current_inferior, "rip");
-  inf_detach (current_inferior);
-  unpush_target (&gnu_ops);
-  generic_mourn_inferior ();
+  inf_debug (gnu_current_inf, "rip");
+  inf_detach (gnu_current_inf);
+  inf_child_mourn_inferior (ops);
 }
 
 \f
@@ -2023,9 +2093,9 @@ gnu_mourn_inferior (void)
 static int
 inf_pick_first_thread (void)
 {
-  if (current_inferior->task && current_inferior->threads)
+  if (gnu_current_inf->task && gnu_current_inf->threads)
     /* The first thread.  */
-    return current_inferior->threads->tid;
+    return gnu_current_inf->threads->tid;
   else
     /* What may be the next thread.  */
     return next_thread_id;
@@ -2034,50 +2104,53 @@ inf_pick_first_thread (void)
 static struct inf *
 cur_inf (void)
 {
-  if (!current_inferior)
-    current_inferior = make_inf ();
-  return current_inferior;
+  if (!gnu_current_inf)
+    gnu_current_inf = make_inf ();
+  return gnu_current_inf;
 }
 
 static void
-gnu_create_inferior (char *exec_file, char *allargs, char **env,
+gnu_create_inferior (struct target_ops *ops, 
+                    char *exec_file, char *allargs, char **env,
                     int from_tty)
 {
   struct inf *inf = cur_inf ();
+  int pid;
 
-  void trace_me ()
+  void trace_me (void)
   {
     /* We're in the child; make this process stop as soon as it execs.  */
     inf_debug (inf, "tracing self");
     if (ptrace (PTRACE_TRACEME) != 0)
       error (_("ptrace (PTRACE_TRACEME) failed!"));
   }
-  void attach_to_child (int pid)
-  {
-    /* Attach to the now stopped child, which is actually a shell...  */
-    inf_debug (inf, "attaching to child: %d", pid);
 
-    inf_attach (inf, pid);
+  inf_debug (inf, "creating inferior");
 
-    attach_flag = 0;
-    push_target (&gnu_ops);
+  pid = fork_inferior (exec_file, allargs, env, trace_me,
+                       NULL, NULL, NULL, NULL);
 
-    inf->pending_execs = 2;
-    inf->nomsg = 1;
-    inf->traced = 1;
+  /* Attach to the now stopped child, which is actually a shell...  */
+  inf_debug (inf, "attaching to child: %d", pid);
 
-    /* Now let the child run again, knowing that it will stop immediately
-       because of the ptrace. */
-    inf_resume (inf);
-    inferior_ptid = pid_to_ptid (inf_pick_first_thread ());
+  inf_attach (inf, pid);
 
-    startup_inferior (inf->pending_execs);
-  }
+  push_target (ops);
 
-  inf_debug (inf, "creating inferior");
+  inf->pending_execs = 1;
+  inf->nomsg = 1;
+  inf->traced = 1;
+
+  /* Now let the child run again, knowing that it will stop
+     immediately because of the ptrace.  */
+  inf_resume (inf);
 
-  fork_inferior (exec_file, allargs, env, trace_me, attach_to_child,
-                NULL, NULL);
+  /* We now have thread info.  */
+  thread_change_ptid (inferior_ptid,
+                     ptid_build (inf->pid, inf_pick_first_thread (), 0));
+
+  startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
+  inf->pending_execs = 0;
 
   inf_validate_procinfo (inf);
   inf_update_signal_thread (inf);
@@ -2089,35 +2162,22 @@ gnu_create_inferior (char *exec_file, char *allargs, char **env,
     inf_steal_exc_ports (inf);
   else
     inf_restore_exc_ports (inf);
-
-  /* Here we go!  */
-  proceed ((CORE_ADDR) -1, 0, 0);
-}
-
-/* Mark our target-struct as eligible for stray "run" and "attach"
-   commands.  */
-static int
-gnu_can_run (void)
-{
-  return 1;
 }
 
 \f
 /* Attach to process PID, then initialize for debugging it
    and wait for the trace-trap that results from attaching.  */
 static void
-gnu_attach (char *args, int from_tty)
+gnu_attach (struct target_ops *ops, const char *args, int from_tty)
 {
   int pid;
   char *exec_file;
   struct inf *inf = cur_inf ();
+  struct inferior *inferior;
 
-  if (!args)
-    error_no_arg (_("process-id to attach"));
+  pid = parse_pid_to_attach (args);
 
-  pid = atoi (args);
-
-  if (pid == getpid ())                /* Trying to masturbate? */
+  if (pid == getpid ())                /* Trying to masturbate?  */
     error (_("I refuse to debug myself!"));
 
   if (from_tty)
@@ -2136,12 +2196,16 @@ gnu_attach (char *args, int from_tty)
   inf_debug (inf, "attaching to pid: %d", pid);
 
   inf_attach (inf, pid);
-  inf_update_procs (inf);
 
-  inferior_ptid = pid_to_ptid (inf_pick_first_thread ());
+  push_target (ops);
 
-  attach_flag = 1;
-  push_target (&gnu_ops);
+  inferior = current_inferior ();
+  inferior_appeared (inferior, pid);
+  inferior->attach_flag = 1;
+
+  inf_update_procs (inf);
+
+  inferior_ptid = ptid_build (pid, inf_pick_first_thread (), 0);
 
   /* We have to initialize the terminal settings now, since the code
      below might try to restore them.  */
@@ -2154,8 +2218,8 @@ gnu_attach (char *args, int from_tty)
   inf_update_signal_thread (inf);
   inf_set_traced (inf, inf->want_signals);
 
-#if 0                          /* Do we need this? */
-  renumber_threads (0);                /* Give our threads reasonable names. */
+#if 0                          /* Do we need this?  */
+  renumber_threads (0);                /* Give our threads reasonable names.  */
 #endif
 }
 
@@ -2168,93 +2232,74 @@ gnu_attach (char *args, int from_tty)
    previously attached.  It *might* work if the program was
    started via fork.  */
 static void
-gnu_detach (char *args, int from_tty)
+gnu_detach (struct target_ops *ops, const char *args, int from_tty)
 {
+  int pid;
+
   if (from_tty)
     {
       char *exec_file = get_exec_file (0);
+
       if (exec_file)
        printf_unfiltered ("Detaching from program `%s' pid %d\n",
-                          exec_file, current_inferior->pid);
+                          exec_file, gnu_current_inf->pid);
       else
-       printf_unfiltered ("Detaching from pid %d\n", current_inferior->pid);
+       printf_unfiltered ("Detaching from pid %d\n", gnu_current_inf->pid);
       gdb_flush (gdb_stdout);
     }
 
-  inf_detach (current_inferior);
+  pid = gnu_current_inf->pid;
+
+  inf_detach (gnu_current_inf);
 
   inferior_ptid = null_ptid;
+  detach_inferior (pid);
 
-  unpush_target (&gnu_ops);    /* Pop out of handling an inferior */
+  inf_child_maybe_unpush_target (ops);
 }
 \f
 static void
-gnu_terminal_init_inferior (void)
-{
-  gdb_assert (current_inferior);
-  terminal_init_inferior_with_pgrp (current_inferior->pid);
-}
-
-/* Get ready to modify the registers array.  On machines which store
-   individual registers, this doesn't need to do anything.  On machines
-   which store all the registers in one fell swoop, this makes sure
-   that registers contains all the registers from the program being
-   debugged.  */
-static void
-gnu_prepare_to_store (void)
+gnu_terminal_init (struct target_ops *self)
 {
-#ifdef CHILD_PREPARE_TO_STORE
-  CHILD_PREPARE_TO_STORE ();
-#endif
-}
-
-static void
-gnu_open (char *arg, int from_tty)
-{
-  error (_("Use the \"run\" command to start a Unix child process."));
+  gdb_assert (gnu_current_inf);
+  child_terminal_init_with_pgrp (gnu_current_inf->pid);
 }
 
 static void
-gnu_stop (void)
+gnu_stop (struct target_ops *self, ptid_t ptid)
 {
   error (_("to_stop target function not implemented"));
 }
 
-static char *
-gnu_pid_to_exec_file (int pid)
-{
-  error (_("to_pid_to_exec_file target function not implemented"));
-  return NULL;
-}
-
-
 static int
-gnu_thread_alive (ptid_t tid)
+gnu_thread_alive (struct target_ops *ops, ptid_t ptid)
 {
-  inf_update_procs (current_inferior);
-  return !!inf_tid_to_thread (current_inferior, PIDGET (tid));
+  inf_update_procs (gnu_current_inf);
+  return !!inf_tid_to_thread (gnu_current_inf,
+                             ptid_get_lwp (ptid));
 }
 
 \f
 /* Read inferior task's LEN bytes from ADDR and copy it to MYADDR in
    gdb's address space.  Return 0 on failure; number of bytes read
    otherwise.  */
-int
-gnu_read_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
+static int
+gnu_read_inferior (task_t task, CORE_ADDR addr, gdb_byte *myaddr, int length)
 {
   error_t err;
   vm_address_t low_address = (vm_address_t) trunc_page (addr);
   vm_size_t aligned_length =
   (vm_size_t) round_page (addr + length) - low_address;
   pointer_t copied;
-  int copy_count;
+  mach_msg_type_number_t copy_count;
 
-  /* Get memory from inferior with page aligned addresses */
+  /* Get memory from inferior with page aligned addresses */
   err = vm_read (task, low_address, aligned_length, &copied, &copy_count);
   if (err)
     return 0;
 
-  err = hurd_safe_copyin (myaddr, (void *) addr - low_address + copied, length);
+  err = hurd_safe_copyin (myaddr, (void *) (addr - low_address + copied),
+                         length);
   if (err)
     {
       warning (_("Read from inferior faulted: %s"), safe_strerror (err));
@@ -2263,7 +2308,8 @@ gnu_read_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
 
   err = vm_deallocate (mach_task_self (), copied, copy_count);
   if (err)
-    warning (_("gnu_read_inferior vm_deallocate failed: %s"), safe_strerror (err));
+    warning (_("gnu_read_inferior vm_deallocate failed: %s"),
+            safe_strerror (err));
 
   return length;
 }
@@ -2283,23 +2329,24 @@ struct obstack region_obstack;
 
 /* Write gdb's LEN bytes from MYADDR and copy it to ADDR in inferior
    task's address space.  */
-int
-gnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
+static int
+gnu_write_inferior (task_t task, CORE_ADDR addr,
+                   const gdb_byte *myaddr, int length)
 {
   error_t err = 0;
   vm_address_t low_address = (vm_address_t) trunc_page (addr);
   vm_size_t aligned_length =
   (vm_size_t) round_page (addr + length) - low_address;
   pointer_t copied;
-  int copy_count;
+  mach_msg_type_number_t copy_count;
   int deallocate = 0;
 
   char *errstr = "Bug in gnu_write_inferior";
 
   struct vm_region_list *region_element;
-  struct vm_region_list *region_head = (struct vm_region_list *) NULL;
+  struct vm_region_list *region_head = NULL;
 
-  /* Get memory from inferior with page aligned addresses */
+  /* Get memory from inferior with page aligned addresses */
   err = vm_read (task,
                 low_address,
                 aligned_length,
@@ -2309,7 +2356,7 @@ gnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
 
   deallocate++;
 
-  err = hurd_safe_copyout ((void *) addr - low_address + copied,
+  err = hurd_safe_copyout ((void *) (addr - low_address + copied),
                           myaddr, length);
   CHK_GOTO_OUT ("Write to inferior faulted", err);
 
@@ -2345,10 +2392,10 @@ gnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
                         &offset);
        CHK_GOTO_OUT ("vm_region failed", err);
 
-       /* Check for holes in memory */
+       /* Check for holes in memory */
        if (old_address != region_address)
          {
-           warning (_("No memory at 0x%x. Nothing written"),
+           warning (_("No memory at 0x%lx. Nothing written"),
                     old_address);
            err = KERN_SUCCESS;
            length = 0;
@@ -2357,23 +2404,22 @@ gnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
 
        if (!(max_protection & VM_PROT_WRITE))
          {
-           warning (_("Memory at address 0x%x is unwritable. Nothing written"),
+           warning (_("Memory at address 0x%lx is unwritable. "
+                      "Nothing written"),
                     old_address);
            err = KERN_SUCCESS;
            length = 0;
            goto out;
          }
 
-       /* Chain the regions for later use */
-       region_element =
-         (struct vm_region_list *)
-         obstack_alloc (&region_obstack, sizeof (struct vm_region_list));
+       /* Chain the regions for later use.  */
+       region_element = XOBNEW (&region_obstack, struct vm_region_list);
 
        region_element->protection = protection;
        region_element->start = region_address;
        region_element->length = region_length;
 
-       /* Chain the regions along with protections */
+       /* Chain the regions along with protections */
        region_element->next = region_head;
        region_head = region_element;
 
@@ -2384,7 +2430,7 @@ gnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
     /* If things fail after this, we give up.
        Somebody is messing up inferior_task's mappings.  */
 
-    /* Enable writes to the chained vm regions */
+    /* Enable writes to the chained vm regions */
     for (scan = region_head; scan; scan = scan->next)
       {
        if (!(scan->protection & VM_PROT_WRITE))
@@ -2404,7 +2450,7 @@ gnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
                    aligned_length);
     CHK_GOTO_OUT ("vm_write failed", err);
 
-    /* Set up the original region protections, if they were changed */
+    /* Set up the original region protections, if they were changed */
     for (scan = region_head; scan; scan = scan->next)
       {
        if (!(scan->protection & VM_PROT_WRITE))
@@ -2439,48 +2485,77 @@ out:
 }
 
 \f
-/* Return 0 on failure, number of bytes handled otherwise.  TARGET
-   is ignored. */
-static int
-gnu_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
-                struct mem_attrib *attrib,
-                struct target_ops *target)
+
+/* Implement the to_xfer_partial target_ops method for
+   TARGET_OBJECT_MEMORY.  */
+
+static enum target_xfer_status
+gnu_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
+                CORE_ADDR memaddr, ULONGEST len, ULONGEST *xfered_len)
 {
-  task_t task = (current_inferior
-                ? (current_inferior->task
-                   ? current_inferior->task->port : 0)
+  task_t task = (gnu_current_inf
+                ? (gnu_current_inf->task
+                   ? gnu_current_inf->task->port : 0)
                 : 0);
+  int res;
 
   if (task == MACH_PORT_NULL)
-    return 0;
+    return TARGET_XFER_E_IO;
+
+  if (writebuf != NULL)
+    {
+      inf_debug (gnu_current_inf, "writing %s[%s] <-- %s",
+                paddress (target_gdbarch (), memaddr), pulongest (len),
+                host_address_to_string (writebuf));
+      res = gnu_write_inferior (task, memaddr, writebuf, len);
+    }
   else
     {
-      inf_debug (current_inferior, "%s %p[%d] %s %p",
-                write ? "writing" : "reading", (void *) memaddr, len,
-                write ? "<--" : "-->", myaddr);
-      if (write)
-       return gnu_write_inferior (task, memaddr, myaddr, len);
-      else
-       return gnu_read_inferior (task, memaddr, myaddr, len);
+      inf_debug (gnu_current_inf, "reading %s[%s] --> %s",
+                paddress (target_gdbarch (), memaddr), pulongest (len),
+                host_address_to_string (readbuf));
+      res = gnu_read_inferior (task, memaddr, readbuf, len);
+    }
+  gdb_assert (res >= 0);
+  if (res == 0)
+    return TARGET_XFER_E_IO;
+  else
+    {
+      *xfered_len = (ULONGEST) res;
+      return TARGET_XFER_OK;
+    }
+}
+
+/* Target to_xfer_partial implementation.  */
+
+static enum target_xfer_status
+gnu_xfer_partial (struct target_ops *ops, enum target_object object,
+                 const char *annex, gdb_byte *readbuf,
+                 const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+                 ULONGEST *xfered_len)
+{
+  switch (object)
+    {
+    case TARGET_OBJECT_MEMORY:
+      return gnu_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
+    default:
+      return TARGET_XFER_E_IO;
     }
 }
 
 /* Call FUNC on each memory region in the task.  */
 static int
-gnu_find_memory_regions (int (*func) (CORE_ADDR,
-                                     unsigned long,
-                                     int, int, int,
-                                     void *),
-                        void *data)
+gnu_find_memory_regions (struct target_ops *self,
+                        find_memory_region_ftype func, void *data)
 {
   error_t err;
   task_t task;
   vm_address_t region_address, last_region_address, last_region_end;
   vm_prot_t last_protection;
 
-  if (current_inferior == 0 || current_inferior->task == 0)
+  if (gnu_current_inf == 0 || gnu_current_inf->task == 0)
     return 0;
-  task = current_inferior->task->port;
+  task = gnu_current_inf->task->port;
   if (task == MACH_PORT_NULL)
     return 0;
 
@@ -2528,6 +2603,7 @@ gnu_find_memory_regions (int (*func) (CORE_ADDR,
                     last_protection & VM_PROT_READ,
                     last_protection & VM_PROT_WRITE,
                     last_protection & VM_PROT_EXECUTE,
+                    1, /* MODIFIED is unknown, pass it as true.  */
                     data);
          last_region_address = region_address;
          last_region_end = region_address += region_length;
@@ -2541,6 +2617,7 @@ gnu_find_memory_regions (int (*func) (CORE_ADDR,
             last_protection & VM_PROT_READ,
             last_protection & VM_PROT_WRITE,
             last_protection & VM_PROT_EXECUTE,
+            1, /* MODIFIED is unknown, pass it as true.  */
             data);
 
   return 0;
@@ -2552,19 +2629,20 @@ char *
 proc_string (struct proc *proc)
 {
   static char tid_str[80];
+
   if (proc_is_task (proc))
-    sprintf (tid_str, "process %d", proc->inf->pid);
+    xsnprintf (tid_str, sizeof (tid_str), "process %d", proc->inf->pid);
   else
-    sprintf (tid_str, "thread %d.%d",
-            proc->inf->pid, pid_to_thread_id (MERGEPID (proc->tid, 0)));
+    xsnprintf (tid_str, sizeof (tid_str), "Thread %d.%d",
+              proc->inf->pid, proc->tid);
   return tid_str;
 }
 
 static char *
-gnu_pid_to_str (ptid_t ptid)
+gnu_pid_to_str (struct target_ops *ops, ptid_t ptid)
 {
-  struct inf *inf = current_inferior;
-  int tid = PIDGET (ptid);
+  struct inf *inf = gnu_current_inf;
+  int tid = ptid_get_lwp (ptid);
   struct proc *thread = inf_tid_to_thread (inf, tid);
 
   if (thread)
@@ -2572,63 +2650,44 @@ gnu_pid_to_str (ptid_t ptid)
   else
     {
       static char tid_str[80];
-      sprintf (tid_str, "bogus thread id %d", tid);
+
+      xsnprintf (tid_str, sizeof (tid_str), "bogus thread id %d", tid);
       return tid_str;
     }
 }
 
 \f
-extern void gnu_store_registers (int regno);
-extern void gnu_fetch_registers (int regno);
+/* Create a prototype generic GNU/Hurd target.  The client can
+   override it with local methods.  */
 
-struct target_ops gnu_ops;
+struct target_ops *
+gnu_target (void)
+{
+  struct target_ops *t = inf_child_target ();
 
-static void
-init_gnu_ops (void)
-{
-  gnu_ops.to_shortname = "GNU";                /* to_shortname */
-  gnu_ops.to_longname = "GNU Hurd process"; /* to_longname */
-  gnu_ops.to_doc = "GNU Hurd process"; /* to_doc */
-  gnu_ops.to_open = gnu_open;          /* to_open */
-  gnu_ops.to_attach = gnu_attach;      /* to_attach */
-  gnu_ops.to_detach = gnu_detach;      /* to_detach */
-  gnu_ops.to_resume = gnu_resume;      /* to_resume */
-  gnu_ops.to_wait = gnu_wait;          /* to_wait */
-  gnu_ops.to_fetch_registers = gnu_fetch_registers;    /* to_fetch_registers */
-  gnu_ops.to_store_registers = gnu_store_registers;    /* to_store_registers */
-  gnu_ops.to_prepare_to_store = gnu_prepare_to_store; /* to_prepare_to_store */
-  gnu_ops.deprecated_xfer_memory = gnu_xfer_memory;
-  gnu_ops.to_find_memory_regions = gnu_find_memory_regions;
-  gnu_ops.to_insert_breakpoint = memory_insert_breakpoint;
-  gnu_ops.to_remove_breakpoint = memory_remove_breakpoint;
-  gnu_ops.to_terminal_init = gnu_terminal_init_inferior;
-  gnu_ops.to_terminal_inferior = terminal_inferior;
-  gnu_ops.to_terminal_ours_for_output = terminal_ours_for_output;
-  gnu_ops.to_terminal_save_ours = terminal_save_ours;
-  gnu_ops.to_terminal_ours = terminal_ours;
-  gnu_ops.to_terminal_info = child_terminal_info;
-  gnu_ops.to_kill = gnu_kill_inferior; /* to_kill */
-  gnu_ops.to_create_inferior = gnu_create_inferior; /* to_create_inferior */
-  gnu_ops.to_mourn_inferior = gnu_mourn_inferior;      /* to_mourn_inferior */
-  gnu_ops.to_can_run = gnu_can_run;    /* to_can_run */
-  gnu_ops.to_thread_alive = gnu_thread_alive;  /* to_thread_alive */
-  gnu_ops.to_pid_to_str = gnu_pid_to_str;   /* to_pid_to_str */
-  gnu_ops.to_stop = gnu_stop;  /* to_stop */
-  gnu_ops.to_pid_to_exec_file = gnu_pid_to_exec_file; /* to_pid_to_exec_file */
-  gnu_ops.to_stratum = process_stratum;                /* to_stratum */
-  gnu_ops.to_has_all_memory = 1;       /* to_has_all_memory */
-  gnu_ops.to_has_memory = 1;           /* to_has_memory */
-  gnu_ops.to_has_stack = 1;            /* to_has_stack */
-  gnu_ops.to_has_registers = 1;                /* to_has_registers */
-  gnu_ops.to_has_execution = 1;                /* to_has_execution */
-  gnu_ops.to_magic = OPS_MAGIC;                /* to_magic */
-}                              /* init_gnu_ops */
+  t->to_attach = gnu_attach;
+  t->to_attach_no_wait = 1;
+  t->to_detach = gnu_detach;
+  t->to_resume = gnu_resume;
+  t->to_wait = gnu_wait;
+  t->to_xfer_partial = gnu_xfer_partial;
+  t->to_find_memory_regions = gnu_find_memory_regions;
+  t->to_terminal_init = gnu_terminal_init;
+  t->to_kill = gnu_kill_inferior;
+  t->to_create_inferior = gnu_create_inferior;
+  t->to_mourn_inferior = gnu_mourn_inferior;
+  t->to_thread_alive = gnu_thread_alive;
+  t->to_pid_to_str = gnu_pid_to_str;
+  t->to_stop = gnu_stop;
+
+  return t;
+}
 
 \f
 /* User task commands.  */
 
-struct cmd_list_element *set_task_cmd_list = 0;
-struct cmd_list_element *show_task_cmd_list = 0;
+static struct cmd_list_element *set_task_cmd_list = 0;
+static struct cmd_list_element *show_task_cmd_list = 0;
 /* User thread commands.  */
 
 /* Commands with a prefix of `set/show thread'.  */
@@ -2643,25 +2702,29 @@ struct cmd_list_element *show_thread_default_cmd_list = NULL;
 static void
 set_thread_cmd (char *args, int from_tty)
 {
-  printf_unfiltered ("\"set thread\" must be followed by the name of a thread property, or \"default\".\n");
+  printf_unfiltered ("\"set thread\" must be followed by the "
+                    "name of a thread property, or \"default\".\n");
 }
 
 static void
 show_thread_cmd (char *args, int from_tty)
 {
-  printf_unfiltered ("\"show thread\" must be followed by the name of a thread property, or \"default\".\n");
+  printf_unfiltered ("\"show thread\" must be followed by the "
+                    "name of a thread property, or \"default\".\n");
 }
 
 static void
 set_thread_default_cmd (char *args, int from_tty)
 {
-  printf_unfiltered ("\"set thread default\" must be followed by the name of a thread property.\n");
+  printf_unfiltered ("\"set thread default\" must be followed "
+                    "by the name of a thread property.\n");
 }
 
 static void
 show_thread_default_cmd (char *args, int from_tty)
 {
-  printf_unfiltered ("\"show thread default\" must be followed by the name of a thread property.\n");
+  printf_unfiltered ("\"show thread default\" must be followed "
+                    "by the name of a thread property.\n");
 }
 
 static int
@@ -2671,10 +2734,12 @@ parse_int_arg (char *args, char *cmd_prefix)
     {
       char *arg_end;
       int val = strtoul (args, &arg_end, 10);
+
       if (*args && *arg_end == '\0')
        return val;
     }
-  error (_("Illegal argument for \"%s\" command, should be an integer."), cmd_prefix);
+  error (_("Illegal argument for \"%s\" command, should be an integer."),
+        cmd_prefix);
 }
 
 static int
@@ -2685,7 +2750,8 @@ _parse_bool_arg (char *args, char *t_val, char *f_val, char *cmd_prefix)
   else if (strcmp (args, f_val) == 0)
     return 0;
   else
-    error (_("Illegal argument for \"%s\" command, should be \"%s\" or \"%s\"."),
+    error (_("Illegal argument for \"%s\" command, "
+            "should be \"%s\" or \"%s\"."),
           cmd_prefix, t_val, f_val);
 }
 
@@ -2704,7 +2770,8 @@ static struct proc *
 cur_thread (void)
 {
   struct inf *inf = cur_inf ();
-  struct proc *thread = inf_tid_to_thread (inf, PIDGET (inferior_ptid));
+  struct proc *thread = inf_tid_to_thread (inf,
+                                          ptid_get_lwp (inferior_ptid));
   if (!thread)
     error (_("No current thread."));
   return thread;
@@ -2715,6 +2782,7 @@ static struct inf *
 active_inf (void)
 {
   struct inf *inf = cur_inf ();
+
   if (!inf->task)
     error (_("No current process."));
   return inf;
@@ -2739,6 +2807,7 @@ static void
 show_task_pause_cmd (char *args, int from_tty)
 {
   struct inf *inf = cur_inf ();
+
   check_empty (args, "show task pause");
   printf_unfiltered ("The inferior task %s suspended while gdb has control.\n",
                     inf->task
@@ -2749,14 +2818,16 @@ show_task_pause_cmd (char *args, int from_tty)
 static void
 set_task_detach_sc_cmd (char *args, int from_tty)
 {
-  cur_inf ()->detach_sc = parse_int_arg (args, "set task detach-suspend-count");
+  cur_inf ()->detach_sc = parse_int_arg (args,
+                                        "set task detach-suspend-count");
 }
 
 static void
 show_task_detach_sc_cmd (char *args, int from_tty)
 {
   check_empty (args, "show task detach-suspend-count");
-  printf_unfiltered ("The inferior task will be left with a suspend count of %d when detaching.\n",
+  printf_unfiltered ("The inferior task will be left with a "
+                    "suspend count of %d when detaching.\n",
                     cur_inf ()->detach_sc);
 }
 
@@ -2765,6 +2836,7 @@ static void
 set_thread_default_pause_cmd (char *args, int from_tty)
 {
   struct inf *inf = cur_inf ();
+
   inf->default_thread_pause_sc =
     parse_bool_arg (args, "set thread default pause") ? 0 : 1;
 }
@@ -2774,6 +2846,7 @@ show_thread_default_pause_cmd (char *args, int from_tty)
 {
   struct inf *inf = cur_inf ();
   int sc = inf->default_thread_pause_sc;
+
   check_empty (args, "show thread default pause");
   printf_unfiltered ("New threads %s suspended while gdb has control%s.\n",
                     sc ? "are" : "aren't",
@@ -2784,6 +2857,7 @@ static void
 set_thread_default_run_cmd (char *args, int from_tty)
 {
   struct inf *inf = cur_inf ();
+
   inf->default_thread_run_sc =
     parse_bool_arg (args, "set thread default run") ? 0 : 1;
 }
@@ -2792,6 +2866,7 @@ static void
 show_thread_default_run_cmd (char *args, int from_tty)
 {
   struct inf *inf = cur_inf ();
+
   check_empty (args, "show thread default run");
   printf_unfiltered ("New threads %s allowed to run.\n",
                     inf->default_thread_run_sc == 0 ? "are" : "aren't");
@@ -2829,7 +2904,7 @@ steal_exc_port (struct proc *proc, mach_port_t name)
                                 name, MACH_MSG_TYPE_COPY_SEND,
                                 &port, &port_type);
   if (err)
-    error (_("Couldn't extract send right %d from inferior: %s"),
+    error (_("Couldn't extract send right %lu from inferior: %s"),
           name, safe_strerror (err));
 
   if (proc->saved_exc_port)
@@ -2839,8 +2914,9 @@ steal_exc_port (struct proc *proc, mach_port_t name)
   proc->saved_exc_port = port;
 
   if (!proc->exc_port)
-    /* If PROC is a thread, we may not have set its exception port before.
-       We can't use proc_steal_exc_port because it also sets saved_exc_port. */
+    /* If PROC is a thread, we may not have set its exception port
+       before.  We can't use proc_steal_exc_port because it also sets
+       saved_exc_port.  */
     {
       proc->exc_port = proc->inf->event_port;
       err = proc_set_exception_port (proc, proc->exc_port);
@@ -2853,6 +2929,7 @@ static void
 set_task_exc_port_cmd (char *args, int from_tty)
 {
   struct inf *inf = cur_inf ();
+
   if (!args)
     error (_("No argument to \"set task exception-port\" command."));
   steal_exc_port (inf->task, parse_and_eval_address (args));
@@ -2868,6 +2945,7 @@ static void
 show_stopped_cmd (char *args, int from_tty)
 {
   struct inf *inf = active_inf ();
+
   check_empty (args, "show stopped");
   printf_unfiltered ("The inferior process %s stopped.\n",
                     inf->stopped ? "is" : "isn't");
@@ -2886,11 +2964,13 @@ set_sig_thread_cmd (char *args, int from_tty)
     inf->signal_thread = 0;
   else
     {
-      int tid = PIDGET (thread_id_to_pid (atoi (args)));
-      if (tid < 0)
-       error (_("Thread ID %s not known.  Use the \"info threads\" command to\n"
+      ptid_t ptid = thread_id_to_pid (atoi (args));
+
+      if (ptid_equal (ptid, minus_one_ptid))
+       error (_("Thread ID %s not known.  "
+                "Use the \"info threads\" command to\n"
               "see the IDs of currently known threads."), args);
-      inf->signal_thread = inf_tid_to_thread (inf, tid);
+      inf->signal_thread = inf_tid_to_thread (inf, ptid_get_lwp (ptid));
     }
 }
 
@@ -2898,6 +2978,7 @@ static void
 show_sig_thread_cmd (char *args, int from_tty)
 {
   struct inf *inf = active_inf ();
+
   check_empty (args, "show signal-thread");
   if (inf->signal_thread)
     printf_unfiltered ("The signal thread is %s.\n",
@@ -2923,6 +3004,7 @@ static void
 show_signals_cmd (char *args, int from_tty)
 {
   struct inf *inf = cur_inf ();
+
   check_empty (args, "show signals");
   printf_unfiltered ("The inferior process's signals %s intercepted.\n",
                     inf->task
@@ -2936,9 +3018,8 @@ set_exceptions_cmd (char *args, int from_tty)
   struct inf *inf = cur_inf ();
   int val = parse_bool_arg (args, "set exceptions");
 
-  if (inf->task && inf->want_exceptions != val)
-    /* Make this take effect immediately in a running process.  */
-    /* XXX */ ;
+  /* Make this take effect immediately in a running process.  */
+  /* XXX */ ;
 
   inf->want_exceptions = val;
 }
@@ -2947,6 +3028,7 @@ static void
 show_exceptions_cmd (char *args, int from_tty)
 {
   struct inf *inf = cur_inf ();
+
   check_empty (args, "show exceptions");
   printf_unfiltered ("Exceptions in the inferior %s trapped.\n",
                     inf->task
@@ -3003,7 +3085,7 @@ set_noninvasive_cmd (char *args, int from_tty)
 
 \f
 static void
-info_port_rights (char *args, mach_port_type_t only)
+info_port_rights (const char *args, mach_port_type_t only)
 {
   struct inf *inf = active_inf ();
   struct value *vmark = value_mark ();
@@ -3016,8 +3098,9 @@ info_port_rights (char *args, mach_port_type_t only)
          struct value *val = parse_to_comma_and_eval (&args);
          long right = value_as_long (val);
          error_t err =
-         print_port_info (right, 0, inf->task->port, PORTINFO_DETAILS,
-                          stdout);
+           print_port_info (right, 0, inf->task->port, PORTINFO_DETAILS,
+                            stdout);
+
          if (err)
            error (_("%ld: %s."), right, safe_strerror (err));
        }
@@ -3026,8 +3109,8 @@ info_port_rights (char *args, mach_port_type_t only)
     /* Print all of them.  */
     {
       error_t err =
-      print_task_ports_info (inf->task->port, only, PORTINFO_DETAILS,
-                            stdout);
+       print_task_ports_info (inf->task->port, only, PORTINFO_DETAILS,
+                              stdout);
       if (err)
        error (_("%s."), safe_strerror (err));
     }
@@ -3117,7 +3200,7 @@ Set the thread that gdb thinks is the libc signal thread."),
 Set whether gdb thinks the inferior process is stopped as with SIGSTOP.\n\
 Stopped process will be continued by sending them a signal."),
           &setlist);
-  add_cmd ("stopped", no_class, show_signals_cmd, _("\
+  add_cmd ("stopped", no_class, show_stopped_cmd, _("\
 Show whether gdb thinks the inferior process is stopped as with SIGSTOP."),
           &showlist);
 
@@ -3133,10 +3216,10 @@ Show whether exceptions in the inferior process will be trapped."),
           &showlist);
 
   add_prefix_cmd ("task", no_class, set_task_cmd,
-                 "Command prefix for setting task attributes.",
+                 _("Command prefix for setting task attributes."),
                  &set_task_cmd_list, "set task ", 0, &setlist);
   add_prefix_cmd ("task", no_class, show_task_cmd,
-                 "Command prefix for showing task attributes.",
+                 _("Command prefix for showing task attributes."),
                  &show_task_cmd_list, "show task ", 0, &showlist);
 
   add_cmd ("pause", class_run, set_task_pause_cmd, _("\
@@ -3154,7 +3237,8 @@ used to pause individual threads by default instead."),
           _("Set the suspend count will leave on the thread when detaching."),
           &set_task_cmd_list);
   add_cmd ("detach-suspend-count", no_class, show_task_detach_sc_cmd,
-          _("Show the suspend count will leave on the thread when detaching."),
+          _("Show the suspend count will leave "
+            "on the thread when detaching."),
           &show_task_cmd_list);
 
   add_cmd ("exception-port", no_class, set_task_exc_port_cmd, _("\
@@ -3174,21 +3258,16 @@ This is the same as setting `task pause', `exceptions', and\n\
           &setlist);
 
   /* Commands to show information about the task's ports.  */
-  add_cmd ("send-rights", class_info, info_send_rights_cmd,
-          _("Show information about the task's send rights"),
-          &infolist);
-  add_cmd ("receive-rights", class_info, info_recv_rights_cmd,
-          _("Show information about the task's receive rights"),
-          &infolist);
-  add_cmd ("port-rights", class_info, info_port_rights_cmd,
-          _("Show information about the task's port rights"),
-          &infolist);
-  add_cmd ("port-sets", class_info, info_port_sets_cmd,
-          _("Show information about the task's port sets"),
-          &infolist);
-  add_cmd ("dead-names", class_info, info_dead_names_cmd,
-          _("Show information about the task's dead names"),
-          &infolist);
+  add_info ("send-rights", info_send_rights_cmd,
+           _("Show information about the task's send rights"));
+  add_info ("receive-rights", info_recv_rights_cmd,
+           _("Show information about the task's receive rights"));
+  add_info ("port-rights", info_port_rights_cmd,
+           _("Show information about the task's port rights"));
+  add_info ("port-sets", info_port_sets_cmd,
+           _("Show information about the task's port sets"));
+  add_info ("dead-names", info_dead_names_cmd,
+           _("Show information about the task's dead names"));
   add_info_alias ("ports", "port-rights", 1);
   add_info_alias ("port", "port-rights", 1);
   add_info_alias ("psets", "port-sets", 1);
@@ -3200,6 +3279,7 @@ set_thread_pause_cmd (char *args, int from_tty)
 {
   struct proc *thread = cur_thread ();
   int old_sc = thread->pause_sc;
+
   thread->pause_sc = parse_bool_arg (args, "set thread pause");
   if (old_sc == 0 && thread->pause_sc != 0 && thread->inf->pause_sc == 0)
     /* If the task is currently unsuspended, immediately suspend it,
@@ -3212,6 +3292,7 @@ show_thread_pause_cmd (char *args, int from_tty)
 {
   struct proc *thread = cur_thread ();
   int sc = thread->pause_sc;
+
   check_empty (args, "show task pause");
   printf_unfiltered ("Thread %s %s suspended while gdb has control%s.\n",
                     proc_string (thread),
@@ -3223,6 +3304,7 @@ static void
 set_thread_run_cmd (char *args, int from_tty)
 {
   struct proc *thread = cur_thread ();
+
   thread->run_sc = parse_bool_arg (args, "set thread run") ? 0 : 1;
 }
 
@@ -3230,6 +3312,7 @@ static void
 show_thread_run_cmd (char *args, int from_tty)
 {
   struct proc *thread = cur_thread ();
+
   check_empty (args, "show thread run");
   printf_unfiltered ("Thread %s %s allowed to run.",
                     proc_string (thread),
@@ -3247,6 +3330,7 @@ static void
 show_thread_detach_sc_cmd (char *args, int from_tty)
 {
   struct proc *thread = cur_thread ();
+
   check_empty (args, "show thread detach-suspend-count");
   printf_unfiltered ("Thread %s will be left with a suspend count"
                     " of %d when detaching.\n",
@@ -3258,6 +3342,7 @@ static void
 set_thread_exc_port_cmd (char *args, int from_tty)
 {
   struct proc *thread = cur_thread ();
+
   if (!args)
     error (_("No argument to \"set thread exception-port\" command."));
   steal_exc_port (thread, parse_and_eval_address (args));
@@ -3268,6 +3353,7 @@ static void
 show_thread_cmd (char *args, int from_tty)
 {
   struct proc *thread = cur_thread ();
+
   check_empty (args, "show thread");
   show_thread_run_cmd (0, from_tty);
   show_thread_pause_cmd (0, from_tty);
@@ -3280,6 +3366,7 @@ static void
 thread_takeover_sc_cmd (char *args, int from_tty)
 {
   struct proc *thread = cur_thread ();
+
   thread_basic_info_data_t _info;
   thread_basic_info_t info = &_info;
   mach_msg_type_number_t info_len = THREAD_BASIC_INFO_COUNT;
@@ -3300,17 +3387,17 @@ static void
 add_thread_commands (void)
 {
   add_prefix_cmd ("thread", no_class, set_thread_cmd,
-                 "Command prefix for setting thread properties.",
+                 _("Command prefix for setting thread properties."),
                  &set_thread_cmd_list, "set thread ", 0, &setlist);
   add_prefix_cmd ("default", no_class, show_thread_cmd,
-                 "Command prefix for setting default thread properties.",
+                 _("Command prefix for setting default thread properties."),
                  &set_thread_default_cmd_list, "set thread default ", 0,
                  &set_thread_cmd_list);
   add_prefix_cmd ("thread", no_class, set_thread_default_cmd,
-                 "Command prefix for showing thread properties.",
+                 _("Command prefix for showing thread properties."),
                  &show_thread_cmd_list, "show thread ", 0, &showlist);
   add_prefix_cmd ("default", no_class, show_thread_default_cmd,
-                 "Command prefix for showing default thread properties.",
+                 _("Command prefix for showing default thread properties."),
                  &show_thread_default_cmd_list, "show thread default ", 0,
                  &show_thread_cmd_list);
 
@@ -3361,19 +3448,26 @@ to the thread's initial suspend-count when gdb notices the threads."),
 }
 
 \f
+
+/* -Wmissing-prototypes */
+extern initialize_file_ftype _initialize_gnu_nat;
+
 void
 _initialize_gnu_nat (void)
 {
   proc_server = getproc ();
-  
-  init_gnu_ops ();
-  add_target (&gnu_ops);
 
   add_task_commands ();
   add_thread_commands ();
-  add_set_cmd ("gnu-debug", class_maintenance,
-              var_boolean, (char *) &gnu_debug_flag,
-              "Set debugging output for the gnu backend.", &maintenancelist);
+  add_setshow_boolean_cmd ("gnu-nat", class_maintenance,
+                          &gnu_debug_flag,
+                          _("Set debugging output for the gnu backend."),
+                          _("Show debugging output for the gnu backend."),
+                          NULL,
+                          NULL,
+                          NULL,
+                          &setdebuglist,
+                          &showdebuglist);
 }
 \f
 #ifdef FLUSH_INFERIOR_CACHE
@@ -3381,7 +3475,7 @@ _initialize_gnu_nat (void)
 /* When over-writing code on some machines the I-Cache must be flushed
    explicitly, because it is not kept coherent by the lazy hardware.
    This definitely includes breakpoints, for instance, or else we
-   end up looping in mysterious Bpt traps */
+   end up looping in mysterious Bpt traps */
 
 void
 flush_inferior_icache (CORE_ADDR pc, int amount)
@@ -3389,7 +3483,7 @@ flush_inferior_icache (CORE_ADDR pc, int amount)
   vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH;
   error_t ret;
 
-  ret = vm_machine_attribute (current_inferior->task->port,
+  ret = vm_machine_attribute (gnu_current_inf->task->port,
                              pc,
                              amount,
                              MATTR_CACHE,