Replacing a bogus file with a semi-bogus one (sharing through devo).
[deliverable/binutils-gdb.git] / gdb / m3-nat.c
index 348b363a5fb6685d0ee5a54721f2951399248ff4..c1719450adb7c9a9e00e1cf01df6f81bec4ce231 100644 (file)
@@ -1,7 +1,7 @@
 /* Interface GDB to Mach 3.0 operating systems.
    (Most) Mach 3.0 related routines live in this file.
 
-   Copyright (C) 1992 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1996 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -17,7 +17,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /*
  * Author: Jukka Virtanen <jtv@hut.fi>
@@ -54,9 +54,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "target.h"
 #include "wait.h"
 #include "gdbcmd.h"
-#include "gdb-threads.h"
+#include "gdbcore.h"
 
+#if 0
 #include <servers/machid_lib.h>
+#else
+#define        MACH_TYPE_TASK                  1
+#define MACH_TYPE_THREAD               2
+#endif
 
 /* Included only for signal names and NSIG
  *
@@ -66,7 +71,71 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <signal.h>
 #define SIG_UNKNOWN 0  /* Exception that has no matching unix signal */
 
-#define private static
+#include <cthreads.h>
+
+/* This is what a cproc looks like.  This is here partly because
+   cthread_internals.h is not a header we can just #include, partly with
+   an eye towards perhaps getting this to work with cross-debugging
+   someday.  Best solution is if CMU publishes a real interface to this
+   stuff.  */
+#define CPROC_NEXT_OFFSET 0
+#define CPROC_NEXT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT)
+#define CPROC_INCARNATION_OFFSET (CPROC_NEXT_OFFSET + CPROC_NEXT_SIZE)
+#define CPROC_INCARNATION_SIZE (sizeof (cthread_t))
+#define CPROC_LIST_OFFSET (CPROC_INCARNATION_OFFSET + CPROC_INCARNATION_SIZE)
+#define CPROC_LIST_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT)
+#define CPROC_WAIT_OFFSET (CPROC_LIST_OFFSET + CPROC_LIST_SIZE)
+#define CPROC_WAIT_SIZE (TARGET_PTR_BIT / HOST_CHAR_BIT)
+#define CPROC_REPLY_OFFSET (CPROC_WAIT_OFFSET + CPROC_WAIT_SIZE)
+#define CPROC_REPLY_SIZE (sizeof (mach_port_t))
+#define CPROC_CONTEXT_OFFSET (CPROC_REPLY_OFFSET + CPROC_REPLY_SIZE)
+#define CPROC_CONTEXT_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_LOCK_OFFSET (CPROC_CONTEXT_OFFSET + CPROC_CONTEXT_SIZE)
+#define CPROC_LOCK_SIZE (sizeof (spin_lock_t))
+#define CPROC_STATE_OFFSET (CPROC_LOCK_OFFSET + CPROC_LOCK_SIZE)
+#define CPROC_STATE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_WIRED_OFFSET (CPROC_STATE_OFFSET + CPROC_STATE_SIZE)
+#define CPROC_WIRED_SIZE (sizeof (mach_port_t))
+#define CPROC_BUSY_OFFSET (CPROC_WIRED_OFFSET + CPROC_WIRED_SIZE)
+#define CPROC_BUSY_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_MSG_OFFSET (CPROC_BUSY_OFFSET + CPROC_BUSY_SIZE)
+#define CPROC_MSG_SIZE (sizeof (mach_msg_header_t))
+#define CPROC_BASE_OFFSET (CPROC_MSG_OFFSET + CPROC_MSG_SIZE)
+#define CPROC_BASE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_SIZE_OFFSET (CPROC_BASE_OFFSET + CPROC_BASE_SIZE)
+#define CPROC_SIZE_SIZE (TARGET_INT_BIT / HOST_CHAR_BIT)
+#define CPROC_SIZE (CPROC_SIZE_OFFSET + CPROC_SIZE_SIZE)
+
+/* Values for the state field in the cproc.  */
+#define CPROC_RUNNING  0
+#define CPROC_SWITCHING 1
+#define CPROC_BLOCKED  2
+#define CPROC_CONDWAIT 4
+
+/* For cproc and kernel thread mapping */
+typedef struct gdb_thread {
+  mach_port_t  name;
+  CORE_ADDR    sp;
+  CORE_ADDR    pc;
+  CORE_ADDR    fp;
+  boolean_t     in_emulator;
+  int          slotid;
+
+  /* This is for the mthreads list.  It points to the cproc list.
+     Perhaps the two lists should be merged (or perhaps it was a mistake
+     to make them both use a struct gdb_thread).  */
+  struct gdb_thread *cproc;
+
+  /* These are for the cproc list, which is linked through the next field
+     of the struct gdb_thread.  */
+  char raw_cproc[CPROC_SIZE];
+  /* The cthread which is pointed to by the incarnation field from the
+     cproc.  This points to the copy we've read into GDB.  */
+  cthread_t cthread;
+  /* Point back to the mthreads list.  */
+  int reverse_map;
+  struct gdb_thread *next;
+} *gdb_thread_t;
 
 /* 
  * Actions for Mach exceptions.
@@ -117,7 +186,7 @@ char *fmt;
 int a,b,c;
 {
   if (debug_level)
-    message (fmt, a, b, c);
+    warning (fmt, a, b, c);
 }
 
 /* This is in libmach.a */
@@ -190,6 +259,9 @@ int must_suspend_thread = 0;
 #define NULL_CLEANUP (struct cleanup *)0
 struct cleanup *cleanup_step = NULL_CLEANUP;
 
+\f
+extern struct target_ops m3_ops;
+static void m3_kill_inferior ();
 \f
 #if 0
 #define MACH_TYPE_EXCEPTION_PORT       -1
@@ -234,7 +306,7 @@ port_chain_insert (list, name, type)
     {
       if (! MACH_PORT_VALID (mid_server))
        {
-         message ("Machid server port invalid, can not map port 0x%x to MID",
+         warning ("Machid server port invalid, can not map port 0x%x to MID",
                   name);
          mid = name;
        }
@@ -244,13 +316,13 @@ port_chain_insert (list, name, type)
          
          if (ret != KERN_SUCCESS)
            {
-             message ("Can not map name (0x%x) to MID with machid", name);
+             warning ("Can not map name (0x%x) to MID with machid", name);
              mid = name;
            }
        }
     }
   else
-    mid = 3735928559;  /* 0x? :-) */
+    abort ();
 
   new = (port_chain_t) obstack_alloc (port_chain_obstack,
                                      sizeof (struct port_chain));
@@ -323,7 +395,7 @@ int         type;
   
   if (! MACH_PORT_VALID (mid_server))
     {
-      message ("Machid server port invalid, can not map port 0x%x to mid",
+      warning ("Machid server port invalid, can not map port 0x%x to mid",
               name);
       return -1;
     }
@@ -336,7 +408,7 @@ int         type;
       
       if (ret != KERN_SUCCESS)
        {
-         message ("Can not map name (0x%x) to mid with machid", name);
+         warning ("Can not map name (0x%x) to mid with machid", name);
          return -1;
        }
       return mid;
@@ -344,7 +416,7 @@ int         type;
 }
 \f
 /* Guard for currently_waiting_for and singlestepped_thread_port */
-private void
+static void
 discard_single_step (thread)
      thread_t thread;
 {
@@ -375,7 +447,7 @@ setup_single_step (thread, start_step)
        {
          if (MACH_PORT_VALID (singlestepped_thread_port))
            {
-             message ("Singlestepped_thread_port (0x%x) is still valid?",
+             warning ("Singlestepped_thread_port (0x%x) is still valid?",
                       singlestepped_thread_port);
              singlestepped_thread_port = MACH_PORT_NULL;
            }
@@ -444,7 +516,7 @@ setup_single_step (thread, start_step)
     }
 }
 \f
-private
+static
 request_notify (name, variant, type)
      mach_port_t       name;
      mach_msg_id_t     variant;
@@ -511,7 +583,8 @@ mach_port_t original_server_port_name = MACH_PORT_NULL;
 
 
 /* Called from inferior after FORK but before EXEC */
-prepare_inferior_task ()
+static void
+m3_trace_me ()
 {
   kern_return_t ret;
   
@@ -545,6 +618,8 @@ void
 intercept_exec_calls (exec_counter)
      int exec_counter;
 {
+  int terminal_initted = 0;
+
   struct syscall_msg_t {
     mach_msg_header_t  header;
     mach_msg_type_t    type;
@@ -679,6 +754,23 @@ intercept_exec_calls (exec_counter)
              original_exec_reply = syscall_in.header.msgh_remote_port;
              syscall_in.header.msgh_remote_port = exec_reply_send;
            }
+
+         if (!terminal_initted)
+           {
+             /* Now that the child has exec'd we know it has already set its
+                process group.  On POSIX systems, tcsetpgrp will fail with
+                EPERM if we try it before the child's setpgid.  */
+
+             /* Set up the "saved terminal modes" of the inferior
+                based on what modes we are starting it with.  */
+             target_terminal_init ();
+
+             /* Install inferior's terminal modes.  */
+             target_terminal_inferior ();
+
+             terminal_initted = 1;
+           }
+
          exec_counter--;
        }
            
@@ -840,7 +932,7 @@ map_slot_to_mid (slot, threads, thread_count)
   return mid;
 }
 
-private int
+static int
 parse_thread_id (arg, thread_count, slots)
      char *arg;
      int thread_count;
@@ -921,8 +1013,8 @@ select_thread (task, thread_id, flag)
   ret = task_threads (task, &thread_list, &thread_count);
   if (ret != KERN_SUCCESS)
     {
-      message ("Can not select a thread from a dead task");
-      kill_inferior ();
+      warning ("Can not select a thread from a dead task");
+      m3_kill_inferior ();
       return KERN_FAILURE;
     }
 
@@ -932,7 +1024,7 @@ select_thread (task, thread_id, flag)
        * exists as a container for memory and ports.
        */
       registers_changed ();
-      message ("Task %d has no threads",
+      warning ("Task %d has no threads",
               map_port_name_to_mid (task, MACH_TYPE_TASK));
       current_thread = MACH_PORT_NULL;
       (void) vm_deallocate(mach_task_self(),
@@ -1010,12 +1102,9 @@ select_thread (task, thread_id, flag)
       CHK ("Could not abort system calls when selecting a thread", ret);
 
       stop_pc = read_pc();
-      set_current_frame (create_new_frame (read_register (FP_REGNUM),
-                                          stop_pc));
+      flush_cached_frames ();
 
       select_frame (get_current_frame (), 0);
-
-      stop_frame_address = FRAME_FP (get_current_frame ());
     }
 
   return KERN_SUCCESS;
@@ -1035,7 +1124,7 @@ switch_to_thread (new_thread)
   mid = map_port_name_to_mid (new_thread,
                              MACH_TYPE_THREAD);
   if (mid == -1)
-    message ("Can't map thread name 0x%x to mid", new_thread);
+    warning ("Can't map thread name 0x%x to mid", new_thread);
   else if (select_thread (inferior_task, mid, 1) != KERN_SUCCESS)
     {
       if (current_thread)
@@ -1049,12 +1138,14 @@ switch_to_thread (new_thread)
 /* Do this in gdb after doing FORK but before STARTUP_INFERIOR.
  * Note that the registers are not yet valid in the inferior task.
  */
-void
-mach_create_inferior_hook (pid)
+static int
+m3_trace_him (pid)
      int pid;
 {
   kern_return_t ret;
 
+  push_target (&m3_ops);
+
   inferior_task = task_by_pid (pid);
 
   if (! MACH_PORT_VALID (inferior_task))
@@ -1079,6 +1170,11 @@ mach_create_inferior_hook (pid)
   setup_exception_port ();
 
   xx_debug ("Now the debugged task is created\n");
+
+  /* One trap to exec the shell, one to exec the program being debugged.  */
+  intercept_exec_calls (2);
+
+  return pid;
 }
 
 setup_exception_port ()
@@ -1142,14 +1238,14 @@ int mach_really_waiting;
    There is no other way to exit this loop.
 
    Returns the inferior_pid for rest of gdb.
-   Side effects: Set unix exit value to *w.
- */
+   Side effects: Set *OURSTATUS.  */
 int
-mach_really_wait (w)
-     WAITTYPE *w;
+mach_really_wait (pid, ourstatus)
+     int pid;
+     struct target_waitstatus *ourstatus;
 {
-  int pid;
   kern_return_t ret;
+  int w;
 
   struct msg {
     mach_msg_header_t    header;
@@ -1191,7 +1287,7 @@ mach_really_wait (w)
            {
              /* Collect Unix exit status for gdb */
 
-             wait3(w, WNOHANG, 0);
+             wait3(&w, WNOHANG, 0);
 
              /* This mess is here to check that the rest of
               * gdb knows that the inferior died. It also
@@ -1200,25 +1296,26 @@ mach_really_wait (w)
               * has happened to it's children when mach-magic
               * is applied on them.
               */
-             if ((!WIFEXITED(*w) && WIFSTOPPED(*w))         ||
-                 (WIFEXITED(*w)  && WEXITSTATUS(*w) > 0377))
+             if ((!WIFEXITED(w) && WIFSTOPPED(w))         ||
+                 (WIFEXITED(w)  && WEXITSTATUS(w) > 0377))
                {
-                 WSETEXIT(*w, 0);
-                 message ("Using exit value 0 for terminated task");
+                 WSETEXIT(w, 0);
+                 warning ("Using exit value 0 for terminated task");
                }
-             else if (!WIFEXITED(*w))
+             else if (!WIFEXITED(w))
                {
-                 int sig = WTERMSIG(*w);
+                 int sig = WTERMSIG(w);
 
                  /* Signals cause problems. Warn the user. */
                  if (sig != SIGKILL) /* Bad luck if garbage matches this */
-                   message ("The terminating signal stuff may be nonsense");
+                   warning ("The terminating signal stuff may be nonsense");
                  else if (sig > NSIG)
                    {
-                     WSETEXIT(*w, 0);
-                     message ("Using exit value 0 for terminated task");
+                     WSETEXIT(w, 0);
+                     warning ("Using exit value 0 for terminated task");
                    }
                }
+             store_waitstatus (ourstatus, w);
              return inferior_pid;
            }
        }
@@ -1249,10 +1346,11 @@ mach_really_wait (w)
       if (stopped_in_exception)
        {
          /* Get unix state. May be changed in mach3_exception_actions() */
-         wait3(w, WNOHANG, 0);
+         wait3(&w, WNOHANG, 0);
 
-         mach3_exception_actions (w, FALSE, "Task");
+         mach3_exception_actions (&w, FALSE, "Task");
 
+         store_waitstatus (ourstatus, w);
          return inferior_pid;
        }
     }
@@ -1273,7 +1371,7 @@ mach3_quit ()
       
       if (ret != KERN_SUCCESS)
        {
-         message ("Could not suspend task for interrupt: %s",
+         warning ("Could not suspend task for interrupt: %s",
                   mach_error_string (ret));
          mach_really_waiting = 0;
          return;
@@ -1286,7 +1384,7 @@ mach3_quit ()
   mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);
   if (mid == -1)
     {
-      message ("Selecting first existing kernel thread");
+      warning ("Selecting first existing kernel thread");
       mid = 0;
     }
 
@@ -1296,6 +1394,9 @@ mach3_quit ()
   return;
 }
 
+#if 0
+/* bogus bogus bogus.  It is NOT OK to quit out of target_wait.  */
+
 /* If ^C is typed when we are waiting for a message
  * and your Unix server is able to notice that we 
  * should quit now.
@@ -1308,6 +1409,7 @@ mach3_request_quit ()
   if (mach_really_waiting)
     immediate_quit = 1;
 }      
+#endif
 
 /*
  * Gdb message server.
@@ -1329,7 +1431,7 @@ gdb_message_server (InP)
       case GDB_MESSAGE_ID_STOP:
        ret = task_suspend (inferior_task);
        if (ret != KERN_SUCCESS)
-         message ("Could not suspend task for stop message: %s",
+         warning ("Could not suspend task for stop message: %s",
                   mach_error_string (ret));
 
        /* QUIT in mach_really_wait() loop. */
@@ -1337,7 +1439,7 @@ gdb_message_server (InP)
        break;
 
       default:
-       message ("Invalid message id %d received, ignored.",
+       warning ("Invalid message id %d received, ignored.",
                 InP->msgh_id);
        break;
       }
@@ -1626,7 +1728,7 @@ catch_exception_raise (port, thread, task, exception, code, subcode)
       if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS)
        error ("Could not select thread %d causing exception", mid);
       else
-       message ("Gdb selected thread %d", mid);
+       warning ("Gdb selected thread %d", mid);
     }
 
   /* If we receive an exception that is not breakpoint
@@ -1636,7 +1738,7 @@ catch_exception_raise (port, thread, task, exception, code, subcode)
   if (MACH_PORT_VALID (singlestepped_thread_port))
     {
       if (stop_exception != EXC_BREAKPOINT)
-       message ("Single step interrupted by exception");
+       warning ("Single step interrupted by exception");
       else if (port == singlestepped_thread_port)
        {
          /* Single step exception occurred, remove trace bit
@@ -1649,7 +1751,7 @@ catch_exception_raise (port, thread, task, exception, code, subcode)
          resume_all_threads (0);
        }
       else
-       message ("Breakpoint while single stepping?");
+       warning ("Breakpoint while single stepping?");
 
       discard_single_step (current_thread);
     }
@@ -1715,7 +1817,7 @@ mach3_read_inferior (addr, myaddr, length)
 
       if (! port_valid (inferior_task, MACH_PORT_TYPE_SEND))
        {
-         kill_inferior ();
+         m3_kill_inferior ();
          error ("Inferior killed (task port invalid)");
        }
       else
@@ -1726,7 +1828,7 @@ mach3_read_inferior (addr, myaddr, length)
             screw it. Eamonn seems to like this, so I enable
             it if OSF is defined...
           */
-         message ("[read inferior %x failed: %s]",
+         warning ("[read inferior %x failed: %s]",
                   addr, mach_error_string (ret));
          errno = 0;
 #endif
@@ -1734,7 +1836,7 @@ mach3_read_inferior (addr, myaddr, length)
        }
     }
 
-  bcopy ((char *)addr - low_address + copied_memory, myaddr, length);
+  memcpy (myaddr, (char *)addr - low_address + copied_memory, length);
 
   ret = vm_deallocate (mach_task_self (),
                       copied_memory,
@@ -1794,7 +1896,7 @@ mach3_write_inferior (addr, myaddr, length)
 
   deallocate++;
 
-  bcopy (myaddr, (char *)addr - low_address + copied_memory, length);
+  memcpy ((char *)addr - low_address + copied_memory, myaddr, length);
 
   obstack_init (&region_obstack);
 
@@ -1832,7 +1934,7 @@ mach3_write_inferior (addr, myaddr, length)
        /* Check for holes in memory */
        if (old_address != region_address)
          {
-           message ("No memory at 0x%x. Nothing written",
+           warning ("No memory at 0x%x. Nothing written",
                     old_address);
            ret = KERN_SUCCESS;
            length = 0;
@@ -1841,7 +1943,7 @@ mach3_write_inferior (addr, myaddr, length)
 
        if (!(max_protection & VM_PROT_WRITE))
          {
-           message ("Memory at address 0x%x is unwritable. Nothing written",
+           warning ("Memory at address 0x%x is unwritable. Nothing written",
                     old_address);
            ret = KERN_SUCCESS;
            length = 0;
@@ -1920,18 +2022,16 @@ mach3_write_inferior (addr, myaddr, length)
 
   if (ret != KERN_SUCCESS)
     {
-      message ("%s %s", errstr, mach_error_string (ret));
+      warning ("%s %s", errstr, mach_error_string (ret));
       return 0;
     }
 
   return length;
 }
 
-/*
- * Return 0 on failure, number of bytes handled otherwise.
- */
-int
-child_xfer_memory (memaddr, myaddr, len, write, target)
+/* Return 0 on failure, number of bytes handled otherwise.  */
+static int
+m3_xfer_memory (memaddr, myaddr, len, write, target)
      CORE_ADDR memaddr;
      char *myaddr;
      int len;
@@ -1949,7 +2049,7 @@ child_xfer_memory (memaddr, myaddr, len, write, target)
 }
 
 \f
-private char *
+static char *
 translate_state(state)
 int    state;
 {
@@ -1963,23 +2063,22 @@ int     state;
   }
 }
 
-private char *
-translate_cstate(state)
-int    state;
+static char *
+translate_cstate (state)
+     int state;
 {
-  switch (state) {
-  case CPROC_RUNNING:  return "R";
-  case CPROC_SWITCHING: return "S";
-  case CPROC_BLOCKED:   return "B";
-  case CPROC_CONDWAIT:  return "C";
-  case CPROC_CONDWAIT|CPROC_SWITCHING:
-                       return "CS";
-  default:             return "?";
-  }
+  switch (state)
+    {
+    case CPROC_RUNNING:        return "R";
+    case CPROC_SWITCHING: return "S";
+    case CPROC_BLOCKED: return "B";
+    case CPROC_CONDWAIT: return "C";
+    case CPROC_CONDWAIT|CPROC_SWITCHING: return "CS";
+    default: return "?";
+    }
 }
 
-/* type == MACH_MSG_TYPE_COPY_SEND || type == MACH_MSG_TYPE_MAKE_SEND
- */
+/* type == MACH_MSG_TYPE_COPY_SEND || type == MACH_MSG_TYPE_MAKE_SEND */
 
 mach_port_t           /* no mach_port_name_t found in include files. */
 map_inferior_port_name (inferior_name, type)
@@ -2019,30 +2118,30 @@ map_inferior_port_name (inferior_name, type)
  * of the sequential number of such cprocs.
  */
 
-private char buf[7];
+static char buf[7];
 
-private char *
+static char *
 get_thread_name (one_cproc, id)
-     cproc_t one_cproc;
+     gdb_thread_t one_cproc;
      int id;
 {
   if (one_cproc)
-    if (one_cproc->incarnation == NULL)
+    if (one_cproc->cthread == NULL)
       {
        /* cproc not mapped to any cthread */
        sprintf(buf, "_C%d", id);
       }
-    else if (! one_cproc->incarnation->name)
+    else if (! one_cproc->cthread->name)
       {
        /* cproc and cthread, but no name */
        sprintf(buf, "_t%d", id);
       }
     else
-      return (one_cproc->incarnation->name);
+      return (char *)(one_cproc->cthread->name);
   else
     {
       if (id < 0)
-       message ("Inconsistency in thread name id %d", id);
+       warning ("Inconsistency in thread name id %d", id);
 
       /* Kernel thread without cproc */
       sprintf(buf, "_K%d", id);
@@ -2065,9 +2164,9 @@ fetch_thread_info (task, mthreads_out)
   ret = task_threads (task, &th_table, &th_count);
   if (ret != KERN_SUCCESS)
     {
-      message ("Error getting inferior's thread list:%s",
+      warning ("Error getting inferior's thread list:%s",
               mach_error_string(ret));
-      kill_inferior ();
+      m3_kill_inferior ();
       return -1;
     }
   
@@ -2112,7 +2211,7 @@ fetch_thread_info (task, mthreads_out)
                       (th_count * sizeof(mach_port_t)));
   if (ret != KERN_SUCCESS)
     {
-      message ("Error trying to deallocate thread list : %s",
+      warning ("Error trying to deallocate thread list : %s",
               mach_error_string (ret));
     }
 
@@ -2139,7 +2238,7 @@ fetch_usp_from_emulator_stack (sp)
                           &stack_pointer,
                           sizeof (CORE_ADDR)) != sizeof (CORE_ADDR))
     {
-      message ("Can't read user sp from emulator stack address 0x%x", sp);
+      warning ("Can't read user sp from emulator stack address 0x%x", sp);
       return 0;
     }
 
@@ -2193,7 +2292,7 @@ have_emulator_p (task)
          static boolean_t informed = FALSE;
          if (!informed)
            {
-             message("Emulation vector address 0x08%x outside emulator space",
+             warning("Emulation vector address 0x08%x outside emulator space",
                      entry);
              informed = TRUE;
            }
@@ -2202,41 +2301,43 @@ have_emulator_p (task)
   return FALSE;
 }
 
-/*
- * Map cprocs to kernel threads and vice versa.
- *
- * For reverse mapping the code mis-uses one struct cproc field,
- * see "os-mach3.h" and code here.
- *
- */
+/* Map cprocs to kernel threads and vice versa.  */
 
 void
 map_cprocs_to_kernel_threads (cprocs, mthreads, thread_count)
-     cproc_t           cprocs;
-     gdb_thread_t       mthreads;
+     gdb_thread_t cprocs;
+     gdb_thread_t mthreads;
      int thread_count;
 {
   int index;
-  cproc_t scan;
-  boolean_t   all_mapped = TRUE;
+  gdb_thread_t scan;
+  boolean_t all_mapped = TRUE;
+  LONGEST stack_base;
+  LONGEST stack_size;
 
-  for (scan = cprocs; scan; scan = scan->list)
+  for (scan = cprocs; scan; scan = scan->next)
     {
       /* Default to: no kernel thread for this cproc */
-      CPROC_REVERSE_MAP (scan) = -1;
+      scan->reverse_map = -1;
 
       /* Check if the cproc is found by its stack */
       for (index = 0; index < thread_count; index++)
        {
-         if ((mthreads + index)->sp > scan->stack_base &&
-             (mthreads + index)->sp <= scan->stack_base + scan->stack_size)
+         stack_base =
+           extract_signed_integer (scan->raw_cproc + CPROC_BASE_OFFSET,
+                                   CPROC_BASE_SIZE);
+         stack_size = 
+           extract_signed_integer (scan->raw_cproc + CPROC_SIZE_OFFSET,
+                                   CPROC_SIZE_SIZE);
+         if ((mthreads + index)->sp > stack_base &&
+             (mthreads + index)->sp <= stack_base + stack_size)
            {
              (mthreads + index)->cproc = scan;
-             CPROC_REVERSE_MAP (scan) = index;
+             scan->reverse_map = index;
              break;
            }
        }
-      all_mapped &= (CPROC_REVERSE_MAP(scan) != -1);
+      all_mapped &= (scan->reverse_map != -1);
     }
 
   /* Check for threads that are currently in the emulator.
@@ -2264,7 +2365,7 @@ map_cprocs_to_kernel_threads (cprocs, mthreads, thread_count)
          gdb_thread_t mthread = (mthreads+index);
          emul_sp = mthread->sp;
 
-         if (! mthread->cproc &&
+         if (mthread->cproc == NULL &&
              EMULATOR_BASE <= emul_sp && emul_sp <= EMULATOR_END)
            {
              mthread->in_emulator = emulator_present;
@@ -2280,20 +2381,30 @@ map_cprocs_to_kernel_threads (cprocs, mthreads, thread_count)
                  /* Try to match this stack pointer to the cprocs that
                   * don't yet have a kernel thread.
                   */
-                 for (scan = cprocs; scan; scan = scan->list)
+                 for (scan = cprocs; scan; scan = scan->next)
                    {
                      
                      /* Check is this unmapped CPROC stack contains
                       * the user stack pointer saved in the
                       * emulator.
                       */
-                     if (CPROC_REVERSE_MAP (scan) == -1 &&
-                         usp > scan->stack_base &&
-                         usp <= scan->stack_base + scan->stack_size)
+                     if (scan->reverse_map == -1)
                        {
-                         mthread->cproc = scan;
-                         CPROC_REVERSE_MAP (scan) = index;
-                         break;
+                         stack_base =
+                           extract_signed_integer
+                             (scan->raw_cproc + CPROC_BASE_OFFSET,
+                              CPROC_BASE_SIZE);
+                         stack_size = 
+                           extract_signed_integer
+                             (scan->raw_cproc + CPROC_SIZE_OFFSET,
+                              CPROC_SIZE_SIZE);
+                         if (usp > stack_base &&
+                             usp <= stack_base + stack_size)
+                           {
+                             mthread->cproc = scan;
+                             scan->reverse_map = index;
+                             break;
+                           }
                        }
                    }
                }
@@ -2313,7 +2424,7 @@ map_cprocs_to_kernel_threads (cprocs, mthreads, thread_count)
 
 void
 print_tl_address (stream, pc)
-     FILE *stream;
+     GDB_FILE *stream;
      CORE_ADDR pc;
 {
   if (! lookup_minimal_symbol_by_pc (pc))
@@ -2353,19 +2464,22 @@ lookup_address_of_variable (name)
 
   if (! symaddr)
     {
-      msymbol = lookup_minimal_symbol (name, (struct objfile *) NULL);
+      msymbol = lookup_minimal_symbol (name, NULL, NULL);
 
       if (msymbol && msymbol->type == mst_data)
-       symaddr = msymbol->address;
+       symaddr = SYMBOL_VALUE_ADDRESS (msymbol);
     }
 
   return symaddr;
 }
 
-private cproc_t
+static gdb_thread_t
 get_cprocs()
 {
-  cproc_t their_cprocs, cproc_head, cproc_copy;
+  gdb_thread_t cproc_head;
+  gdb_thread_t cproc_copy;
+  CORE_ADDR their_cprocs;
+  char *buf[TARGET_PTR_BIT / HOST_CHAR_BIT];
   char *name;
   cthread_t cthread;
   CORE_ADDR symaddr;
@@ -2373,65 +2487,76 @@ get_cprocs()
   symaddr = lookup_address_of_variable ("cproc_list");
 
   if (! symaddr)
-    { /* cproc_list is not in a file compiled with debugging
+    {
+      /* cproc_list is not in a file compiled with debugging
         symbols, but don't give up yet */
-      
+
       symaddr = lookup_address_of_variable ("cprocs");
 
       if (symaddr)
        {
          static int informed = 0;
-         if (!informed) {
-           informed++;
-           message ("Your program is loaded with an old threads library.");
-           message ("GDB does not know the old form of threads");
-           message ("so things may not work.");
-         }
+         if (!informed)
+           {
+             informed++;
+             warning ("Your program is loaded with an old threads library.");
+             warning ("GDB does not know the old form of threads");
+             warning ("so things may not work.");
+           }
        }
     }
 
   /* Stripped or no -lthreads loaded or "cproc_list" is in wrong segment. */
   if (! symaddr)
-    return NO_CPROC;
+    return NULL;
 
   /* Get the address of the first cproc in the task */
-  if (!mach3_read_inferior(symaddr,
-                          &their_cprocs,
-                          sizeof(cproc_t)))
-    error("Can't read cproc master list at address (0x%x).", symaddr);
+  if (!mach3_read_inferior (symaddr,
+                           buf,
+                           TARGET_PTR_BIT / HOST_CHAR_BIT))
+    error ("Can't read cproc master list at address (0x%x).", symaddr);
+  their_cprocs = extract_address (buf, TARGET_PTR_BIT / HOST_CHAR_BIT);
 
   /* Scan the CPROCs in the task.
      CPROCs are chained with LIST field, not NEXT field, which
      chains mutexes, condition variables and queues */
-  
-  cproc_head = NO_CPROC;
 
-  while (their_cprocs != NO_CPROC)
+  cproc_head = NULL;
+
+  while (their_cprocs != (CORE_ADDR)0)
     {
-      cproc_copy = (cproc_t) obstack_alloc(cproc_obstack,
-                                          sizeof(struct cproc));
-      
-      if (!mach3_read_inferior(their_cprocs,
-                               cproc_copy,
-                               sizeof(struct cproc)))
+      CORE_ADDR cproc_copy_incarnation;
+      cproc_copy = (gdb_thread_t) obstack_alloc (cproc_obstack,
+                                                sizeof (struct gdb_thread));
+
+      if (!mach3_read_inferior (their_cprocs,
+                               &cproc_copy->raw_cproc[0],
+                               CPROC_SIZE))
        error("Can't read next cproc at 0x%x.", their_cprocs);
-      
-      their_cprocs = cproc_copy->list;
-      
-      if (cproc_copy->incarnation != NULL)
+
+      their_cprocs =
+       extract_address (cproc_copy->raw_cproc + CPROC_LIST_OFFSET,
+                        CPROC_LIST_SIZE);
+      cproc_copy_incarnation =
+       extract_address (cproc_copy->raw_cproc + CPROC_INCARNATION_OFFSET,
+                        CPROC_INCARNATION_SIZE);
+
+      if (cproc_copy_incarnation == (CORE_ADDR)0)
+       cproc_copy->cthread = NULL;
+      else
        {
          /* This CPROC has an attached CTHREAD. Get its name */
          cthread = (cthread_t)obstack_alloc (cproc_obstack,
                                              sizeof(struct cthread));
-         
-         if (!mach3_read_inferior(cproc_copy->incarnation,
+
+         if (!mach3_read_inferior (cproc_copy_incarnation,
                                    cthread,
                                    sizeof(struct cthread)))
            error("Can't read next thread at 0x%x.",
-                 cproc_copy->incarnation);
-         
-         cproc_copy->incarnation = cthread;
-         
+                 cproc_copy_incarnation);
+
+         cproc_copy->cthread = cthread;
+
          if (cthread->name)
            {
              name = (char *) obstack_alloc (cproc_obstack, MAX_NAME_LEN);
@@ -2442,12 +2567,12 @@ get_cprocs()
              cthread->name = name;
            }
        }
-      
+
       /* insert in front */
-      cproc_copy->list = cproc_head;
-      cproc_head       = cproc_copy;
+      cproc_copy->next = cproc_head;
+      cproc_head = cproc_copy;
     }
-  return(cproc_head);
+  return cproc_head;
 }
 
 #ifndef FETCH_CPROC_STATE
@@ -2468,10 +2593,14 @@ mach3_cproc_state (mthread)
 {
   int context;
 
-  if (! mthread || !mthread->cproc || !mthread->cproc->context)
+  if (! mthread || !mthread->cproc)
     return -1;
 
-  context = mthread->cproc->context;
+  context = extract_signed_integer
+    (mthread->cproc->raw_cproc + CPROC_CONTEXT_OFFSET,
+     CPROC_CONTEXT_SIZE);
+  if (context == 0)
+    return -1;
 
   mthread->sp = context + MACHINE_CPROC_SP_OFFSET;
 
@@ -2479,7 +2608,7 @@ mach3_cproc_state (mthread)
                           &mthread->pc,
                           sizeof (CORE_ADDR)) != sizeof (CORE_ADDR))
     {
-      message ("Can't read cproc pc from inferior");
+      warning ("Can't read cproc pc from inferior");
       return -1;
     }
 
@@ -2487,7 +2616,7 @@ mach3_cproc_state (mthread)
                           &mthread->fp,
                           sizeof (CORE_ADDR)) != sizeof (CORE_ADDR))
     {
-      message ("Can't read cproc fp from inferior");
+      warning ("Can't read cproc fp from inferior");
       return -1;
     }
 
@@ -2501,8 +2630,8 @@ thread_list_command()
 {
   thread_basic_info_data_t ths;
   int     thread_count;
-  cproc_t cprocs;
-  cproc_t scan;
+  gdb_thread_t cprocs;
+  gdb_thread_t scan;
   int     index;
   char   *name;
   char    selected;
@@ -2537,19 +2666,24 @@ thread_list_command()
   
   map_cprocs_to_kernel_threads (cprocs, their_threads, thread_count);
   
-  for (scan = cprocs; scan; scan = scan->list)
+  for (scan = cprocs; scan; scan = scan->next)
     {
       int mid;
       char buf[10];
       char slot[3];
+      int cproc_state =
+       extract_signed_integer
+         (scan->raw_cproc + CPROC_STATE_OFFSET, CPROC_STATE_SIZE);
       
       selected = ' ';
       
       /* a wired cproc? */
-      wired    = scan->wired ? "wired" : "";
-      
-      if (CPROC_REVERSE_MAP(scan) != -1)
-       kthread  = (their_threads + CPROC_REVERSE_MAP(scan));
+      wired = (extract_address (scan->raw_cproc + CPROC_WIRED_OFFSET,
+                               CPROC_WIRED_SIZE)
+              ? "wired" : "");
+
+      if (scan->reverse_map != -1)
+       kthread  = (their_threads + scan->reverse_map);
       else
        kthread  = NULL;
 
@@ -2568,7 +2702,7 @@ thread_list_command()
          
          if (ret != KERN_SUCCESS)
            {
-             message ("Unable to get basic info on thread %d : %s",
+             warning ("Unable to get basic info on thread %d : %s",
                       mid,
                       mach_error_string (ret));
              continue;
@@ -2601,9 +2735,9 @@ thread_list_command()
                           kthread->in_emulator ? "E" : "",
                           translate_state (ths.run_state),
                           buf,
-                          translate_cstate (scan->state),
+                          translate_cstate (cproc_state),
                           wired);
-         print_tl_address (stdout, kthread->pc);
+         print_tl_address (gdb_stdout, kthread->pc);
        }
       else
        {
@@ -2628,14 +2762,14 @@ thread_list_command()
                           "",
                           "-", /* kernel state */
                           "",
-                          translate_cstate (scan->state),
+                          translate_cstate (cproc_state),
                           "");
          state.cproc = scan;
 
          if (FETCH_CPROC_STATE (&state) == -1)
            puts_filtered ("???");
          else
-           print_tl_address (stdout, state.pc);
+           print_tl_address (gdb_stdout, state.pc);
 
          neworder++;
        }
@@ -2665,7 +2799,7 @@ thread_list_command()
            
          if (ret != KERN_SUCCESS)
            {
-             message ("Unable to get basic info on thread %d : %s",
+             warning ("Unable to get basic info on thread %d : %s",
                       mid,
                       mach_error_string (ret));
              continue;
@@ -2701,7 +2835,7 @@ thread_list_command()
                           buf,
                           "",   /* No cproc state */
                           ""); /* Can't be wired */
-         print_tl_address (stdout, their_threads[index].pc);
+         print_tl_address (gdb_stdout, their_threads[index].pc);
          puts_filtered ("\n");
        }
     }
@@ -2761,7 +2895,7 @@ boolean_t   set;
 
   if (! MACH_PORT_VALID (thread))
     {
-      message ("thread_trace: invalid thread");
+      warning ("thread_trace: invalid thread");
       return;
     }
 
@@ -2810,13 +2944,13 @@ flush_inferior_icache(pc, amount)
                              MATTR_CACHE,
                              &flush);
   if (ret != KERN_SUCCESS)
-    message ("Error flushing inferior's cache : %s",
+    warning ("Error flushing inferior's cache : %s",
             mach_error_string (ret));
 }
 #endif FLUSH_INFERIOR_CACHE
 
 \f
-private
+static
 suspend_all_threads (from_tty)
      int from_tty;
 {
@@ -2830,9 +2964,9 @@ suspend_all_threads (from_tty)
   ret = task_threads (inferior_task, &thread_list, &thread_count);
   if (ret != KERN_SUCCESS)
     {
-      message ("Could not suspend inferior threads.");
-      kill_inferior ();
-      return_to_top_level ();
+      warning ("Could not suspend inferior threads.");
+      m3_kill_inferior ();
+      return_to_top_level (RETURN_ERROR);
     }
   
   for (index = 0; index < thread_count; index++)
@@ -2845,7 +2979,7 @@ suspend_all_threads (from_tty)
       ret = thread_suspend(thread_list[ index ]);
 
       if (ret != KERN_SUCCESS)
-       message ("Error trying to suspend thread %d : %s",
+       warning ("Error trying to suspend thread %d : %s",
                 mid, mach_error_string (ret));
 
       if (from_tty)
@@ -2857,7 +2991,7 @@ suspend_all_threads (from_tty)
                             &infoCnt);
          CHK ("suspend can't get thread info", ret);
          
-         message ("Thread %d suspend count is %d",
+         warning ("Thread %d suspend count is %d",
                   mid, th_info.suspend_count);
        }
     }
@@ -2906,7 +3040,7 @@ thread_suspend_command (args, from_tty)
 
   ret = thread_suspend (current_thread);
   if (ret != KERN_SUCCESS)
-    message ("thread_suspend failed : %s",
+    warning ("thread_suspend failed : %s",
             mach_error_string (ret));
 
   infoCnt = THREAD_BASIC_INFO_COUNT;
@@ -2916,7 +3050,7 @@ thread_suspend_command (args, from_tty)
                     &infoCnt);
   CHK ("suspend can't get thread info", ret);
   
-  message ("Thread %d suspend count is %d", mid, th_info.suspend_count);
+  warning ("Thread %d suspend count is %d", mid, th_info.suspend_count);
   
   current_thread = saved_thread;
 }
@@ -2934,7 +3068,7 @@ resume_all_threads (from_tty)
     ret = task_threads (inferior_task, &thread_list, &thread_count);
     if (ret != KERN_SUCCESS)
       {
-       kill_inferior ();
+       m3_kill_inferior ();
        error("task_threads", mach_error_string( ret));
       }
 
@@ -2953,17 +3087,17 @@ resume_all_threads (from_tty)
        if (! th_info.suspend_count)
          {
            if (mid != -1 && from_tty)
-             message ("Thread %d is not suspended", mid);
+             warning ("Thread %d is not suspended", mid);
            continue;
          }
 
        ret = thread_resume (thread_list[ index ]);
 
        if (ret != KERN_SUCCESS)
-         message ("Error trying to resume thread %d : %s",
+         warning ("Error trying to resume thread %d : %s",
                   mid, mach_error_string (ret));
        else if (mid != -1 && from_tty)
-         message ("Thread %d suspend count is %d",
+         warning ("Thread %d suspend count is %d",
                   mid, --th_info.suspend_count);
       }
 
@@ -3006,7 +3140,7 @@ thread_resume_command (args, from_tty)
       {
        if (current_thread)
          current_thread = saved_thread;
-       return_to_top_level ();
+       return_to_top_level (RETURN_ERROR);
       }
 
   ret = thread_info (current_thread,
@@ -3017,18 +3151,18 @@ thread_resume_command (args, from_tty)
   
   if (! th_info.suspend_count)
     {
-      message ("Thread %d is not suspended", mid);
+      warning ("Thread %d is not suspended", mid);
       goto out;
     }
 
   ret = thread_resume (current_thread);
   if (ret != KERN_SUCCESS)
-    message ("thread_resume failed : %s",
+    warning ("thread_resume failed : %s",
             mach_error_string (ret));
   else
     {
       th_info.suspend_count--;
-      message ("Thread %d suspend count is %d", mid, th_info.suspend_count);
+      warning ("Thread %d suspend count is %d", mid, th_info.suspend_count);
     }
       
  out:
@@ -3076,7 +3210,7 @@ thread_kill_command (args, from_tty)
       CHK ("Thread could not be terminated", ret);
 
       if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS)
-       message ("Last thread was killed, use \"kill\" command to kill task");
+       warning ("Last thread was killed, use \"kill\" command to kill task");
     }
   else
     for (index = 0; index < thread_count; index++)
@@ -3093,7 +3227,7 @@ thread_kill_command (args, from_tty)
                       (thread_count * sizeof(mach_port_t)));
   CHK ("Error trying to deallocate thread list", ret);
   
-  message ("Thread %d killed", mid);
+  warning ("Thread %d killed", mid);
 }
 
 \f
@@ -3133,14 +3267,14 @@ task_resume_command (args, from_tty)
 
   if (ta_info.suspend_count == 1)
     {
-      message ("Inferior task %d is no longer suspended", mid);
+      warning ("Inferior task %d is no longer suspended", mid);
       must_suspend_thread = 1;
       /* @@ This is not complete: Registers change all the time when not
         suspended! */
       registers_changed ();
     }
   else
-    message ("Inferior task %d suspend count is now %d",
+    warning ("Inferior task %d suspend count is now %d",
             mid, ta_info.suspend_count-1);
 }
 
@@ -3172,11 +3306,11 @@ task_suspend_command (args, from_tty)
                   &infoCnt);
   CHK ("task_suspend_command: task_info failed", ret);
   
-  message ("Inferior task %d suspend count is now %d",
+  warning ("Inferior task %d suspend count is now %d",
           mid, ta_info.suspend_count);
 }
 
-private char *
+static char *
 get_size (bytes)
      int bytes;
 {
@@ -3271,7 +3405,7 @@ task_info_command (args, from_tty)
  * exception mid [ forward | keep ]
  */
 
-private void
+static void
 exception_command (args, from_tty)
      char *args;
      int from_tty;
@@ -3320,7 +3454,7 @@ exception_command (args, from_tty)
     error ("exception action is either \"keep\" or \"forward\"");
 }
 
-private void
+static void
 print_exception_info (exception)
      int exception;
 {
@@ -3378,7 +3512,7 @@ mach3_exception_actions (w, force_print_only, who)
 
   if (exception_map[stop_exception].print || force_print)
     {
-      int giveback = grab_terminal ();
+      target_terminal_ours ();
       
       printf_filtered ("\n%s received %s exception : ",
                       who,
@@ -3415,9 +3549,6 @@ mach3_exception_actions (w, force_print_only, who)
       default:
        fatal ("Unknown exception");
       }
-      
-      if (giveback)
-       terminal_inferior ();
     }
 }
 \f
@@ -3489,7 +3620,7 @@ gdb_register_port (name, port)
 
   if (! MACH_PORT_VALID (port) || !name || !*name)
     {
-      message ("Invalid registration request");
+      warning ("Invalid registration request");
       return;
     }
 
@@ -3532,36 +3663,36 @@ struct cmd_list_element *cmd_thread_list;
 struct cmd_list_element *cmd_task_list;
 
 /*ARGSUSED*/
-private void
+static void
 thread_command (arg, from_tty)
      char *arg;
      int from_tty;
 {
-  printf ("\"thread\" must be followed by the name of a thread command.\n");
-  help_list (cmd_thread_list, "thread ", -1, stdout);
+  printf_unfiltered ("\"thread\" must be followed by the name of a thread command.\n");
+  help_list (cmd_thread_list, "thread ", -1, gdb_stdout);
 }
 
 /*ARGSUSED*/
-private void
+static void
 task_command (arg, from_tty)
      char *arg;
      int from_tty;
 {
-  printf ("\"task\" must be followed by the name of a task command.\n");
-  help_list (cmd_task_list, "task ", -1, stdout);
+  printf_unfiltered ("\"task\" must be followed by the name of a task command.\n");
+  help_list (cmd_task_list, "task ", -1, gdb_stdout);
 }
 
 add_mach_specific_commands ()
 {
-  extern void condition_thread ();
-
   /* Thread handling commands */
 
-  add_prefix_cmd ("thread", class_stack, thread_command,
-      "Generic command for handling threads in the debugged task.",
+  /* FIXME: Move our thread support into the generic thread.c stuff so we
+     can share that code.  */
+  add_prefix_cmd ("mthread", class_stack, thread_command,
+      "Generic command for handling Mach threads in the debugged task.",
       &cmd_thread_list, "thread ", 0, &cmdlist);
 
-  add_com_alias ("th", "thread", class_stack, 1);
+  add_com_alias ("th", "mthread", class_stack, 1);
 
   add_cmd ("select", class_stack, thread_select_command, 
           "Select and print MID of the selected thread",
@@ -3578,13 +3709,18 @@ add_mach_specific_commands ()
   add_cmd ("kill", class_run, thread_kill_command,
           "Kill the specified thread MID from inferior task.",
           &cmd_thread_list);
+#if 0
+  /* The rest of this support (condition_thread) was not merged.  It probably
+     should not be merged in this form, but instead added to the generic GDB
+     thread support.  */
   add_cmd ("break", class_breakpoint, condition_thread,
           "Breakpoint N will only be effective for thread MID or @SLOT\n\
            If MID/@SLOT is omitted allow all threads to break at breakpoint",
           &cmd_thread_list);
+#endif
   /* Thread command shorthands (for backward compatibility) */
-  add_alias_cmd ("ts", "thread select", 0, 0, &cmdlist);
-  add_alias_cmd ("tl", "thread list",   0, 0, &cmdlist);
+  add_alias_cmd ("ts", "mthread select", 0, 0, &cmdlist);
+  add_alias_cmd ("tl", "mthread list",   0, 0, &cmdlist);
 
   /* task handling commands */
 
@@ -3626,75 +3762,6 @@ the exception to some signal (see info exception)\n\
 Normally \"keep\" is used to return to GDB on exception.");
 }
 
-void
-_initialize_mach_os ()
-{
-  kern_return_t ret;
-
-  ret = mach_port_allocate(mach_task_self(), 
-                          MACH_PORT_RIGHT_PORT_SET,
-                          &inferior_wait_port_set);
-  if (ret != KERN_SUCCESS)
-    fatal("initial port set %s",mach_error_string(ret));
-
-  /* mach_really_wait now waits for this */
-  currently_waiting_for = inferior_wait_port_set;
-
-  ret = netname_look_up(name_server_port, hostname, "MachID", &mid_server);
-  if (ret != KERN_SUCCESS)
-    {
-      mid_server = MACH_PORT_NULL;
-      
-      message ("initialize machid: netname_lookup_up(MachID) : %s",
-              mach_error_string(ret));
-      message ("Some (most?) features disabled...");
-    }
-  
-  mid_auth = mach_privileged_host_port();
-  if (mid_auth == MACH_PORT_NULL)
-    mid_auth = mach_task_self();
-  
-  obstack_init (port_chain_obstack);
-
-  ret = mach_port_allocate (mach_task_self (), 
-                           MACH_PORT_RIGHT_RECEIVE,
-                           &thread_exception_port);
-  CHK ("Creating thread_exception_port for single stepping", ret);
-  
-  ret = mach_port_insert_right (mach_task_self (),
-                               thread_exception_port,
-                               thread_exception_port,
-                               MACH_MSG_TYPE_MAKE_SEND);
-  CHK ("Inserting send right to thread_exception_port", ret);
-
-  /* Allocate message port */
-  ret = mach_port_allocate (mach_task_self (),
-                           MACH_PORT_RIGHT_RECEIVE,
-                           &our_message_port);
-  if (ret != KERN_SUCCESS)
-    message ("Creating message port %s", mach_error_string (ret));
-  else
-    {
-      char buf[ MAX_NAME_LEN ];
-      ret = mach_port_move_member(mach_task_self (),
-                                 our_message_port,
-                                 inferior_wait_port_set);
-      if (ret != KERN_SUCCESS)
-       message ("message move member %s", mach_error_string (ret));
-
-
-      /* @@@@ No way to change message port name currently */
-      /* Foo. This assumes gdb has a unix pid */
-      sprintf (buf, "gdb-%d", getpid ());
-      gdb_register_port (buf, our_message_port);
-    }
-  
-  /* Heap for thread commands */
-  obstack_init (cproc_obstack);
-
-  add_mach_specific_commands ();
-}
-
 kern_return_t
 do_mach_notify_dead_name (notify, name)
      mach_port_t notify;
@@ -3714,29 +3781,31 @@ do_mach_notify_dead_name (notify, name)
   switch (element->type) {
 
   case MACH_TYPE_THREAD:
+    target_terminal_ours_for_output ();
     if (name == current_thread)
       {
-       message ("\nCurrent thread %d died", element->mid);
+       printf_filtered ("\nCurrent thread %d died", element->mid);
        current_thread = MACH_PORT_NULL;
       }
     else
-      message ("\nThread %d died", element->mid);
+      printf_filtered ("\nThread %d died", element->mid);
 
     break;
 
   case MACH_TYPE_TASK:
+    target_terminal_ours_for_output ();
     if (name != inferior_task)
-      message ("Task %d died, but it was not the selected task",
+      printf_filtered ("Task %d died, but it was not the selected task",
               element->mid);
     else              
       {
-       message ("Current task %d died", element->mid);
+       printf_filtered ("Current task %d died", element->mid);
        
        mach_port_destroy (mach_task_self(), name);
        inferior_task = MACH_PORT_NULL;
        
        if (notify_chain)
-         message("There were still unreceived dead_name_notifications???");
+         warning ("There were still unreceived dead_name_notifications???");
        
        /* Destroy the old notifications */
        setup_notify_port (0);
@@ -3758,7 +3827,7 @@ do_mach_notify_msg_accepted (notify, name)
      mach_port_t notify;
      mach_port_t name;
 {
-  message ("do_mach_notify_msg_accepted : notify %x, name %x",
+  warning ("do_mach_notify_msg_accepted : notify %x, name %x",
           notify, name);
   return KERN_SUCCESS;
 }
@@ -3768,7 +3837,7 @@ do_mach_notify_no_senders (notify, mscount)
      mach_port_t notify;
      mach_port_mscount_t mscount;
 {
-  message ("do_mach_notify_no_senders : notify %x, mscount %x",
+  warning ("do_mach_notify_no_senders : notify %x, mscount %x",
           notify, mscount);
   return KERN_SUCCESS;
 }
@@ -3778,7 +3847,7 @@ do_mach_notify_port_deleted (notify, name)
      mach_port_t notify;
      mach_port_t name;
 {
-  message ("do_mach_notify_port_deleted : notify %x, name %x",
+  warning ("do_mach_notify_port_deleted : notify %x, name %x",
           notify, name);
   return KERN_SUCCESS;
 }
@@ -3788,7 +3857,7 @@ do_mach_notify_port_destroyed (notify, rights)
      mach_port_t notify;
      mach_port_t rights;
 {
-  message ("do_mach_notify_port_destroyed : notify %x, rights %x",
+  warning ("do_mach_notify_port_destroyed : notify %x, rights %x",
           notify, rights);
   return KERN_SUCCESS;
 }
@@ -3799,14 +3868,14 @@ do_mach_notify_send_once (notify)
 {
 #ifdef DUMP_SYSCALL
   /* MANY of these are generated. */
-  message ("do_mach_notify_send_once : notify %x",
+  warning ("do_mach_notify_send_once : notify %x",
           notify);
 #endif
   return KERN_SUCCESS;
 }
 
 /* Kills the inferior. It's gone when you call this */
-void
+static void
 kill_inferior_fast ()
 {
   WAITTYPE w;
@@ -3831,13 +3900,44 @@ kill_inferior_fast ()
   setup_notify_port (0);
 }
 
-void
-kill_inferior ()
+static void
+m3_kill_inferior ()
 {
   kill_inferior_fast ();
   target_mourn_inferior ();
 }
 
+/* Clean up after the inferior dies.  */
+
+static void
+m3_mourn_inferior ()
+{
+  unpush_target (&m3_ops);
+  generic_mourn_inferior ();
+}
+
+\f
+/* Fork an inferior process, and start debugging it.  */
+
+static void
+m3_create_inferior (exec_file, allargs, env)
+     char *exec_file;
+     char *allargs;
+     char **env;
+{
+  fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL);
+  /* We are at the first instruction we care about.  */
+  /* Pedal to the metal... */
+  proceed ((CORE_ADDR) -1, 0, 0);
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach"
+   commands.  */
+static int
+m3_can_run ()
+{
+  return 1;
+}
 \f
 /* Mach 3.0 does not need ptrace for anything
  * Make sure nobody uses it on mach.
@@ -3853,9 +3953,10 @@ int a,b,c,d;
    If SIGNAL is nonzero, give it that signal.  */
 
 void
-child_resume (step, signal)
+m3_resume (pid, step, signal)
+     int pid;
      int step;
-     int signal;
+     enum target_signal signal;
 {
   kern_return_t        ret;
 
@@ -3885,7 +3986,7 @@ child_resume (step, signal)
   vm_read_cache_valid = FALSE;
 
   if (signal && inferior_pid > 0) /* Do not signal, if attached by MID */
-    kill (inferior_pid, signal);
+    kill (inferior_pid, target_signal_to_host (signal));
 
   if (step)
     {
@@ -3899,7 +4000,7 @@ child_resume (step, signal)
   
   ret = task_resume (inferior_task);
   if (ret == KERN_FAILURE)
-    message ("Task was not suspended");
+    warning ("Task was not suspended");
   else
     CHK ("Resuming task", ret);
   
@@ -3971,7 +4072,8 @@ mid_attach (mid)
  * like "atta 0" or "atta foo" (equal to the previous :-) and
  * "atta pidself". Anyway, the latter is allowed by specifying a MID.
  */
-attach (pid)
+static int
+m3_do_attach (pid)
      int pid;
 {
   kern_return_t ret;
@@ -4004,6 +4106,42 @@ attach (pid)
   return inferior_pid;
 }
 
+/* Attach to process PID, then initialize for debugging it
+   and wait for the trace-trap that results from attaching.  */
+
+static void
+m3_attach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  char *exec_file;
+  int pid;
+
+  if (!args)
+    error_no_arg ("process-id to attach");
+
+  pid = atoi (args);
+
+  if (pid == getpid())         /* Trying to masturbate? */
+    error ("I refuse to debug myself!");
+
+  if (from_tty)
+    {
+      exec_file = (char *) get_exec_file (0);
+
+      if (exec_file)
+       printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, target_pid_to_str (pid));
+      else
+       printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
+
+      gdb_flush (gdb_stdout);
+    }
+
+  m3_do_attach (pid);
+  inferior_pid = pid;
+  push_target (&m3_ops);
+}
+\f
 void
 deallocate_inferior_ports ()
 {
@@ -4017,7 +4155,7 @@ deallocate_inferior_ports ()
   ret = task_threads (inferior_task, &thread_list, &thread_count);
   if (ret != KERN_SUCCESS)
     {
-      message ("deallocate_inferior_ports: task_threads",
+      warning ("deallocate_inferior_ports: task_threads",
               mach_error_string(ret));
       return;
     }
@@ -4060,8 +4198,8 @@ deallocate_inferior_ports ()
    and continue it with signal number SIGNAL.
    SIGNAL = 0 means just continue it.  */
 
-void
-detach (signal)
+static void
+m3_do_detach (signal)
      int signal;
 {
   kern_return_t ret;
@@ -4087,7 +4225,7 @@ detach (signal)
   setup_notify_port (0);
 
   if (remove_breakpoints ())
-    message ("Could not remove breakpoints when detaching");
+    warning ("Could not remove breakpoints when detaching");
   
   if (signal && inferior_pid > 0)
     kill (inferior_pid, signal);
@@ -4099,8 +4237,73 @@ detach (signal)
   
   attach_flag = 0;
 }
+
+/* Take a program previously attached to and detaches it.
+   The program resumes execution and will no longer stop
+   on signals, etc.  We'd better not have left any breakpoints
+   in the program or it'll die when it hits one.  For this
+   to work, it may be necessary for the process to have been
+   previously attached.  It *might* work if the program was
+   started via fork.  */
+
+static void
+m3_detach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  int siggnal = 0;
+
+  if (from_tty)
+    {
+      char *exec_file = get_exec_file (0);
+      if (exec_file == 0)
+       exec_file = "";
+      printf_unfiltered ("Detaching from program: %s %s\n",
+             exec_file, target_pid_to_str (inferior_pid));
+      gdb_flush (gdb_stdout);
+    }
+  if (args)
+    siggnal = atoi (args);
+  
+  m3_do_detach (siggnal);
+  inferior_pid = 0;
+  unpush_target (&m3_ops);             /* Pop out of handling an inferior */
+}
 #endif /* ATTACH_DETACH */
 
+/* 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
+m3_prepare_to_store ()
+{
+#ifdef CHILD_PREPARE_TO_STORE
+  CHILD_PREPARE_TO_STORE ();
+#endif
+}
+
+/* Print status information about what we're accessing.  */
+
+static void
+m3_files_info (ignore)
+     struct target_ops *ignore;
+{
+  /* FIXME: should print MID and all that crap.  */
+  printf_unfiltered ("\tUsing the running image of %s %s.\n",
+                      attach_flag? "attached": "child", target_pid_to_str (inferior_pid));
+}
+
+static void
+m3_open (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  error ("Use the \"run\" command to start a Unix child process.");
+}
+
 #ifdef DUMP_SYSCALL
 #ifdef __STDC__
 #define STR(x) #x
@@ -4316,3 +4519,124 @@ char    *p;
   puts_filtered("\n");
 }
 #endif  DUMP_SYSCALL
+
+static void
+m3_stop ()
+{
+  error ("to_stop target function not implemented");
+}
+
+struct target_ops m3_ops = {
+  "mach",                      /* to_shortname */
+  "Mach child process",        /* to_longname */
+  "Mach child process (started by the \"run\" command).",      /* to_doc */
+  m3_open,                     /* to_open */
+  0,                           /* to_close */
+  m3_attach,                   /* to_attach */
+  m3_detach,           /* to_detach */
+  m3_resume,                   /* to_resume */
+  mach_really_wait,                    /* to_wait */
+  fetch_inferior_registers,    /* to_fetch_registers */
+  store_inferior_registers,    /* to_store_registers */
+  m3_prepare_to_store, /* to_prepare_to_store */
+  m3_xfer_memory,              /* to_xfer_memory */
+  m3_files_info,               /* to_files_info */
+  memory_insert_breakpoint,    /* to_insert_breakpoint */
+  memory_remove_breakpoint,    /* to_remove_breakpoint */
+  terminal_init_inferior,      /* to_terminal_init */
+  terminal_inferior,           /* to_terminal_inferior */
+  terminal_ours_for_output,    /* to_terminal_ours_for_output */
+  terminal_ours,               /* to_terminal_ours */
+  child_terminal_info,         /* to_terminal_info */
+  m3_kill_inferior,            /* to_kill */
+  0,                           /* to_load */
+  0,                           /* to_lookup_symbol */
+
+  m3_create_inferior,  /* to_create_inferior */
+  m3_mourn_inferior,   /* to_mourn_inferior */
+  m3_can_run,          /* to_can_run */
+  0,                           /* to_notice_signals */
+  0,                           /* to_thread_alive */
+  m3_stop,                     /* to_stop */
+  process_stratum,             /* to_stratum */
+  0,                           /* to_next */
+  1,                           /* to_has_all_memory */
+  1,                           /* to_has_memory */
+  1,                           /* to_has_stack */
+  1,                           /* to_has_registers */
+  1,                           /* to_has_execution */
+  0,                           /* sections */
+  0,                           /* sections_end */
+  OPS_MAGIC                    /* to_magic */
+};
+
+void
+_initialize_m3_nat ()
+{
+  kern_return_t ret;
+
+  add_target (&m3_ops);
+
+  ret = mach_port_allocate(mach_task_self(), 
+                          MACH_PORT_RIGHT_PORT_SET,
+                          &inferior_wait_port_set);
+  if (ret != KERN_SUCCESS)
+    fatal("initial port set %s",mach_error_string(ret));
+
+  /* mach_really_wait now waits for this */
+  currently_waiting_for = inferior_wait_port_set;
+
+  ret = netname_look_up(name_server_port, hostname, "MachID", &mid_server);
+  if (ret != KERN_SUCCESS)
+    {
+      mid_server = MACH_PORT_NULL;
+      
+      warning ("initialize machid: netname_lookup_up(MachID) : %s",
+              mach_error_string(ret));
+      warning ("Some (most?) features disabled...");
+    }
+  
+  mid_auth = mach_privileged_host_port();
+  if (mid_auth == MACH_PORT_NULL)
+    mid_auth = mach_task_self();
+  
+  obstack_init (port_chain_obstack);
+
+  ret = mach_port_allocate (mach_task_self (), 
+                           MACH_PORT_RIGHT_RECEIVE,
+                           &thread_exception_port);
+  CHK ("Creating thread_exception_port for single stepping", ret);
+  
+  ret = mach_port_insert_right (mach_task_self (),
+                               thread_exception_port,
+                               thread_exception_port,
+                               MACH_MSG_TYPE_MAKE_SEND);
+  CHK ("Inserting send right to thread_exception_port", ret);
+
+  /* Allocate message port */
+  ret = mach_port_allocate (mach_task_self (),
+                           MACH_PORT_RIGHT_RECEIVE,
+                           &our_message_port);
+  if (ret != KERN_SUCCESS)
+    warning ("Creating message port %s", mach_error_string (ret));
+  else
+    {
+      char buf[ MAX_NAME_LEN ];
+      ret = mach_port_move_member(mach_task_self (),
+                                 our_message_port,
+                                 inferior_wait_port_set);
+      if (ret != KERN_SUCCESS)
+       warning ("message move member %s", mach_error_string (ret));
+
+
+      /* @@@@ No way to change message port name currently */
+      /* Foo. This assumes gdb has a unix pid */
+      sprintf (buf, "gdb-%d", getpid ());
+      gdb_register_port (buf, our_message_port);
+    }
+  
+  /* Heap for thread commands */
+  obstack_init (cproc_obstack);
+
+  add_mach_specific_commands ();
+}
This page took 0.050162 seconds and 4 git commands to generate.