/* Interface GDB to Mach 3.0 operating systems.
   (Most) Mach 3.0 related routines live in this file.

   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
   2002 Free Software Foundation, Inc.

   This file is part of GDB.

   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
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   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.  */

/*
 * Author: Jukka Virtanen <jtv@hut.fi>
 *         Computing Centre
 *         Helsinki University of Technology
 *         Finland
 *
 * Thanks to my friends who helped with ideas and testing:
 *
 *      Johannes Helander, Antti Louko, Tero Mononen,
 *      jvh@cs.hut.fi      alo@hut.fi   tmo@cs.hut.fi
 *
 *      Tero Kivinen       and          Eamonn McManus
 *      kivinen@cs.hut.fi               emcmanus@gr.osf.org
 *      
 */

#include <stdio.h>

#include <mach.h>
#include <servers/netname.h>
#include <servers/machid.h>
#include <mach/message.h>
#include <mach/notify.h>
#include <mach_error.h>
#include <mach/exception.h>
#include <mach/vm_attributes.h>

#include "defs.h"
#include "inferior.h"
#include "symtab.h"
#include "value.h"
#include "language.h"
#include "target.h"
#include "gdb_wait.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "regcache.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

 * note: There are many problems in signal handling with
 *       gdb in Mach 3.0 in general.
 */
#include <signal.h>
#define SIG_UNKNOWN 0		/* Exception that has no matching unix signal */

#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.
 *
 * sigmap field maps the exception to corresponding Unix signal.
 *
 * I do not know how to map the exception to unix signal
 * if SIG_UNKNOWN is specified.
 */

struct exception_list
  {
    char *name;
    boolean_t forward;
    boolean_t print;
    int sigmap;
  }
exception_map[] =
{
  {
    "not_mach3_exception", FALSE, TRUE, SIG_UNKNOWN
  }
  ,
  {
    "EXC_BAD_ACCESS", FALSE, TRUE, SIGSEGV
  }
  ,
  {
    "EXC_BAD_INSTRUCTION", FALSE, TRUE, SIGILL
  }
  ,
  {
    "EXC_ARITHMETIC", FALSE, TRUE, SIGFPE
  }
  ,
  {
    "EXC_EMULATION", FALSE, TRUE, SIGEMT
  }
  ,				/* ??? */
  {
    "EXC_SOFTWARE", FALSE, TRUE, SIG_UNKNOWN
  }
  ,
  {
    "EXC_BREAKPOINT", FALSE, FALSE, SIGTRAP
  }
};

/* Mach exception table size */
int max_exception = sizeof (exception_map) / sizeof (struct exception_list) - 1;

#define MAX_EXCEPTION max_exception

WAITTYPE wait_status;

/* If you define this, intercepted bsd server calls will be
 * dumped while waiting the inferior to EXEC the correct
 * program
 */
/* #define DUMP_SYSCALL         /* debugging interceptor */

/* xx_debug() outputs messages if this is nonzero.
 * If > 1, DUMP_SYSCALL will dump message contents.
 */
int debug_level = 0;

/* "Temporary" debug stuff */
void
xx_debug (char *fmt, int a, int b, int c)
{
  if (debug_level)
    warning (fmt, a, b, c);
}

/* This is in libmach.a */
extern mach_port_t name_server_port;

/* Set in catch_exception_raise */
int stop_exception, stop_code, stop_subcode;
int stopped_in_exception;

/* Thread that was the active thread when we stopped */
thread_t stop_thread = MACH_PORT_NULL;

char *hostname = "";

/* Set when task is attached or created */
boolean_t emulator_present = FALSE;

task_t inferior_task;
thread_t current_thread;

/* Exception ports for inferior task */
mach_port_t inferior_exception_port = MACH_PORT_NULL;
mach_port_t inferior_old_exception_port = MACH_PORT_NULL;

/* task exceptions and notifications */
mach_port_t inferior_wait_port_set = MACH_PORT_NULL;
mach_port_t our_notify_port = MACH_PORT_NULL;

/* This is "inferior_wait_port_set" when not single stepping, and
 *         "singlestepped_thread_port" when we are single stepping.
 * 
 * This is protected by a cleanup function: discard_single_step()
 */
mach_port_t currently_waiting_for = MACH_PORT_NULL;

/* A port for external messages to gdb.
 * External in the meaning that they do not come
 * from the inferior_task, but rather from external
 * tasks.
 *
 * As a debugging feature:
 * A debugger debugging another debugger can stop the
 * inferior debugger by the following command sequence
 * (without running external programs)
 *
 *    (top-gdb) set stop_inferior_gdb ()
 *    (top-gdb) continue
 */
mach_port_t our_message_port = MACH_PORT_NULL;

/* For single stepping */
mach_port_t thread_exception_port = MACH_PORT_NULL;
mach_port_t thread_saved_exception_port = MACH_PORT_NULL;
mach_port_t singlestepped_thread_port = MACH_PORT_NULL;

/* For machid calls */
mach_port_t mid_server = MACH_PORT_NULL;
mach_port_t mid_auth = MACH_PORT_NULL;

/* If gdb thinks the inferior task is not suspended, it
 * must take suspend/abort the threads when it reads the state.
 */
int must_suspend_thread = 0;

/* When single stepping, we switch the port that mach_really_wait() listens to.
 * This cleanup is a guard to prevent the port set from being left to
 * the singlestepped_thread_port when error() is called.
 *  This is nonzero only when we are single stepping.
 */
#define NULL_CLEANUP (struct cleanup *)0
struct cleanup *cleanup_step = NULL_CLEANUP;


static struct target_ops m3_ops;

static void m3_kill_inferior ();

#if 0
#define MACH_TYPE_EXCEPTION_PORT	-1
#endif

/* Chain of ports to remember requested notifications. */

struct port_chain
  {
    struct port_chain *next;
    mach_port_t port;
    int type;
    int mid;			/* Now only valid with MACH_TYPE_THREAD and */
    /*  MACH_TYPE_THREAD */
  };
typedef struct port_chain *port_chain_t;

/* Room for chain nodes comes from pchain_obstack */
struct obstack pchain_obstack;
struct obstack *port_chain_obstack = &pchain_obstack;

/* For thread handling */
struct obstack Cproc_obstack;
struct obstack *cproc_obstack = &Cproc_obstack;

/* the list of notified ports */
port_chain_t notify_chain = (port_chain_t) NULL;

port_chain_t
port_chain_insert (port_chain_t list, mach_port_t name, int type)
{
  kern_return_t ret;
  port_chain_t new;
  int mid;

  if (!MACH_PORT_VALID (name))
    return list;

  if (type == MACH_TYPE_TASK || type == MACH_TYPE_THREAD)
    {
      if (!MACH_PORT_VALID (mid_server))
	{
	  warning ("Machid server port invalid, can not map port 0x%x to MID",
		   name);
	  mid = name;
	}
      else
	{
	  ret = machid_mach_register (mid_server, mid_auth, name, type, &mid);

	  if (ret != KERN_SUCCESS)
	    {
	      warning ("Can not map name (0x%x) to MID with machid", name);
	      mid = name;
	    }
	}
    }
  else
    internal_error (__FILE__, __LINE__, "failed internal consistency check");

  new = (port_chain_t) obstack_alloc (port_chain_obstack,
				      sizeof (struct port_chain));
  new->next = list;
  new->port = name;
  new->type = type;
  new->mid = mid;

  return new;
}

port_chain_t
port_chain_delete (port_chain_t list, mach_port_t elem)
{
  if (list)
    if (list->port == elem)
      list = list->next;
    else
      while (list->next)
	{
	  if (list->next->port == elem)
	    list->next = list->next->next;	/* GCd with obstack_free() */
	  else
	    list = list->next;
	}
  return list;
}

void
port_chain_destroy (struct obstack *ostack)
{
  obstack_free (ostack, 0);
  obstack_init (ostack);
}

port_chain_t
port_chain_member (port_chain_t list, mach_port_t elem)
{
  while (list)
    {
      if (list->port == elem)
	return list;
      list = list->next;
    }
  return (port_chain_t) NULL;
}

int
map_port_name_to_mid (mach_port_t name, int type)
{
  port_chain_t elem;

  if (!MACH_PORT_VALID (name))
    return -1;

  elem = port_chain_member (notify_chain, name);

  if (elem && (elem->type == type))
    return elem->mid;

  if (elem)
    return -1;

  if (!MACH_PORT_VALID (mid_server))
    {
      warning ("Machid server port invalid, can not map port 0x%x to mid",
	       name);
      return -1;
    }
  else
    {
      int mid;
      kern_return_t ret;

      ret = machid_mach_register (mid_server, mid_auth, name, type, &mid);

      if (ret != KERN_SUCCESS)
	{
	  warning ("Can not map name (0x%x) to mid with machid", name);
	  return -1;
	}
      return mid;
    }
}

/* Guard for currently_waiting_for and singlestepped_thread_port */
static void
discard_single_step (thread_t thread)
{
  currently_waiting_for = inferior_wait_port_set;

  cleanup_step = NULL_CLEANUP;
  if (MACH_PORT_VALID (thread) && MACH_PORT_VALID (singlestepped_thread_port))
    setup_single_step (thread, FALSE);
}

setup_single_step (thread_t thread, boolean_t start_step)
{
  kern_return_t ret;

  if (!MACH_PORT_VALID (thread))
    error ("Invalid thread supplied to setup_single_step");
  else
    {
      mach_port_t teport;

      /* Get the current thread exception port */
      ret = thread_get_exception_port (thread, &teport);
      CHK ("Getting thread's exception port", ret);

      if (start_step)
	{
	  if (MACH_PORT_VALID (singlestepped_thread_port))
	    {
	      warning ("Singlestepped_thread_port (0x%x) is still valid?",
		       singlestepped_thread_port);
	      singlestepped_thread_port = MACH_PORT_NULL;
	    }

	  /* If we are already stepping this thread */
	  if (MACH_PORT_VALID (teport) && teport == thread_exception_port)
	    {
	      ret = mach_port_deallocate (mach_task_self (), teport);
	      CHK ("Could not deallocate thread exception port", ret);
	    }
	  else
	    {
	      ret = thread_set_exception_port (thread, thread_exception_port);
	      CHK ("Setting exception port for thread", ret);
#if 0
	      /* Insert thread exception port to wait port set */
	      ret = mach_port_move_member (mach_task_self (),
					   thread_exception_port,
					   inferior_wait_port_set);
	      CHK ("Moving thread exception port to inferior_wait_port_set",
		   ret);
#endif
	      thread_saved_exception_port = teport;
	    }

	  thread_trace (thread, TRUE);

	  singlestepped_thread_port = thread_exception_port;
	  currently_waiting_for = singlestepped_thread_port;
	  cleanup_step = make_cleanup (discard_single_step, thread);
	}
      else
	{
	  if (!MACH_PORT_VALID (teport))
	    error ("Single stepped thread had an invalid exception port?");

	  if (teport != thread_exception_port)
	    error ("Single stepped thread had an unknown exception port?");

	  ret = mach_port_deallocate (mach_task_self (), teport);
	  CHK ("Couldn't deallocate thread exception port", ret);
#if 0
	  /* Remove thread exception port from wait port set */
	  ret = mach_port_move_member (mach_task_self (),
				       thread_exception_port,
				       MACH_PORT_NULL);
	  CHK ("Removing thread exception port from inferior_wait_port_set",
	       ret);
#endif
	  /* Restore thread's old exception port */
	  ret = thread_set_exception_port (thread,
					   thread_saved_exception_port);
	  CHK ("Restoring stepped thread's exception port", ret);

	  if (MACH_PORT_VALID (thread_saved_exception_port))
	    (void) mach_port_deallocate (mach_task_self (),
					 thread_saved_exception_port);

	  thread_trace (thread, FALSE);

	  singlestepped_thread_port = MACH_PORT_NULL;
	  currently_waiting_for = inferior_wait_port_set;
	  if (cleanup_step)
	    discard_cleanups (cleanup_step);
	}
    }
}

static
request_notify (mach_port_t name, mach_msg_id_t variant, int type)
{
  kern_return_t ret;
  mach_port_t previous_port_dummy = MACH_PORT_NULL;

  if (!MACH_PORT_VALID (name))
    return;

  if (port_chain_member (notify_chain, name))
    return;

  ret = mach_port_request_notification (mach_task_self (),
					name,
					variant,
					1,
					our_notify_port,
					MACH_MSG_TYPE_MAKE_SEND_ONCE,
					&previous_port_dummy);
  CHK ("Serious: request_notify failed", ret);

  (void) mach_port_deallocate (mach_task_self (),
			       previous_port_dummy);

  notify_chain = port_chain_insert (notify_chain, name, type);
}

reverse_msg_bits (mach_msg_header_t *msgp, int type)
{
  int rbits, lbits;
  rbits = MACH_MSGH_BITS_REMOTE (msgp->msgh_bits);
  lbits = type;
  msgp->msgh_bits =
    (msgp->msgh_bits & ~MACH_MSGH_BITS_PORTS_MASK) |
    MACH_MSGH_BITS (lbits, rbits);
}

/* On the third day He said:

   Let this be global
   and then it was global.

   When creating the inferior fork, the
   child code in inflow.c sets the name of the
   bootstrap_port in its address space to this
   variable.

   The name is transferred to our address space
   with mach3_read_inferior().

   Thou shalt not do this with
   task_get_bootstrap_port() in this task, since
   the name in the inferior task is different than
   the one we get.

   For blessed are the meek, as they shall inherit
   the address space.
 */
mach_port_t original_server_port_name = MACH_PORT_NULL;


/* Called from inferior after FORK but before EXEC */
static void
m3_trace_me (void)
{
  kern_return_t ret;

  /* Get the NAME of the bootstrap port in this task
     so that GDB can read it */
  ret = task_get_bootstrap_port (mach_task_self (),
				 &original_server_port_name);
  if (ret != KERN_SUCCESS)
    internal_error (__FILE__, __LINE__, "failed internal consistency check");
  ret = mach_port_deallocate (mach_task_self (),
			      original_server_port_name);
  if (ret != KERN_SUCCESS)
    internal_error (__FILE__, __LINE__, "failed internal consistency check");

  /* Suspend this task to let the parent change my ports.
     Resumed by the debugger */
  ret = task_suspend (mach_task_self ());
  if (ret != KERN_SUCCESS)
    internal_error (__FILE__, __LINE__, "failed internal consistency check");
}

/*
 * Intercept system calls to Unix server.
 * After EXEC_COUNTER calls to exec(), return.
 *
 * Pre-assertion:  Child is suspended. (Not verified)
 * Post-condition: Child is suspended after EXEC_COUNTER exec() calls.
 */

void
intercept_exec_calls (int exec_counter)
{
  int terminal_initted = 0;

  struct syscall_msg_t
    {
      mach_msg_header_t header;
      mach_msg_type_t type;
      char room[2000];		/* Enuff space */
    };

  struct syscall_msg_t syscall_in, syscall_out;

  mach_port_t fake_server;
  mach_port_t original_server_send;
  mach_port_t original_exec_reply;
  mach_port_t exec_reply;
  mach_port_t exec_reply_send;
  mach_msg_type_name_t acquired;
  mach_port_t emulator_server_port_name;
  struct task_basic_info info;
  mach_msg_type_number_t info_count;

  kern_return_t ret;

  if (exec_counter <= 0)
    return;			/* We are already set up in the correct program */

  ret = mach_port_allocate (mach_task_self (),
			    MACH_PORT_RIGHT_RECEIVE,
			    &fake_server);
  CHK ("create inferior_fake_server port failed", ret);

  /* Wait for inferior_task to suspend itself */
  while (1)
    {
      info_count = sizeof (info);
      ret = task_info (inferior_task,
		       TASK_BASIC_INFO,
		       (task_info_t) & info,
		       &info_count);
      CHK ("Task info", ret);

      if (info.suspend_count)
	break;

      /* Note that the definition of the parameter was undefined
       * at the time of this writing, so I just use an `ad hoc' value.
       */
      (void) swtch_pri (42);	/* Universal Priority Value */
    }

  /* Read the inferior's bootstrap port name */
  if (!mach3_read_inferior (&original_server_port_name,
			    &original_server_port_name,
			    sizeof (original_server_port_name)))
    error ("Can't read inferior task bootstrap port name");

  /* @@ BUG: If more than 1 send right GDB will FAIL!!! */
  /*      Should get refs, and set them back when restoring */
  /* Steal the original bsd server send right from inferior */
  ret = mach_port_extract_right (inferior_task,
				 original_server_port_name,
				 MACH_MSG_TYPE_MOVE_SEND,
				 &original_server_send,
				 &acquired);
  CHK ("mach_port_extract_right (bsd server send)", ret);

  if (acquired != MACH_MSG_TYPE_PORT_SEND)
    error ("Incorrect right extracted, send right to bsd server expected");

  ret = mach_port_insert_right (inferior_task,
				original_server_port_name,
				fake_server,
				MACH_MSG_TYPE_MAKE_SEND);
  CHK ("mach_port_insert_right (fake server send)", ret);

  xx_debug ("inferior task bsd server ports set up \nfs %x, ospn %x, oss %x\n",
	    fake_server,
	    original_server_port_name, original_server_send);

  /* A receive right to the reply generated by unix server exec() request */
  ret = mach_port_allocate (mach_task_self (),
			    MACH_PORT_RIGHT_RECEIVE,
			    &exec_reply);
  CHK ("create intercepted_reply_port port failed", ret);

  /* Pass this send right to Unix server so it replies to us after exec() */
  ret = mach_port_extract_right (mach_task_self (),
				 exec_reply,
				 MACH_MSG_TYPE_MAKE_SEND_ONCE,
				 &exec_reply_send,
				 &acquired);
  CHK ("mach_port_extract_right (exec_reply)", ret);

  if (acquired != MACH_MSG_TYPE_PORT_SEND_ONCE)
    error ("Incorrect right extracted, send once expected for exec reply");

  ret = mach_port_move_member (mach_task_self (),
			       fake_server,
			       inferior_wait_port_set);
  CHK ("Moving fake syscall port to inferior_wait_port_set", ret);

  xx_debug ("syscall fake server set up, resuming inferior\n");

  ret = task_resume (inferior_task);
  CHK ("task_resume (startup)", ret);

  /* Read requests from the inferior.
     Pass directly through everything else except exec() calls.
   */
  while (exec_counter > 0)
    {
      ret = mach_msg (&syscall_in.header,	/* header */
		      MACH_RCV_MSG,	/* options */
		      0,	/* send size */
		      sizeof (struct syscall_msg_t),	/* receive size */
		      inferior_wait_port_set,	/* receive_name */
		      MACH_MSG_TIMEOUT_NONE,
		      MACH_PORT_NULL);
      CHK ("mach_msg (intercepted sycall)", ret);

#ifdef DUMP_SYSCALL
      print_msg (&syscall_in.header);
#endif

      /* ASSERT : msgh_local_port == fake_server */

      if (notify_server (&syscall_in.header, &syscall_out.header))
	error ("received a notify while intercepting syscalls");

      if (syscall_in.header.msgh_id == MIG_EXEC_SYSCALL_ID)
	{
	  xx_debug ("Received EXEC SYSCALL, counter = %d\n", exec_counter);
	  if (exec_counter == 1)
	    {
	      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--;
	}

      syscall_in.header.msgh_local_port = syscall_in.header.msgh_remote_port;
      syscall_in.header.msgh_remote_port = original_server_send;

      reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_COPY_SEND);

      ret = mach_msg_send (&syscall_in.header);
      CHK ("Forwarded syscall", ret);
    }

  ret = mach_port_move_member (mach_task_self (),
			       fake_server,
			       MACH_PORT_NULL);
  CHK ("Moving fake syscall out of inferior_wait_port_set", ret);

  ret = mach_port_move_member (mach_task_self (),
			       exec_reply,
			       inferior_wait_port_set);
  CHK ("Moving exec_reply to inferior_wait_port_set", ret);

  ret = mach_msg (&syscall_in.header,	/* header */
		  MACH_RCV_MSG,	/* options */
		  0,		/* send size */
		  sizeof (struct syscall_msg_t),	/* receive size */
		  inferior_wait_port_set,	/* receive_name */
		  MACH_MSG_TIMEOUT_NONE,
		  MACH_PORT_NULL);
  CHK ("mach_msg (exec reply)", ret);

  ret = task_suspend (inferior_task);
  CHK ("Suspending inferior after last exec", ret);

  must_suspend_thread = 0;

  xx_debug ("Received exec reply from bsd server, suspended inferior task\n");

#ifdef DUMP_SYSCALL
  print_msg (&syscall_in.header);
#endif

  /* Message should appear as if it came from the unix server */
  syscall_in.header.msgh_local_port = MACH_PORT_NULL;

  /*  and go to the inferior task original reply port */
  syscall_in.header.msgh_remote_port = original_exec_reply;

  reverse_msg_bits (&syscall_in.header, MACH_MSG_TYPE_MOVE_SEND_ONCE);

  ret = mach_msg_send (&syscall_in.header);
  CHK ("Forwarding exec reply to inferior", ret);

  /* Garbage collect */
  ret = mach_port_deallocate (inferior_task,
			      original_server_port_name);
  CHK ("deallocating fake server send right", ret);

  ret = mach_port_insert_right (inferior_task,
				original_server_port_name,
				original_server_send,
				MACH_MSG_TYPE_MOVE_SEND);
  CHK ("Restoring the original bsd server send right", ret);

  ret = mach_port_destroy (mach_task_self (),
			   fake_server);
  fake_server = MACH_PORT_DEAD;
  CHK ("mach_port_destroy (fake_server)", ret);

  ret = mach_port_destroy (mach_task_self (),
			   exec_reply);
  exec_reply = MACH_PORT_DEAD;
  CHK ("mach_port_destroy (exec_reply)", ret);

  xx_debug ("Done with exec call interception\n");
}

void
consume_send_rights (thread_array_t thread_list, int thread_count)
{
  int index;

  if (!thread_count)
    return;

  for (index = 0; index < thread_count; index++)
    {
      /* Since thread kill command kills threads, don't check ret */
      (void) mach_port_deallocate (mach_task_self (),
				   thread_list[index]);
    }
}

/* suspend/abort/resume a thread. */
setup_thread (mach_port_t thread, int what)
{
  kern_return_t ret;

  if (what)
    {
      ret = thread_suspend (thread);
      CHK ("setup_thread thread_suspend", ret);

      ret = thread_abort (thread);
      CHK ("setup_thread thread_abort", ret);
    }
  else
    {
      ret = thread_resume (thread);
      CHK ("setup_thread thread_resume", ret);
    }
}

int
map_slot_to_mid (int slot, thread_array_t threads, int thread_count)
{
  kern_return_t ret;
  int deallocate = 0;
  int index;
  int mid;

  if (!threads)
    {
      deallocate++;
      ret = task_threads (inferior_task, &threads, &thread_count);
      CHK ("Can not select a thread from a dead task", ret);
    }

  if (slot < 0 || slot >= thread_count)
    {
      if (deallocate)
	{
	  consume_send_rights (threads, thread_count);
	  (void) vm_deallocate (mach_task_self (), (vm_address_t) threads,
				(thread_count * sizeof (mach_port_t)));
	}
      if (slot < 0)
	error ("invalid slot number");
      else
	return -(slot + 1);
    }

  mid = map_port_name_to_mid (threads[slot], MACH_TYPE_THREAD);

  if (deallocate)
    {
      consume_send_rights (threads, thread_count);
      (void) vm_deallocate (mach_task_self (), (vm_address_t) threads,
			    (thread_count * sizeof (mach_port_t)));
    }

  return mid;
}

static int
parse_thread_id (char *arg, int thread_count, int slots)
{
  kern_return_t ret;
  int mid;
  int slot;
  int index;

  if (arg == 0)
    return 0;

  while (*arg && (*arg == ' ' || *arg == '\t'))
    arg++;

  if (!*arg)
    return 0;

  /* Currently parse MID and @SLOTNUMBER */
  if (*arg != '@')
    {
      mid = atoi (arg);
      if (mid <= 0)
	error ("valid thread mid expected");
      return mid;
    }

  arg++;
  slot = atoi (arg);

  if (slot < 0)
    error ("invalid slot number");

  /* If you want slot numbers to remain slot numbers, set slots.

   * Well, since 0 is reserved, return the ordinal number
   * of the thread rather than the slot number. Awk, this
   * counts as a kludge.
   */
  if (slots)
    return -(slot + 1);

  if (thread_count && slot >= thread_count)
    return -(slot + 1);

  mid = map_slot_to_mid (slot);

  return mid;
}

/* THREAD_ID 0 is special; it selects the first kernel
 * thread from the list (i.e. SLOTNUMBER 0)
 * This is used when starting the program with 'run' or when attaching.
 *
 * If FLAG is 0 the context is not changed, and the registers, frame, etc
 * will continue to describe the old thread.
 *
 * If FLAG is nonzero, really select the thread.
 * If FLAG is 2, the THREAD_ID is a slotnumber instead of a mid.
 * 
 */
kern_return_t
select_thread (mach_port_t task, int thread_id, int flag)
{
  thread_array_t thread_list;
  int thread_count;
  kern_return_t ret;
  int index;
  thread_t new_thread = MACH_PORT_NULL;

  if (thread_id < 0)
    error ("Can't select cprocs without kernel thread");

  ret = task_threads (task, &thread_list, &thread_count);
  if (ret != KERN_SUCCESS)
    {
      warning ("Can not select a thread from a dead task");
      m3_kill_inferior ();
      return KERN_FAILURE;
    }

  if (thread_count == 0)
    {
      /* The task can not do anything anymore, but it still
       * exists as a container for memory and ports.
       */
      registers_changed ();
      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 (),
			    (vm_address_t) thread_list,
			    (thread_count * sizeof (mach_port_t)));
      return KERN_FAILURE;
    }

  if (!thread_id || flag == 2)
    {
      /* First thread or a slotnumber */
      if (!thread_id)
	new_thread = thread_list[0];
      else
	{
	  if (thread_id < thread_count)
	    new_thread = thread_list[thread_id];
	  else
	    {
	      (void) vm_deallocate (mach_task_self (),
				    (vm_address_t) thread_list,
				    (thread_count * sizeof (mach_port_t)));
	      error ("No such thread slot number : %d", thread_id);
	    }
	}
    }
  else
    {
      for (index = 0; index < thread_count; index++)
	if (thread_id == map_port_name_to_mid (thread_list[index],
					       MACH_TYPE_THREAD))
	  {
	    new_thread = thread_list[index];
	    index = -1;
	    break;
	  }

      if (index != -1)
	error ("No thread with mid %d", thread_id);
    }

  /* Notify when the selected thread dies */
  request_notify (new_thread, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_THREAD);

  ret = vm_deallocate (mach_task_self (),
		       (vm_address_t) thread_list,
		       (thread_count * sizeof (mach_port_t)));
  CHK ("vm_deallocate", ret);

  if (!flag)
    current_thread = new_thread;
  else
    {
#if 0
      if (MACH_PORT_VALID (current_thread))
	{
	  /* Store the gdb's view of the thread we are deselecting

	   * @@ I think gdb updates registers immediately when they are
	   * changed, so don't do this.
	   */
	  ret = thread_abort (current_thread);
	  CHK ("Could not abort system calls when saving state of old thread",
	       ret);
	  target_prepare_to_store ();
	  target_store_registers (-1);
	}
#endif

      registers_changed ();

      current_thread = new_thread;

      ret = thread_abort (current_thread);
      CHK ("Could not abort system calls when selecting a thread", ret);

      stop_pc = read_pc ();
      flush_cached_frames ();

      select_frame (get_current_frame ());
    }

  return KERN_SUCCESS;
}

/*
 * Switch to use thread named NEW_THREAD.
 * Return it's MID
 */
int
switch_to_thread (thread_t new_thread)
{
  thread_t saved_thread = current_thread;
  int mid;

  mid = map_port_name_to_mid (new_thread,
			      MACH_TYPE_THREAD);
  if (mid == -1)
    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)
	current_thread = saved_thread;
      error ("Could not select thread %d", mid);
    }

  return mid;
}

/* Do this in gdb after doing FORK but before STARTUP_INFERIOR.
 * Note that the registers are not yet valid in the inferior task.
 */
static int
m3_trace_him (int pid)
{
  kern_return_t ret;

  push_target (&m3_ops);

  inferior_task = task_by_pid (pid);

  if (!MACH_PORT_VALID (inferior_task))
    error ("Can not map Unix pid %d to Mach task", pid);

  /* Clean up previous notifications and create new ones */
  setup_notify_port (1);

  /* When notification appears, the inferior task has died */
  request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK);

  emulator_present = have_emulator_p (inferior_task);

  /* By default, select the first thread,
   * If task has no threads, gives a warning
   * Does not fetch registers, since they are not yet valid.
   */
  select_thread (inferior_task, 0, 0);

  inferior_exception_port = MACH_PORT_NULL;

  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 (void)
{
  kern_return_t ret;

  ret = mach_port_allocate (mach_task_self (),
			    MACH_PORT_RIGHT_RECEIVE,
			    &inferior_exception_port);
  CHK ("mach_port_allocate", ret);

  /* add send right */
  ret = mach_port_insert_right (mach_task_self (),
				inferior_exception_port,
				inferior_exception_port,
				MACH_MSG_TYPE_MAKE_SEND);
  CHK ("mach_port_insert_right", ret);

  ret = mach_port_move_member (mach_task_self (),
			       inferior_exception_port,
			       inferior_wait_port_set);
  CHK ("mach_port_move_member", ret);

  ret = task_get_special_port (inferior_task,
			       TASK_EXCEPTION_PORT,
			       &inferior_old_exception_port);
  CHK ("task_get_special_port(old exc)", ret);

  ret = task_set_special_port (inferior_task,
			       TASK_EXCEPTION_PORT,
			       inferior_exception_port);
  CHK ("task_set_special_port", ret);

  ret = mach_port_deallocate (mach_task_self (),
			      inferior_exception_port);
  CHK ("mack_port_deallocate", ret);

#if 0
  /* When notify appears, the inferior_task's exception
   * port has been destroyed.
   *
   * Not used, since the dead_name_notification already
   * appears when task dies.
   *
   */
  request_notify (inferior_exception_port,
		  MACH_NOTIFY_NO_SENDERS,
		  MACH_TYPE_EXCEPTION_PORT);
#endif
}

/* Nonzero if gdb is waiting for a message */
int mach_really_waiting;

/* Wait for the inferior to stop for some reason.
   - Loop on notifications until inferior_task dies.
   - Loop on exceptions until stopped_in_exception comes true.
   (e.g. we receive a single step trace trap)
   - a message arrives to gdb's message port

   There is no other way to exit this loop.

   Returns the inferior_ptid for rest of gdb.
   Side effects: Set *OURSTATUS.  */
ptid_t
mach_really_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
{
  kern_return_t ret;
  int w;

  struct msg
    {
      mach_msg_header_t header;
      mach_msg_type_t foo;
      int data[8000];
    }
  in_msg, out_msg;

  /* Either notify (death), exception or message can stop the inferior */
  stopped_in_exception = FALSE;

  while (1)
    {
      QUIT;

      stop_exception = stop_code = stop_subcode = -1;
      stop_thread = MACH_PORT_NULL;

      mach_really_waiting = 1;
      ret = mach_msg (&in_msg.header,	/* header */
		      MACH_RCV_MSG,	/* options */
		      0,	/* send size */
		      sizeof (struct msg),	/* receive size */
		      currently_waiting_for,	/* receive name */
		      MACH_MSG_TIMEOUT_NONE,
		      MACH_PORT_NULL);
      mach_really_waiting = 0;
      CHK ("mach_msg (receive)", ret);

      /* Check if we received a notify of the childs' death */
      if (notify_server (&in_msg.header, &out_msg.header))
	{
	  /* If inferior_task is null then the inferior has
	     gone away and we want to return to command level.
	     Otherwise it was just an informative message and we
	     need to look to see if there are any more. */
	  if (inferior_task != MACH_PORT_NULL)
	    continue;
	  else
	    {
	      /* Collect Unix exit status for gdb */

	      wait3 (&w, WNOHANG, 0);

	      /* This mess is here to check that the rest of
	       * gdb knows that the inferior died. It also
	       * tries to hack around the fact that Mach 3.0 (mk69)
	       * unix server (ux28) does not always know what
	       * has happened to it's children when mach-magic
	       * is applied on them.
	       */
	      if ((!WIFEXITED (w) && WIFSTOPPED (w)) ||
		  (WIFEXITED (w) && WEXITSTATUS (w) > 0377))
		{
		  WSETEXIT (w, 0);
		  warning ("Using exit value 0 for terminated task");
		}
	      else if (!WIFEXITED (w))
		{
		  int sig = WTERMSIG (w);

		  /* Signals cause problems. Warn the user. */
		  if (sig != SIGKILL)	/* Bad luck if garbage matches this */
		    warning ("The terminating signal stuff may be nonsense");
		  else if (sig > NSIG)
		    {
		      WSETEXIT (w, 0);
		      warning ("Using exit value 0 for terminated task");
		    }
		}
	      store_waitstatus (ourstatus, w);
	      return inferior_ptid;
	    }
	}

      /* Hmm. Check for exception, as it was not a notification.
         exc_server() does an upcall to catch_exception_raise()
         if this rpc is an exception. Further actions are decided
         there.
       */
      if (!exc_server (&in_msg.header, &out_msg.header))
	{

	  /* Not an exception, check for message.

	   * Messages don't come from the inferior, or if they
	   * do they better be asynchronous or it will hang.
	   */
	  if (gdb_message_server (&in_msg.header))
	    continue;

	  error ("Unrecognized message received in mach_really_wait");
	}

      /* Send the reply of the exception rpc to the suspended task */
      ret = mach_msg_send (&out_msg.header);
      CHK ("mach_msg_send (exc reply)", ret);

      if (stopped_in_exception)
	{
	  /* Get unix state. May be changed in mach3_exception_actions() */
	  wait3 (&w, WNOHANG, 0);

	  mach3_exception_actions (&w, FALSE, "Task");

	  store_waitstatus (ourstatus, w);
	  return inferior_ptid;
	}
    }
}

/* Called by macro DO_QUIT() in utils.c(quit).
 * This is called just before calling error() to return to command level
 */
void
mach3_quit (void)
{
  int mid;
  kern_return_t ret;

  if (mach_really_waiting)
    {
      ret = task_suspend (inferior_task);

      if (ret != KERN_SUCCESS)
	{
	  warning ("Could not suspend task for interrupt: %s",
		   mach_error_string (ret));
	  mach_really_waiting = 0;
	  return;
	}
    }

  must_suspend_thread = 0;
  mach_really_waiting = 0;

  mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);
  if (mid == -1)
    {
      warning ("Selecting first existing kernel thread");
      mid = 0;
    }

  current_thread = MACH_PORT_NULL;	/* Force setup */
  select_thread (inferior_task, mid, 1);

  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.
 *
 * Called by REQUEST_QUIT() from utils.c(request_quit)
 */
void
mach3_request_quit (void)
{
  if (mach_really_waiting)
    immediate_quit = 1;
}
#endif

/*
 * Gdb message server.
 * Currently implemented is the STOP message, that causes
 * gdb to return to the command level like ^C had been typed from terminal.
 */
int
gdb_message_server (mach_msg_header_t *InP)
{
  kern_return_t ret;
  int mid;

  if (InP->msgh_local_port == our_message_port)
    {
      /* A message coming to our_message_port. Check validity */
      switch (InP->msgh_id)
	{

	case GDB_MESSAGE_ID_STOP:
	  ret = task_suspend (inferior_task);
	  if (ret != KERN_SUCCESS)
	    warning ("Could not suspend task for stop message: %s",
		     mach_error_string (ret));

	  /* QUIT in mach_really_wait() loop. */
	  request_quit (0);
	  break;

	default:
	  warning ("Invalid message id %d received, ignored.",
		   InP->msgh_id);
	  break;
	}

      return 1;
    }

  /* Message not handled by this server */
  return 0;
}

/* NOTE: This is not an RPC call. It is a simpleroutine.

 * This is not called from this gdb code.
 *
 * It may be called by another debugger to cause this
 * debugger to enter command level:
 *
 *            (gdb) set stop_inferior_gdb ()
 *            (gdb) continue
 *
 * External program "stop-gdb" implements this also.
 */
void
stop_inferior_gdb (void)
{
  kern_return_t ret;

  /* Code generated by mig, with minor cleanups :-)

   * simpleroutine stop_inferior_gdb (our_message_port : mach_port_t);
   */

  typedef struct
    {
      mach_msg_header_t Head;
    }
  Request;

  Request Mess;

  register Request *InP = &Mess;

  InP->Head.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);

  /* msgh_size passed as argument */
  InP->Head.msgh_remote_port = our_message_port;
  InP->Head.msgh_local_port = MACH_PORT_NULL;
  InP->Head.msgh_seqno = 0;
  InP->Head.msgh_id = GDB_MESSAGE_ID_STOP;

  ret = mach_msg (&InP->Head,
		  MACH_SEND_MSG | MACH_MSG_OPTION_NONE,
		  sizeof (Request),
		  0,
		  MACH_PORT_NULL,
		  MACH_MSG_TIMEOUT_NONE,
		  MACH_PORT_NULL);
}

#ifdef THREAD_ALLOWED_TO_BREAK
/*
 * Return 1 if the MID specifies the thread that caused the
 * last exception.
 *  Since catch_exception_raise() selects the thread causing
 * the last exception to current_thread, we just check that
 * it is selected and the last exception was a breakpoint.
 */
int
mach_thread_for_breakpoint (int mid)
{
  int cmid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);

  if (mid < 0)
    {
      mid = map_slot_to_mid (-(mid + 1), 0, 0);
      if (mid < 0)
	return 0;		/* Don't stop, no such slot */
    }

  if (!mid || cmid == -1)
    return 1;			/* stop */

  return cmid == mid && stop_exception == EXC_BREAKPOINT;
}
#endif /* THREAD_ALLOWED_TO_BREAK */

#ifdef THREAD_PARSE_ID
/*
 * Map a thread id string (MID or a @SLOTNUMBER)
 * to a thread-id.
 *
 *   0  matches all threads.
 *   Otherwise the meaning is defined only in this file.
 *   (mach_thread_for_breakpoint uses it)
 *
 * @@ This allows non-existent MIDs to be specified.
 *    It now also allows non-existent slots to be
 *    specified. (Slot numbers stored are negative,
 *    and the magnitude is one greater than the actual
 *    slot index. (Since 0 is reserved))
 */
int
mach_thread_parse_id (char *arg)
{
  int mid;
  if (arg == 0)
    error ("thread id expected");
  mid = parse_thread_id (arg, 0, 1);

  return mid;
}
#endif /* THREAD_PARSE_ID */

#ifdef THREAD_OUTPUT_ID
char *
mach_thread_output_id (int mid)
{
  static char foobar[20];

  if (mid > 0)
    sprintf (foobar, "mid %d", mid);
  else if (mid < 0)
    sprintf (foobar, "@%d", -(mid + 1));
  else
    sprintf (foobar, "*any thread*");

  return foobar;
}
#endif /* THREAD_OUTPUT_ID */

/* Called with hook PREPARE_TO_PROCEED() from infrun.c.

 * If we have switched threads and stopped at breakpoint return 1 otherwise 0.
 *
 *  if SELECT_IT is nonzero, reselect the thread that was active when
 *  we stopped at a breakpoint.
 *
 * Note that this implementation is potentially redundant now that
 * default_prepare_to_proceed() has been added.  
 *
 * FIXME This may not support switching threads after Ctrl-C
 * correctly. The default implementation does support this.
 */

mach3_prepare_to_proceed (int select_it)
{
  if (stop_thread &&
      stop_thread != current_thread &&
      stop_exception == EXC_BREAKPOINT)
    {
      int mid;

      if (!select_it)
	return 1;

      mid = switch_to_thread (stop_thread);

      return 1;
    }

  return 0;
}

/* this stuff here is an upcall via libmach/excServer.c 
   and mach_really_wait which does the actual upcall.

   The code will pass the exception to the inferior if:

   - The task that signaled is not the inferior task
   (e.g. when debugging another debugger)

   - The user has explicitely requested to pass on the exceptions.
   (e.g to the default unix exception handler, which maps
   exceptions to signals, or the user has her own exception handler)

   - If the thread that signaled is being single-stepped and it
   has set it's own exception port and the exception is not
   EXC_BREAKPOINT. (Maybe this is not desirable?)
 */

kern_return_t
catch_exception_raise (mach_port_t port, thread_t thread, task_t task,
		       int exception, int code, int subcode)
{
  kern_return_t ret;
  boolean_t signal_thread;
  int mid = map_port_name_to_mid (thread, MACH_TYPE_THREAD);

  if (!MACH_PORT_VALID (thread))
    {
      /* If the exception was sent and thread dies before we
         receive it, THREAD will be MACH_PORT_DEAD
       */

      current_thread = thread = MACH_PORT_NULL;
      error ("Received exception from nonexistent thread");
    }

  /* Check if the task died in transit.
   * @@ Isn't the thread also invalid in such case?
   */
  if (!MACH_PORT_VALID (task))
    {
      current_thread = thread = MACH_PORT_NULL;
      error ("Received exception from nonexistent task");
    }

  if (exception < 0 || exception > MAX_EXCEPTION)
    internal_error (__FILE__, __LINE__,
		    "catch_exception_raise: unknown exception code %d thread %d",
		    exception,
		    mid);

  if (!MACH_PORT_VALID (inferior_task))
    error ("got an exception, but inferior_task is null or dead");

  stop_exception = exception;
  stop_code = code;
  stop_subcode = subcode;
  stop_thread = thread;

  signal_thread = exception != EXC_BREAKPOINT &&
    port == singlestepped_thread_port &&
    MACH_PORT_VALID (thread_saved_exception_port);

  /* If it was not our inferior or if we want to forward
   * the exception to the inferior's handler, do it here
   *
   * Note: If you have forwarded EXC_BREAKPOINT I trust you know why.
   */
  if (task != inferior_task ||
      signal_thread ||
      exception_map[exception].forward)
    {
      mach_port_t eport = inferior_old_exception_port;

      if (signal_thread)
	{
	  /*
	     GDB now forwards the exeption to thread's original handler,
	     since the user propably knows what he is doing.
	     Give a message, though.
	   */

	  mach3_exception_actions ((WAITTYPE *) NULL, TRUE, "Thread");
	  eport = thread_saved_exception_port;
	}

      /* Send the exception to the original handler */
      ret = exception_raise (eport,
			     thread,
			     task,
			     exception,
			     code,
			     subcode);

      (void) mach_port_deallocate (mach_task_self (), task);
      (void) mach_port_deallocate (mach_task_self (), thread);

      /* If we come here, we don't want to trace any more, since we
       * will never stop for tracing anyway.
       */
      discard_single_step (thread);

      /* Do not stop the inferior */
      return ret;
    }

  /* Now gdb handles the exception */
  stopped_in_exception = TRUE;

  ret = task_suspend (task);
  CHK ("Error suspending inferior after exception", ret);

  must_suspend_thread = 0;

  if (current_thread != thread)
    {
      if (MACH_PORT_VALID (singlestepped_thread_port))
	/* Cleanup discards single stepping */
	error ("Exception from thread %d while singlestepping thread %d",
	       mid,
	       map_port_name_to_mid (current_thread, MACH_TYPE_THREAD));

      /* Then select the thread that caused the exception */
      if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS)
	error ("Could not select thread %d causing exception", mid);
      else
	warning ("Gdb selected thread %d", mid);
    }

  /* If we receive an exception that is not breakpoint
   * exception, we interrupt the single step and return to
   * debugger. Trace condition is cleared.
   */
  if (MACH_PORT_VALID (singlestepped_thread_port))
    {
      if (stop_exception != EXC_BREAKPOINT)
	warning ("Single step interrupted by exception");
      else if (port == singlestepped_thread_port)
	{
	  /* Single step exception occurred, remove trace bit
	   * and return to gdb.
	   */
	  if (!MACH_PORT_VALID (current_thread))
	    error ("Single stepped thread is not valid");

	  /* Resume threads, but leave the task suspended */
	  resume_all_threads (0);
	}
      else
	warning ("Breakpoint while single stepping?");

      discard_single_step (current_thread);
    }

  (void) mach_port_deallocate (mach_task_self (), task);
  (void) mach_port_deallocate (mach_task_self (), thread);

  return KERN_SUCCESS;
}

int
port_valid (mach_port_t port, int mask)
{
  kern_return_t ret;
  mach_port_type_t type;

  ret = mach_port_type (mach_task_self (),
			port,
			&type);
  if (ret != KERN_SUCCESS || (type & mask) != mask)
    return 0;
  return 1;
}

/* @@ No vm read cache implemented yet */
boolean_t vm_read_cache_valid = FALSE;

/*
 * 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
mach3_read_inferior (CORE_ADDR addr, char *myaddr, int length)
{
  kern_return_t ret;
  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_memory;
  int copy_count;

  /* Get memory from inferior with page aligned addresses */
  ret = vm_read (inferior_task,
		 low_address,
		 aligned_length,
		 &copied_memory,
		 &copy_count);
  if (ret != KERN_SUCCESS)
    {
      /* the problem is that the inferior might be killed for whatever reason
       * before we go to mach_really_wait. This is one place that ought to
       * catch many of those errors.
       * @@ A better fix would be to make all external events to GDB
       * to arrive via a SINGLE port set. (Including user input!)
       */

      if (!port_valid (inferior_task, MACH_PORT_TYPE_SEND))
	{
	  m3_kill_inferior ();
	  error ("Inferior killed (task port invalid)");
	}
      else
	{
#ifdef OSF
	  extern int errno;
	  /* valprint.c gives nicer format if this does not
	     screw it. Eamonn seems to like this, so I enable
	     it if OSF is defined...
	   */
	  warning ("[read inferior %x failed: %s]",
		   addr, mach_error_string (ret));
	  errno = 0;
#endif
	  return 0;
	}
    }

  memcpy (myaddr, (char *) addr - low_address + copied_memory, length);

  ret = vm_deallocate (mach_task_self (),
		       copied_memory,
		       copy_count);
  CHK ("mach3_read_inferior vm_deallocate failed", ret);

  return length;
}

#define CHK_GOTO_OUT(str,ret) \
  do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0)

struct vm_region_list
{
  struct vm_region_list *next;
  vm_prot_t protection;
  vm_address_t start;
  vm_size_t length;
};

struct obstack region_obstack;

/*
 * Write inferior task's LEN bytes from ADDR and copy it to MYADDR
 * in gdb's address space.
 */
int
mach3_write_inferior (CORE_ADDR addr, char *myaddr, int length)
{
  kern_return_t ret;
  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_memory;
  int copy_count;
  int deallocate = 0;

  char *errstr = "Bug in mach3_write_inferior";

  struct vm_region_list *region_element;
  struct vm_region_list *region_head = (struct vm_region_list *) NULL;

  /* Get memory from inferior with page aligned addresses */
  ret = vm_read (inferior_task,
		 low_address,
		 aligned_length,
		 &copied_memory,
		 &copy_count);
  CHK_GOTO_OUT ("mach3_write_inferior vm_read failed", ret);

  deallocate++;

  memcpy ((char *) addr - low_address + copied_memory, myaddr, length);

  obstack_init (&region_obstack);

  /* Do writes atomically.
   * First check for holes and unwritable memory.
   */
  {
    vm_size_t remaining_length = aligned_length;
    vm_address_t region_address = low_address;

    struct vm_region_list *scan;

    while (region_address < low_address + aligned_length)
      {
	vm_prot_t protection;
	vm_prot_t max_protection;
	vm_inherit_t inheritance;
	boolean_t shared;
	mach_port_t object_name;
	vm_offset_t offset;
	vm_size_t region_length = remaining_length;
	vm_address_t old_address = region_address;

	ret = vm_region (inferior_task,
			 &region_address,
			 &region_length,
			 &protection,
			 &max_protection,
			 &inheritance,
			 &shared,
			 &object_name,
			 &offset);
	CHK_GOTO_OUT ("vm_region failed", ret);

	/* Check for holes in memory */
	if (old_address != region_address)
	  {
	    warning ("No memory at 0x%x. Nothing written",
		     old_address);
	    ret = KERN_SUCCESS;
	    length = 0;
	    goto out;
	  }

	if (!(max_protection & VM_PROT_WRITE))
	  {
	    warning ("Memory at address 0x%x is unwritable. Nothing written",
		     old_address);
	    ret = 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));

	region_element->protection = protection;
	region_element->start = region_address;
	region_element->length = region_length;

	/* Chain the regions along with protections */
	region_element->next = region_head;
	region_head = region_element;

	region_address += region_length;
	remaining_length = remaining_length - region_length;
      }

    /* If things fail after this, we give up.
     * Somebody is messing up inferior_task's mappings.
     */

    /* Enable writes to the chained vm regions */
    for (scan = region_head; scan; scan = scan->next)
      {
	boolean_t protection_changed = FALSE;

	if (!(scan->protection & VM_PROT_WRITE))
	  {
	    ret = vm_protect (inferior_task,
			      scan->start,
			      scan->length,
			      FALSE,
			      scan->protection | VM_PROT_WRITE);
	    CHK_GOTO_OUT ("vm_protect: enable write failed", ret);
	  }
      }

    ret = vm_write (inferior_task,
		    low_address,
		    copied_memory,
		    aligned_length);
    CHK_GOTO_OUT ("vm_write failed", ret);

    /* Set up the original region protections, if they were changed */
    for (scan = region_head; scan; scan = scan->next)
      {
	boolean_t protection_changed = FALSE;

	if (!(scan->protection & VM_PROT_WRITE))
	  {
	    ret = vm_protect (inferior_task,
			      scan->start,
			      scan->length,
			      FALSE,
			      scan->protection);
	    CHK_GOTO_OUT ("vm_protect: enable write failed", ret);
	  }
      }
  }

out:
  if (deallocate)
    {
      obstack_free (&region_obstack, 0);

      (void) vm_deallocate (mach_task_self (),
			    copied_memory,
			    copy_count);
    }

  if (ret != KERN_SUCCESS)
    {
      warning ("%s %s", errstr, mach_error_string (ret));
      return 0;
    }

  return length;
}

/* Return 0 on failure, number of bytes handled otherwise.  TARGET is
   ignored. */
static int
m3_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
		struct target_ops *target)
{
  int result;

  if (write)
    result = mach3_write_inferior (memaddr, myaddr, len);
  else
    result = mach3_read_inferior (memaddr, myaddr, len);

  return result;
}


static char *
translate_state (int state)
{
  switch (state)
    {
    case TH_STATE_RUNNING:
      return ("R");
    case TH_STATE_STOPPED:
      return ("S");
    case TH_STATE_WAITING:
      return ("W");
    case TH_STATE_UNINTERRUPTIBLE:
      return ("U");
    case TH_STATE_HALTED:
      return ("H");
    default:
      return ("?");
    }
}

static char *
translate_cstate (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 "?";
    }
}

/* 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 (mach_port_t inferior_name, mach_msg_type_name_t type)
{
  kern_return_t ret;
  mach_msg_type_name_t acquired;
  mach_port_t iport;

  ret = mach_port_extract_right (inferior_task,
				 inferior_name,
				 type,
				 &iport,
				 &acquired);
  CHK ("mach_port_extract_right (map_inferior_port_name)", ret);

  if (acquired != MACH_MSG_TYPE_PORT_SEND)
    error ("Incorrect right extracted, (map_inferior_port_name)");

  ret = mach_port_deallocate (mach_task_self (),
			      iport);
  CHK ("Deallocating mapped port (map_inferior_port_name)", ret);

  return iport;
}

/*
 * Naming convention:
 *  Always return user defined name if found.
 *  _K == A kernel thread with no matching CPROC
 *  _C == A cproc with no current cthread
 *  _t == A cthread with no user defined name
 *
 * The digits that follow the _names are the SLOT number of the
 * kernel thread if there is such a thing, otherwise just a negation
 * of the sequential number of such cprocs.
 */

static char buf[7];

static char *
get_thread_name (gdb_thread_t one_cproc, int id)
{
  if (one_cproc)
    if (one_cproc->cthread == NULL)
      {
	/* cproc not mapped to any cthread */
	sprintf (buf, "_C%d", id);
      }
    else if (!one_cproc->cthread->name)
      {
	/* cproc and cthread, but no name */
	sprintf (buf, "_t%d", id);
      }
    else
      return (char *) (one_cproc->cthread->name);
  else
    {
      if (id < 0)
	warning ("Inconsistency in thread name id %d", id);

      /* Kernel thread without cproc */
      sprintf (buf, "_K%d", id);
    }

  return buf;
}

int
fetch_thread_info (mach_port_t task, gdb_thread_t *mthreads_out)
{
  kern_return_t ret;
  thread_array_t th_table;
  int th_count;
  gdb_thread_t mthreads = NULL;
  int index;

  ret = task_threads (task, &th_table, &th_count);
  if (ret != KERN_SUCCESS)
    {
      warning ("Error getting inferior's thread list:%s",
	       mach_error_string (ret));
      m3_kill_inferior ();
      return -1;
    }

  mthreads = (gdb_thread_t)
    obstack_alloc
    (cproc_obstack,
     th_count * sizeof (struct gdb_thread));

  for (index = 0; index < th_count; index++)
    {
      thread_t saved_thread = MACH_PORT_NULL;
      int mid;

      if (must_suspend_thread)
	setup_thread (th_table[index], 1);

      if (th_table[index] != current_thread)
	{
	  saved_thread = current_thread;

	  mid = switch_to_thread (th_table[index]);
	}

      mthreads[index].name = th_table[index];
      mthreads[index].cproc = NULL;	/* map_cprocs_to_kernel_threads() */
      mthreads[index].in_emulator = FALSE;
      mthreads[index].slotid = index;

      mthreads[index].sp = read_register (SP_REGNUM);
      mthreads[index].fp = read_register (FP_REGNUM);
      mthreads[index].pc = read_pc ();

      if (MACH_PORT_VALID (saved_thread))
	mid = switch_to_thread (saved_thread);

      if (must_suspend_thread)
	setup_thread (th_table[index], 0);
    }

  consume_send_rights (th_table, th_count);
  ret = vm_deallocate (mach_task_self (), (vm_address_t) th_table,
		       (th_count * sizeof (mach_port_t)));
  if (ret != KERN_SUCCESS)
    {
      warning ("Error trying to deallocate thread list : %s",
	       mach_error_string (ret));
    }

  *mthreads_out = mthreads;

  return th_count;
}


/*
 * Current emulator always saves the USP on top of
 * emulator stack below struct emul_stack_top stuff.
 */
CORE_ADDR
fetch_usp_from_emulator_stack (CORE_ADDR sp)
{
  CORE_ADDR stack_pointer;

  sp = (sp & ~(EMULATOR_STACK_SIZE - 1)) +
    EMULATOR_STACK_SIZE - sizeof (struct emul_stack_top);

  if (mach3_read_inferior (sp,
			   &stack_pointer,
			   sizeof (CORE_ADDR)) != sizeof (CORE_ADDR))
    {
      warning ("Can't read user sp from emulator stack address 0x%x", sp);
      return 0;
    }

  return stack_pointer;
}

#ifdef MK67

/* get_emulation_vector() interface was changed after mk67 */
#define EMUL_VECTOR_COUNT 400	/* Value does not matter too much */

#endif /* MK67 */

/* Check if the emulator exists at task's address space.
 */
boolean_t
have_emulator_p (task_t task)
{
  kern_return_t ret;
#ifndef EMUL_VECTOR_COUNT
  vm_offset_t *emulation_vector;
  int n;
#else
  vm_offset_t emulation_vector[EMUL_VECTOR_COUNT];
  int n = EMUL_VECTOR_COUNT;
#endif
  int i;
  int vector_start;

  ret = task_get_emulation_vector (task,
				   &vector_start,
#ifndef EMUL_VECTOR_COUNT
				   &emulation_vector,
#else
				   emulation_vector,
#endif
				   &n);
  CHK ("task_get_emulation_vector", ret);
  xx_debug ("%d vectors from %d at 0x%08x\n",
	    n, vector_start, emulation_vector);

  for (i = 0; i < n; i++)
    {
      vm_offset_t entry = emulation_vector[i];

      if (EMULATOR_BASE <= entry && entry <= EMULATOR_END)
	return TRUE;
      else if (entry)
	{
	  static boolean_t informed = FALSE;
	  if (!informed)
	    {
	      warning ("Emulation vector address 0x08%x outside emulator space",
		       entry);
	      informed = TRUE;
	    }
	}
    }
  return FALSE;
}

/* Map cprocs to kernel threads and vice versa.  */

void
map_cprocs_to_kernel_threads (gdb_thread_t cprocs, gdb_thread_t mthreads,
			      int thread_count)
{
  int index;
  gdb_thread_t scan;
  boolean_t all_mapped = TRUE;
  LONGEST stack_base;
  LONGEST stack_size;

  for (scan = cprocs; scan; scan = scan->next)
    {
      /* Default to: no kernel thread for this cproc */
      scan->reverse_map = -1;

      /* Check if the cproc is found by its stack */
      for (index = 0; index < thread_count; index++)
	{
	  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;
	      scan->reverse_map = index;
	      break;
	    }
	}
      all_mapped &= (scan->reverse_map != -1);
    }

  /* Check for threads that are currently in the emulator.
   * If so, they have a different stack, and the still unmapped
   * cprocs may well get mapped to these threads.
   * 
   * If:
   *  - cproc stack does not match any kernel thread stack pointer
   *  - there is at least one extra kernel thread
   *    that has no cproc mapped above.
   *  - some kernel thread stack pointer points to emulator space
   *  then we find the user stack pointer saved in the emulator
   *  stack, and try to map that to the cprocs.
   *
   * Also set in_emulator for kernel threads.
   */

  if (emulator_present)
    {
      for (index = 0; index < thread_count; index++)
	{
	  CORE_ADDR emul_sp;
	  CORE_ADDR usp;

	  gdb_thread_t mthread = (mthreads + index);
	  emul_sp = mthread->sp;

	  if (mthread->cproc == NULL &&
	      EMULATOR_BASE <= emul_sp && emul_sp <= EMULATOR_END)
	    {
	      mthread->in_emulator = emulator_present;

	      if (!all_mapped && cprocs)
		{
		  usp = fetch_usp_from_emulator_stack (emul_sp);

		  /* @@ Could be more accurate */
		  if (!usp)
		    error ("Zero stack pointer read from emulator?");

		  /* Try to match this stack pointer to the cprocs that
		   * don't yet have a kernel thread.
		   */
		  for (scan = cprocs; scan; scan = scan->next)
		    {

		      /* Check is this unmapped CPROC stack contains
		       * the user stack pointer saved in the
		       * emulator.
		       */
		      if (scan->reverse_map == -1)
			{
			  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;
			    }
			}
		    }
		}
	    }
	}
    }
}

/*
 * Format of the thread_list command
 *
 *                   slot mid sel   name  emul ks susp  cstate wired   address
 */
#define TL_FORMAT "%-2.2s %5d%c %-10.10s %1.1s%s%-5.5s %-2.2s %-5.5s "

#define TL_HEADER "\n@    MID  Name        KState CState   Where\n"

void
print_tl_address (struct ui_file *stream, CORE_ADDR pc)
{
  if (!lookup_minimal_symbol_by_pc (pc))
    fprintf_filtered (stream, local_hex_format (), pc);
  else
    {
      extern int addressprint;
      extern int asm_demangle;

      int store = addressprint;
      addressprint = 0;
      print_address_symbolic (pc, stream, asm_demangle, "");
      addressprint = store;
    }
}

/* For thread names, but also for gdb_message_port external name */
#define MAX_NAME_LEN 50

/* Returns the address of variable NAME or 0 if not found */
CORE_ADDR
lookup_address_of_variable (char *name)
{
  struct symbol *sym;
  CORE_ADDR symaddr = 0;
  struct minimal_symbol *msymbol;

  sym = lookup_symbol (name,
		       (struct block *) NULL,
		       VAR_NAMESPACE,
		       (int *) NULL,
		       (struct symtab **) NULL);

  if (sym)
    symaddr = SYMBOL_VALUE (sym);

  if (!symaddr)
    {
      msymbol = lookup_minimal_symbol (name, NULL, NULL);

      if (msymbol && msymbol->type == mst_data)
	symaddr = SYMBOL_VALUE_ADDRESS (msymbol);
    }

  return symaddr;
}

static gdb_thread_t
get_cprocs (void)
{
  gdb_thread_t cproc_head;
  gdb_thread_t cproc_copy;
  CORE_ADDR their_cprocs;
  char *buf;
  char *name;
  cthread_t cthread;
  CORE_ADDR symaddr;

  buf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
  symaddr = lookup_address_of_variable ("cproc_list");

  if (!symaddr)
    {
      /* 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++;
	      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 NULL;

  /* Get the address of the first cproc in the task */
  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 = NULL;

  while (their_cprocs != (CORE_ADDR) 0)
    {
      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 =
	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,
				    cthread,
				    sizeof (struct cthread)))
	      error ("Can't read next thread at 0x%x.",
		     cproc_copy_incarnation);

	  cproc_copy->cthread = cthread;

	  if (cthread->name)
	    {
	      name = (char *) obstack_alloc (cproc_obstack, MAX_NAME_LEN);

	      if (!mach3_read_inferior (cthread->name, name, MAX_NAME_LEN))
		error ("Can't read next thread's name at 0x%x.", cthread->name);

	      cthread->name = name;
	    }
	}

      /* insert in front */
      cproc_copy->next = cproc_head;
      cproc_head = cproc_copy;
    }
  return cproc_head;
}

#ifndef FETCH_CPROC_STATE
/*
 * Check if your machine does not grok the way this routine
 * fetches the FP,PC and SP of a cproc that is not
 * currently attached to any kernel thread (e.g. its cproc.context
 * field points to the place in stack where the context
 * is saved).
 *
 * If it doesn't, define your own routine.
 */
#define FETCH_CPROC_STATE(mth) mach3_cproc_state (mth)

int
mach3_cproc_state (gdb_thread_t mthread)
{
  int context;

  if (!mthread || !mthread->cproc)
    return -1;

  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;

  if (mach3_read_inferior (context + MACHINE_CPROC_PC_OFFSET,
			   &mthread->pc,
			   sizeof (CORE_ADDR)) != sizeof (CORE_ADDR))
    {
      warning ("Can't read cproc pc from inferior");
      return -1;
    }

  if (mach3_read_inferior (context + MACHINE_CPROC_FP_OFFSET,
			   &mthread->fp,
			   sizeof (CORE_ADDR)) != sizeof (CORE_ADDR))
    {
      warning ("Can't read cproc fp from inferior");
      return -1;
    }

  return 0;
}
#endif /* FETCH_CPROC_STATE */


void
thread_list_command (void)
{
  thread_basic_info_data_t ths;
  int thread_count;
  gdb_thread_t cprocs;
  gdb_thread_t scan;
  int index;
  char *name;
  char selected;
  char *wired;
  int infoCnt;
  kern_return_t ret;
  mach_port_t mid_or_port;
  gdb_thread_t their_threads;
  gdb_thread_t kthread;

  int neworder = 1;

  char *fmt = "There are %d kernel threads in task %d.\n";

  int tmid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK);

  MACH_ERROR_NO_INFERIOR;

  thread_count = fetch_thread_info (inferior_task,
				    &their_threads);
  if (thread_count == -1)
    return;

  if (thread_count == 1)
    fmt = "There is %d kernel thread in task %d.\n";

  printf_filtered (fmt, thread_count, tmid);

  puts_filtered (TL_HEADER);

  cprocs = get_cprocs ();

  map_cprocs_to_kernel_threads (cprocs, their_threads, thread_count);

  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 = (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;

      if (kthread)
	{
	  /* These cprocs have a kernel thread */

	  mid = map_port_name_to_mid (kthread->name, MACH_TYPE_THREAD);

	  infoCnt = THREAD_BASIC_INFO_COUNT;

	  ret = thread_info (kthread->name,
			     THREAD_BASIC_INFO,
			     (thread_info_t) & ths,
			     &infoCnt);

	  if (ret != KERN_SUCCESS)
	    {
	      warning ("Unable to get basic info on thread %d : %s",
		       mid,
		       mach_error_string (ret));
	      continue;
	    }

	  /* Who is the first to have more than 100 threads */
	  sprintf (slot, "%d", kthread->slotid % 100);

	  if (kthread->name == current_thread)
	    selected = '*';

	  if (ths.suspend_count)
	    sprintf (buf, "%d", ths.suspend_count);
	  else
	    buf[0] = '\000';

#if 0
	  if (ths.flags & TH_FLAGS_SWAPPED)
	    strcat (buf, "S");
#endif

	  if (ths.flags & TH_FLAGS_IDLE)
	    strcat (buf, "I");

	  printf_filtered (TL_FORMAT,
			   slot,
			   mid,
			   selected,
			   get_thread_name (scan, kthread->slotid),
			   kthread->in_emulator ? "E" : "",
			   translate_state (ths.run_state),
			   buf,
			   translate_cstate (cproc_state),
			   wired);
	  print_tl_address (gdb_stdout, kthread->pc);
	}
      else
	{
	  /* These cprocs don't have a kernel thread.
	   * find out the calling frame with 
	   * FETCH_CPROC_STATE.
	   */

	  struct gdb_thread state;

#if 0
	  /* jtv -> emcmanus: why do you want this here? */
	  if (scan->incarnation == NULL)
	    continue;		/* EMcM */
#endif

	  printf_filtered (TL_FORMAT,
			   "-",
			   -neworder,	/* Pseudo MID */
			   selected,
			   get_thread_name (scan, -neworder),
			   "",
			   "-",	/* kernel state */
			   "",
			   translate_cstate (cproc_state),
			   "");
	  state.cproc = scan;

	  if (FETCH_CPROC_STATE (&state) == -1)
	    puts_filtered ("???");
	  else
	    print_tl_address (gdb_stdout, state.pc);

	  neworder++;
	}
      puts_filtered ("\n");
    }

  /* Scan for kernel threads without cprocs */
  for (index = 0; index < thread_count; index++)
    {
      if (!their_threads[index].cproc)
	{
	  int mid;

	  char buf[10];
	  char slot[3];

	  mach_port_t name = their_threads[index].name;

	  mid = map_port_name_to_mid (name, MACH_TYPE_THREAD);

	  infoCnt = THREAD_BASIC_INFO_COUNT;

	  ret = thread_info (name,
			     THREAD_BASIC_INFO,
			     (thread_info_t) & ths,
			     &infoCnt);

	  if (ret != KERN_SUCCESS)
	    {
	      warning ("Unable to get basic info on thread %d : %s",
		       mid,
		       mach_error_string (ret));
	      continue;
	    }

	  sprintf (slot, "%d", index % 100);

	  if (name == current_thread)
	    selected = '*';
	  else
	    selected = ' ';

	  if (ths.suspend_count)
	    sprintf (buf, "%d", ths.suspend_count);
	  else
	    buf[0] = '\000';

#if 0
	  if (ths.flags & TH_FLAGS_SWAPPED)
	    strcat (buf, "S");
#endif

	  if (ths.flags & TH_FLAGS_IDLE)
	    strcat (buf, "I");

	  printf_filtered (TL_FORMAT,
			   slot,
			   mid,
			   selected,
			   get_thread_name (NULL, index),
			   their_threads[index].in_emulator ? "E" : "",
			   translate_state (ths.run_state),
			   buf,
			   "",	/* No cproc state */
			   "");	/* Can't be wired */
	  print_tl_address (gdb_stdout, their_threads[index].pc);
	  puts_filtered ("\n");
	}
    }

  obstack_free (cproc_obstack, 0);
  obstack_init (cproc_obstack);
}

void
thread_select_command (char *args, int from_tty)
{
  int mid;
  thread_array_t thread_list;
  int thread_count;
  kern_return_t ret;
  int is_slot = 0;

  MACH_ERROR_NO_INFERIOR;

  if (!args)
    error_no_arg ("MID or @SLOTNUMBER to specify a thread to select");

  while (*args == ' ' || *args == '\t')
    args++;

  if (*args == '@')
    {
      is_slot++;
      args++;
    }

  mid = atoi (args);

  if (mid == 0)
    if (!is_slot || *args != '0')	/* Rudimentary checks */
      error ("You must select threads by MID or @SLOTNUMBER");

  if (select_thread (inferior_task, mid, is_slot ? 2 : 1) != KERN_SUCCESS)
    return;

  if (from_tty)
    printf_filtered ("Thread %d selected\n",
		     is_slot ? map_port_name_to_mid (current_thread,
						   MACH_TYPE_THREAD) : mid);
}

thread_trace (mach_port_t thread, boolean_t set)
{
  int flavor = TRACE_FLAVOR;
  unsigned int stateCnt = TRACE_FLAVOR_SIZE;
  kern_return_t ret;
  thread_state_data_t state;

  if (!MACH_PORT_VALID (thread))
    {
      warning ("thread_trace: invalid thread");
      return;
    }

  if (must_suspend_thread)
    setup_thread (thread, 1);

  ret = thread_get_state (thread, flavor, state, &stateCnt);
  CHK ("thread_trace: error reading thread state", ret);

  if (set)
    {
      TRACE_SET (thread, state);
    }
  else
    {
      if (!TRACE_CLEAR (thread, state))
	{
	  if (must_suspend_thread)
	    setup_thread (thread, 0);
	  return;
	}
    }

  ret = thread_set_state (thread, flavor, state, stateCnt);
  CHK ("thread_trace: error writing thread state", ret);
  if (must_suspend_thread)
    setup_thread (thread, 0);
}

#ifdef	FLUSH_INFERIOR_CACHE

/* 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 */

flush_inferior_icache (CORE_ADDR pc, int amount)
{
  vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH;
  kern_return_t ret;

  ret = vm_machine_attribute (inferior_task,
			      pc,
			      amount,
			      MATTR_CACHE,
			      &flush);
  if (ret != KERN_SUCCESS)
    warning ("Error flushing inferior's cache : %s",
	     mach_error_string (ret));
}
#endif /* FLUSH_INFERIOR_CACHE */


static
suspend_all_threads (int from_tty)
{
  kern_return_t ret;
  thread_array_t thread_list;
  int thread_count, index;
  int infoCnt;
  thread_basic_info_data_t th_info;


  ret = task_threads (inferior_task, &thread_list, &thread_count);
  if (ret != KERN_SUCCESS)
    {
      warning ("Could not suspend inferior threads.");
      m3_kill_inferior ();
      throw_exception (RETURN_ERROR);
    }

  for (index = 0; index < thread_count; index++)
    {
      int mid;

      mid = map_port_name_to_mid (thread_list[index],
				  MACH_TYPE_THREAD);

      ret = thread_suspend (thread_list[index]);

      if (ret != KERN_SUCCESS)
	warning ("Error trying to suspend thread %d : %s",
		 mid, mach_error_string (ret));

      if (from_tty)
	{
	  infoCnt = THREAD_BASIC_INFO_COUNT;
	  ret = thread_info (thread_list[index],
			     THREAD_BASIC_INFO,
			     (thread_info_t) & th_info,
			     &infoCnt);
	  CHK ("suspend can't get thread info", ret);

	  warning ("Thread %d suspend count is %d",
		   mid, th_info.suspend_count);
	}
    }

  consume_send_rights (thread_list, thread_count);
  ret = vm_deallocate (mach_task_self (),
		       (vm_address_t) thread_list,
		       (thread_count * sizeof (int)));
  CHK ("Error trying to deallocate thread list", ret);
}

void
thread_suspend_command (char *args, int from_tty)
{
  kern_return_t ret;
  int mid;
  mach_port_t saved_thread;
  int infoCnt;
  thread_basic_info_data_t th_info;

  MACH_ERROR_NO_INFERIOR;

  if (!strcasecmp (args, "all"))
    {
      suspend_all_threads (from_tty);
      return;
    }

  saved_thread = current_thread;

  mid = parse_thread_id (args, 0, 0);

  if (mid < 0)
    error ("You can suspend only existing kernel threads with MID or @SLOTNUMBER");

  if (mid == 0)
    mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);
  else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS)
    {
      if (current_thread)
	current_thread = saved_thread;
      error ("Could not select thread %d", mid);
    }

  ret = thread_suspend (current_thread);
  if (ret != KERN_SUCCESS)
    warning ("thread_suspend failed : %s",
	     mach_error_string (ret));

  infoCnt = THREAD_BASIC_INFO_COUNT;
  ret = thread_info (current_thread,
		     THREAD_BASIC_INFO,
		     (thread_info_t) & th_info,
		     &infoCnt);
  CHK ("suspend can't get thread info", ret);

  warning ("Thread %d suspend count is %d", mid, th_info.suspend_count);

  current_thread = saved_thread;
}

resume_all_threads (int from_tty)
{
  kern_return_t ret;
  thread_array_t thread_list;
  int thread_count, index;
  int mid;
  int infoCnt;
  thread_basic_info_data_t th_info;

  ret = task_threads (inferior_task, &thread_list, &thread_count);
  if (ret != KERN_SUCCESS)
    {
      m3_kill_inferior ();
      error ("task_threads", mach_error_string (ret));
    }

  for (index = 0; index < thread_count; index++)
    {
      infoCnt = THREAD_BASIC_INFO_COUNT;
      ret = thread_info (thread_list[index],
			 THREAD_BASIC_INFO,
			 (thread_info_t) & th_info,
			 &infoCnt);
      CHK ("resume_all can't get thread info", ret);

      mid = map_port_name_to_mid (thread_list[index],
				  MACH_TYPE_THREAD);

      if (!th_info.suspend_count)
	{
	  if (mid != -1 && from_tty)
	    warning ("Thread %d is not suspended", mid);
	  continue;
	}

      ret = thread_resume (thread_list[index]);

      if (ret != KERN_SUCCESS)
	warning ("Error trying to resume thread %d : %s",
		 mid, mach_error_string (ret));
      else if (mid != -1 && from_tty)
	warning ("Thread %d suspend count is %d",
		 mid, --th_info.suspend_count);
    }

  consume_send_rights (thread_list, thread_count);
  ret = vm_deallocate (mach_task_self (),
		       (vm_address_t) thread_list,
		       (thread_count * sizeof (int)));
  CHK ("Error trying to deallocate thread list", ret);
}

void
thread_resume_command (char *args, int from_tty)
{
  int mid;
  mach_port_t saved_thread;
  kern_return_t ret;
  thread_basic_info_data_t th_info;
  int infoCnt = THREAD_BASIC_INFO_COUNT;

  MACH_ERROR_NO_INFERIOR;

  if (!strcasecmp (args, "all"))
    {
      resume_all_threads (from_tty);
      return;
    }

  saved_thread = current_thread;

  mid = parse_thread_id (args, 0, 0);

  if (mid < 0)
    error ("You can resume only existing kernel threads with MID or @SLOTNUMBER");

  if (mid == 0)
    mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);
  else if (select_thread (inferior_task, mid, 0) != KERN_SUCCESS)
    {
      if (current_thread)
	current_thread = saved_thread;
      throw_exception (RETURN_ERROR);
    }

  ret = thread_info (current_thread,
		     THREAD_BASIC_INFO,
		     (thread_info_t) & th_info,
		     &infoCnt);
  CHK ("resume can't get thread info", ret);

  if (!th_info.suspend_count)
    {
      warning ("Thread %d is not suspended", mid);
      goto out;
    }

  ret = thread_resume (current_thread);
  if (ret != KERN_SUCCESS)
    warning ("thread_resume failed : %s",
	     mach_error_string (ret));
  else
    {
      th_info.suspend_count--;
      warning ("Thread %d suspend count is %d", mid, th_info.suspend_count);
    }

out:
  current_thread = saved_thread;
}

void
thread_kill_command (char *args, int from_tty)
{
  int mid;
  kern_return_t ret;
  int thread_count;
  thread_array_t thread_table;
  int index;
  mach_port_t thread_to_kill = MACH_PORT_NULL;


  MACH_ERROR_NO_INFERIOR;

  if (!args)
    error_no_arg ("thread mid to kill from the inferior task");

  mid = parse_thread_id (args, 0, 0);

  if (mid < 0)
    error ("You can kill only existing kernel threads with MID or @SLOTNUMBER");

  if (mid)
    {
      ret = machid_mach_port (mid_server, mid_auth, mid, &thread_to_kill);
      CHK ("thread_kill_command: machid_mach_port map failed", ret);
    }
  else
    mid = map_port_name_to_mid (current_thread, MACH_TYPE_THREAD);

  /* Don't allow gdb to kill *any* thread in the system. Use mkill program for that */
  ret = task_threads (inferior_task, &thread_table, &thread_count);
  CHK ("Error getting inferior's thread list", ret);

  if (thread_to_kill == current_thread)
    {
      ret = thread_terminate (thread_to_kill);
      CHK ("Thread could not be terminated", ret);

      if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS)
	warning ("Last thread was killed, use \"kill\" command to kill task");
    }
  else
    for (index = 0; index < thread_count; index++)
      if (thread_table[index] == thread_to_kill)
	{
	  ret = thread_terminate (thread_to_kill);
	  CHK ("Thread could not be terminated", ret);
	}

  if (thread_count > 1)
    consume_send_rights (thread_table, thread_count);

  ret = vm_deallocate (mach_task_self (), (vm_address_t) thread_table,
		       (thread_count * sizeof (mach_port_t)));
  CHK ("Error trying to deallocate thread list", ret);

  warning ("Thread %d killed", mid);
}


/* Task specific commands; add more if you like */

void
task_resume_command (char *args, int from_tty)
{
  kern_return_t ret;
  task_basic_info_data_t ta_info;
  int infoCnt = TASK_BASIC_INFO_COUNT;
  int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK);

  MACH_ERROR_NO_INFERIOR;

  /* Would be trivial to change, but is it desirable? */
  if (args)
    error ("Currently gdb can resume only it's inferior task");

  ret = task_info (inferior_task,
		   TASK_BASIC_INFO,
		   (task_info_t) & ta_info,
		   &infoCnt);
  CHK ("task_resume_command: task_info failed", ret);

  if (ta_info.suspend_count == 0)
    error ("Inferior task %d is not suspended", mid);
  else if (ta_info.suspend_count == 1 &&
	   from_tty &&
	!query ("Suspend count is now 1. Do you know what you are doing? "))
    error ("Task not resumed");

  ret = task_resume (inferior_task);
  CHK ("task_resume_command: task_resume", ret);

  if (ta_info.suspend_count == 1)
    {
      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
    warning ("Inferior task %d suspend count is now %d",
	     mid, ta_info.suspend_count - 1);
}


void
task_suspend_command (char *args, int from_tty)
{
  kern_return_t ret;
  task_basic_info_data_t ta_info;
  int infoCnt = TASK_BASIC_INFO_COUNT;
  int mid = map_port_name_to_mid (inferior_task, MACH_TYPE_TASK);

  MACH_ERROR_NO_INFERIOR;

  /* Would be trivial to change, but is it desirable? */
  if (args)
    error ("Currently gdb can suspend only it's inferior task");

  ret = task_suspend (inferior_task);
  CHK ("task_suspend_command: task_suspend", ret);

  must_suspend_thread = 0;

  ret = task_info (inferior_task,
		   TASK_BASIC_INFO,
		   (task_info_t) & ta_info,
		   &infoCnt);
  CHK ("task_suspend_command: task_info failed", ret);

  warning ("Inferior task %d suspend count is now %d",
	   mid, ta_info.suspend_count);
}

static char *
get_size (int bytes)
{
  static char size[30];
  int zz = bytes / 1024;

  if (zz / 1024)
    sprintf (size, "%-2.1f M", ((float) bytes) / (1024.0 * 1024.0));
  else
    sprintf (size, "%d K", zz);

  return size;
}

/* Does this require the target task to be suspended?? I don't think so. */
void
task_info_command (char *args, int from_tty)
{
  int mid = -5;
  mach_port_t task;
  kern_return_t ret;
  task_basic_info_data_t ta_info;
  int infoCnt = TASK_BASIC_INFO_COUNT;
  int page_size = round_page (1);
  int thread_count = 0;

  if (MACH_PORT_VALID (inferior_task))
    mid = map_port_name_to_mid (inferior_task,
				MACH_TYPE_TASK);

  task = inferior_task;

  if (args)
    {
      int tmid = atoi (args);

      if (tmid <= 0)
	error ("Invalid mid %d for task info", tmid);

      if (tmid != mid)
	{
	  mid = tmid;
	  ret = machid_mach_port (mid_server, mid_auth, tmid, &task);
	  CHK ("task_info_command: machid_mach_port map failed", ret);
	}
    }

  if (mid < 0)
    error ("You have to give the task MID as an argument");

  ret = task_info (task,
		   TASK_BASIC_INFO,
		   (task_info_t) & ta_info,
		   &infoCnt);
  CHK ("task_info_command: task_info failed", ret);

  printf_filtered ("\nTask info for task %d:\n\n", mid);
  printf_filtered (" Suspend count : %d\n", ta_info.suspend_count);
  printf_filtered (" Base priority : %d\n", ta_info.base_priority);
  printf_filtered (" Virtual size  : %s\n", get_size (ta_info.virtual_size));
  printf_filtered (" Resident size : %s\n", get_size (ta_info.resident_size));

  {
    thread_array_t thread_list;

    ret = task_threads (task, &thread_list, &thread_count);
    CHK ("task_info_command: task_threads", ret);

    printf_filtered (" Thread count  : %d\n", thread_count);

    consume_send_rights (thread_list, thread_count);
    ret = vm_deallocate (mach_task_self (),
			 (vm_address_t) thread_list,
			 (thread_count * sizeof (int)));
    CHK ("Error trying to deallocate thread list", ret);
  }
  if (have_emulator_p (task))
    printf_filtered (" Emulator at   : 0x%x..0x%x\n",
		     EMULATOR_BASE, EMULATOR_END);
  else
    printf_filtered (" No emulator.\n");

  if (thread_count && task == inferior_task)
    printf_filtered ("\nUse the \"thread list\" command to see the threads\n");
}

/* You may either FORWARD the exception to the inferior, or KEEP
 * it and return to GDB command level.
 *
 * exception mid [ forward | keep ]
 */

static void
exception_command (char *args, int from_tty)
{
  char *scan = args;
  int exception;
  int len;

  if (!args)
    error_no_arg ("exception number action");

  while (*scan == ' ' || *scan == '\t')
    scan++;

  if ('0' <= *scan && *scan <= '9')
    while ('0' <= *scan && *scan <= '9')
      scan++;
  else
    error ("exception number action");

  exception = atoi (args);
  if (exception <= 0 || exception > MAX_EXCEPTION)
    error ("Allowed exception numbers are in range 1..%d",
	   MAX_EXCEPTION);

  if (*scan != ' ' && *scan != '\t')
    error ("exception number must be followed by a space");
  else
    while (*scan == ' ' || *scan == '\t')
      scan++;

  args = scan;
  len = 0;
  while (*scan)
    {
      len++;
      scan++;
    }

  if (!len)
    error ("exception number action");

  if (!strncasecmp (args, "forward", len))
    exception_map[exception].forward = TRUE;
  else if (!strncasecmp (args, "keep", len))
    exception_map[exception].forward = FALSE;
  else
    error ("exception action is either \"keep\" or \"forward\"");
}

static void
print_exception_info (int exception)
{
  boolean_t forward = exception_map[exception].forward;

  printf_filtered ("%s\t(%d): ", exception_map[exception].name,
		   exception);
  if (!forward)
    if (exception_map[exception].sigmap != SIG_UNKNOWN)
      printf_filtered ("keep and handle as signal %d\n",
		       exception_map[exception].sigmap);
    else
      printf_filtered ("keep and handle as unknown signal %d\n",
		       exception_map[exception].sigmap);
  else
    printf_filtered ("forward exception to inferior\n");
}

void
exception_info (char *args, int from_tty)
{
  int exception;

  if (!args)
    for (exception = 1; exception <= MAX_EXCEPTION; exception++)
      print_exception_info (exception);
  else
    {
      exception = atoi (args);

      if (exception <= 0 || exception > MAX_EXCEPTION)
	error ("Invalid exception number, values from 1 to %d allowed",
	       MAX_EXCEPTION);
      print_exception_info (exception);
    }
}

/* Check for actions for mach exceptions.
 */
mach3_exception_actions (WAITTYPE *w, boolean_t force_print_only, char *who)
{
  boolean_t force_print = FALSE;


  if (force_print_only ||
      exception_map[stop_exception].sigmap == SIG_UNKNOWN)
    force_print = TRUE;
  else
    WSETSTOP (*w, exception_map[stop_exception].sigmap);

  if (exception_map[stop_exception].print || force_print)
    {
      target_terminal_ours ();

      printf_filtered ("\n%s received %s exception : ",
		       who,
		       exception_map[stop_exception].name);

      wrap_here ("   ");

      switch (stop_exception)
	{
	case EXC_BAD_ACCESS:
	  printf_filtered ("referencing address 0x%x : %s\n",
			   stop_subcode,
			   mach_error_string (stop_code));
	  break;
	case EXC_BAD_INSTRUCTION:
	  printf_filtered
	    ("illegal or undefined instruction. code %d subcode %d\n",
	     stop_code, stop_subcode);
	  break;
	case EXC_ARITHMETIC:
	  printf_filtered ("code %d\n", stop_code);
	  break;
	case EXC_EMULATION:
	  printf_filtered ("code %d subcode %d\n", stop_code, stop_subcode);
	  break;
	case EXC_SOFTWARE:
	  printf_filtered ("%s specific, code 0x%x\n",
			   stop_code < 0xffff ? "hardware" : "os emulation",
			   stop_code);
	  break;
	case EXC_BREAKPOINT:
	  printf_filtered ("type %d (machine dependent)\n",
			   stop_code);
	  break;
	default:
	  internal_error (__FILE__, __LINE__,
			  "Unknown exception");
	}
    }
}

setup_notify_port (int create_new)
{
  kern_return_t ret;

  if (MACH_PORT_VALID (our_notify_port))
    {
      ret = mach_port_destroy (mach_task_self (), our_notify_port);
      CHK ("Could not destroy our_notify_port", ret);
    }

  our_notify_port = MACH_PORT_NULL;
  notify_chain = (port_chain_t) NULL;
  port_chain_destroy (port_chain_obstack);

  if (create_new)
    {
      ret = mach_port_allocate (mach_task_self (),
				MACH_PORT_RIGHT_RECEIVE,
				&our_notify_port);
      if (ret != KERN_SUCCESS)
	internal_error (__FILE__, __LINE__,
			"Creating notify port %s", mach_error_string (ret));

      ret = mach_port_move_member (mach_task_self (),
				   our_notify_port,
				   inferior_wait_port_set);
      if (ret != KERN_SUCCESS)
	internal_error (__FILE__, __LINE__,
			"initial move member %s", mach_error_string (ret));
    }
}

/*
 * Register our message port to the net name server
 *
 * Currently used only by the external stop-gdb program
 * since ^C does not work if you would like to enter
 * gdb command level while debugging your program.
 *
 * NOTE: If the message port is sometimes used for other
 * purposes also, the NAME must not be a guessable one.
 * Then, there should be a way to change it.
 */

char registered_name[MAX_NAME_LEN];

void
message_port_info (char *args, int from_tty)
{
  if (registered_name[0])
    printf_filtered ("gdb's message port name: '%s'\n",
		     registered_name);
  else
    printf_filtered ("gdb's message port is not currently registered\n");
}

void
gdb_register_port (char *name, mach_port_t port)
{
  kern_return_t ret;
  static int already_signed = 0;
  int len;

  if (!MACH_PORT_VALID (port) || !name || !*name)
    {
      warning ("Invalid registration request");
      return;
    }

  if (!already_signed)
    {
      ret = mach_port_insert_right (mach_task_self (),
				    our_message_port,
				    our_message_port,
				    MACH_MSG_TYPE_MAKE_SEND);
      CHK ("Failed to create a signature to our_message_port", ret);
      already_signed = 1;
    }
  else if (already_signed > 1)
    {
      ret = netname_check_out (name_server_port,
			       registered_name,
			       our_message_port);
      CHK ("Failed to check out gdb's message port", ret);
      registered_name[0] = '\000';
      already_signed = 1;
    }

  ret = netname_check_in (name_server_port,	/* Name server port */
			  name,	/* Name of service */
			  our_message_port,	/* Signature */
			  port);	/* Creates a new send right */
  CHK ("Failed to check in the port", ret);

  len = 0;
  while (len < MAX_NAME_LEN && *(name + len))
    {
      registered_name[len] = *(name + len);
      len++;
    }
  registered_name[len] = '\000';
  already_signed = 2;
}

struct cmd_list_element *cmd_thread_list;
struct cmd_list_element *cmd_task_list;

/*ARGSUSED */
static void
thread_command (char *arg, int from_tty)
{
  printf_unfiltered ("\"thread\" must be followed by the name of a thread command.\n");
  help_list (cmd_thread_list, "thread ", -1, gdb_stdout);
}

/*ARGSUSED */
static void
task_command (char *arg, int from_tty)
{
  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 (void)
{
  /* Thread handling commands */

  /* 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", "mthread", class_stack, 1);

  add_cmd ("select", class_stack, thread_select_command,
	   "Select and print MID of the selected thread",
	   &cmd_thread_list);
  add_cmd ("list", class_stack, thread_list_command,
	   "List info of task's threads. Selected thread is marked with '*'",
	   &cmd_thread_list);
  add_cmd ("suspend", class_run, thread_suspend_command,
	   "Suspend one or all of the threads in the selected task.",
	   &cmd_thread_list);
  add_cmd ("resume", class_run, thread_resume_command,
	   "Resume one or all of the threads in the selected task.",
	   &cmd_thread_list);
  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", "mthread select", 0, 0, &cmdlist);
  add_alias_cmd ("tl", "mthread list", 0, 0, &cmdlist);

  /* task handling commands */

  add_prefix_cmd ("task", class_stack, task_command,
		  "Generic command for handling debugged task.",
		  &cmd_task_list, "task ", 0, &cmdlist);

  add_com_alias ("ta", "task", class_stack, 1);

  add_cmd ("suspend", class_run, task_suspend_command,
	   "Suspend the inferior task.",
	   &cmd_task_list);
  add_cmd ("resume", class_run, task_resume_command,
	   "Resume the inferior task.",
	   &cmd_task_list);
  add_cmd ("info", no_class, task_info_command,
	   "Print information about the specified task.",
	   &cmd_task_list);

  /* Print my message port name */

  add_info ("message-port", message_port_info,
	    "Returns the name of gdb's message port in the netnameserver");

  /* Exception commands */

  add_info ("exceptions", exception_info,
	    "What debugger does when program gets various exceptions.\n\
Specify an exception number as argument to print info on that\n\
exception only.");

  add_com ("exception", class_run, exception_command,
	   "Specify how to handle an exception.\n\
Args are exception number followed by \"forward\" or \"keep\".\n\
`Forward' means forward the exception to the program's normal exception\n\
handler.\n\
`Keep' means reenter debugger if this exception happens, and GDB maps\n\
the exception to some signal (see info exception)\n\
Normally \"keep\" is used to return to GDB on exception.");
}

kern_return_t
do_mach_notify_dead_name (mach_port_t notify, mach_port_t name)
{
  kern_return_t kr = KERN_SUCCESS;

  /* Find the thing that notified */
  port_chain_t element = port_chain_member (notify_chain, name);

  /* Take name of from unreceived dead name notification list */
  notify_chain = port_chain_delete (notify_chain, name);

  if (!element)
    error ("Received a dead name notify from unchained port (0x%x)", name);

  switch (element->type)
    {

    case MACH_TYPE_THREAD:
      target_terminal_ours_for_output ();
      if (name == current_thread)
	{
	  printf_filtered ("\nCurrent thread %d died", element->mid);
	  current_thread = MACH_PORT_NULL;
	}
      else
	printf_filtered ("\nThread %d died", element->mid);

      break;

    case MACH_TYPE_TASK:
      target_terminal_ours_for_output ();
      if (name != inferior_task)
	printf_filtered ("Task %d died, but it was not the selected task",
			 element->mid);
      else
	{
	  printf_filtered ("Current task %d died", element->mid);

	  mach_port_destroy (mach_task_self (), name);
	  inferior_task = MACH_PORT_NULL;

	  if (notify_chain)
	    warning ("There were still unreceived dead_name_notifications???");

	  /* Destroy the old notifications */
	  setup_notify_port (0);

	}
      break;

    default:
      error ("Unregistered dead_name 0x%x notification received. Type is %d, mid is 0x%x",
	     name, element->type, element->mid);
      break;
    }

  return KERN_SUCCESS;
}

kern_return_t
do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name)
{
  warning ("do_mach_notify_msg_accepted : notify %x, name %x",
	   notify, name);
  return KERN_SUCCESS;
}

kern_return_t
do_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t mscount)
{
  warning ("do_mach_notify_no_senders : notify %x, mscount %x",
	   notify, mscount);
  return KERN_SUCCESS;
}

kern_return_t
do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name)
{
  warning ("do_mach_notify_port_deleted : notify %x, name %x",
	   notify, name);
  return KERN_SUCCESS;
}

kern_return_t
do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t rights)
{
  warning ("do_mach_notify_port_destroyed : notify %x, rights %x",
	   notify, rights);
  return KERN_SUCCESS;
}

kern_return_t
do_mach_notify_send_once (mach_port_t notify)
{
#ifdef DUMP_SYSCALL
  /* MANY of these are generated. */
  warning ("do_mach_notify_send_once : notify %x",
	   notify);
#endif
  return KERN_SUCCESS;
}

/* Kills the inferior. It's gone when you call this */
static void
kill_inferior_fast (void)
{
  WAITTYPE w;

  if (PIDGET (inferior_ptid) == 0 || PIDGET (inferior_ptid) == 1)
    return;

  /* kill() it, since the Unix server does not otherwise notice when
   * killed with task_terminate().
   */
  if (PIDGET (inferior_ptid) > 0)
    kill (PIDGET (inferior_ptid), SIGKILL);

  /* It's propably terminate already */
  (void) task_terminate (inferior_task);

  inferior_task = MACH_PORT_NULL;
  current_thread = MACH_PORT_NULL;

  wait3 (&w, WNOHANG, 0);

  setup_notify_port (0);
}

static void
m3_kill_inferior (void)
{
  kill_inferior_fast ();
  target_mourn_inferior ();
}

/* Clean up after the inferior dies.  */

static void
m3_mourn_inferior (void)
{
  unpush_target (&m3_ops);
  generic_mourn_inferior ();
}


/* Fork an inferior process, and start debugging it.  */

static void
m3_create_inferior (char *exec_file, char *allargs, char **env)
{
  fork_inferior (exec_file, allargs, env, m3_trace_me, m3_trace_him, NULL, 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 (void)
{
  return 1;
}

/* Mach 3.0 does not need ptrace for anything
 * Make sure nobody uses it on mach.
 */
ptrace (int a, int b, int c, int d)
{
  error ("Lose, Lose! Somebody called ptrace\n");
}

/* Resume execution of the inferior process.
   If STEP is nonzero, single-step it.
   If SIGNAL is nonzero, give it that signal.  */

void
m3_resume (ptid_t ptid, int step, enum target_signal signal)
{
  kern_return_t ret;

  if (step)
    {
      thread_basic_info_data_t th_info;
      unsigned int infoCnt = THREAD_BASIC_INFO_COUNT;

      /* There is no point in single stepping when current_thread
       * is dead.
       */
      if (!MACH_PORT_VALID (current_thread))
	error ("No thread selected; can not single step");

      /* If current_thread is suspended, tracing it would never return.
       */
      ret = thread_info (current_thread,
			 THREAD_BASIC_INFO,
			 (thread_info_t) & th_info,
			 &infoCnt);
      CHK ("child_resume: can't get thread info", ret);

      if (th_info.suspend_count)
	error ("Can't trace a suspended thread. Use \"thread resume\" command to resume it");
    }

  vm_read_cache_valid = FALSE;

  if (signal && PIDGET (inferior_ptid) > 0)	/* Do not signal, if attached by MID */
    kill (PIDGET (inferior_ptid), target_signal_to_host (signal));

  if (step)
    {
      suspend_all_threads (0);

      setup_single_step (current_thread, TRUE);

      ret = thread_resume (current_thread);
      CHK ("thread_resume", ret);
    }

  ret = task_resume (inferior_task);
  if (ret == KERN_FAILURE)
    warning ("Task was not suspended");
  else
    CHK ("Resuming task", ret);

  /* HACK HACK This is needed by the multiserver system HACK HACK */
  while ((ret = task_resume (inferior_task)) == KERN_SUCCESS)
    /* make sure it really runs */ ;
  /* HACK HACK This is needed by the multiserver system HACK HACK */
}

#ifdef ATTACH_DETACH

/* Start debugging the process with the given task */
void
task_attach (task_t tid)
{
  kern_return_t ret;
  inferior_task = tid;

  ret = task_suspend (inferior_task);
  CHK ("task_attach: task_suspend", ret);

  must_suspend_thread = 0;

  setup_notify_port (1);

  request_notify (inferior_task, MACH_NOTIFY_DEAD_NAME, MACH_TYPE_TASK);

  setup_exception_port ();

  emulator_present = have_emulator_p (inferior_task);

  attach_flag = 1;
}

/* Well, we can call error also here and leave the
 * target stack inconsistent. Sigh.
 * Fix this sometime (the only way to fail here is that
 * the task has no threads at all, which is rare, but
 * possible; or if the target task has died, which is also
 * possible, but unlikely, since it has been suspended.
 * (Someone must have killed it))
 */
void
attach_to_thread (void)
{
  if (select_thread (inferior_task, 0, 1) != KERN_SUCCESS)
    error ("Could not select any threads to attach to");
}

mid_attach (int mid)
{
  kern_return_t ret;

  ret = machid_mach_port (mid_server, mid_auth, mid, &inferior_task);
  CHK ("mid_attach: machid_mach_port", ret);

  task_attach (inferior_task);

  return mid;
}

/* 
 * Start debugging the process whose unix process-id is PID.
 * A negative "pid" value is legal and signifies a mach_id not a unix pid.
 *
 * Prevent (possible unwanted) dangerous operations by enabled users
 * like "atta 0" or "atta foo" (equal to the previous :-) and
 * "atta pidself". Anyway, the latter is allowed by specifying a MID.
 */
static int
m3_do_attach (int pid)
{
  kern_return_t ret;

  if (pid == 0)
    error ("MID=0, Debugging the master unix server does not compute");

  /* Foo. This assumes gdb has a unix pid */
  if (pid == getpid ())
    error ("I will debug myself only by mid. (Gdb would suspend itself!)");

  if (pid < 0)
    {
      mid_attach (-(pid));

      /* inferior_ptid will be NEGATIVE! */
      inferior_ptid = pid_to_ptid (pid);

      return PIDGET (inferior_ptid);
    }

  inferior_task = task_by_pid (pid);
  if (!MACH_PORT_VALID (inferior_task))
    error ("Cannot map Unix pid %d to Mach task port", pid);

  task_attach (inferior_task);

  inferior_ptid = pid_to_ptid (pid);

  return PIDGET (inferior_ptid);
}

/* Attach to process PID, then initialize for debugging it
   and wait for the trace-trap that results from attaching.  */

static void
m3_attach (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_to_ptid (pid)));
      else
	printf_unfiltered ("Attaching to %s\n",
	                   target_pid_to_str (pid_to_ptid (pid)));

      gdb_flush (gdb_stdout);
    }

  m3_do_attach (pid_to_ptid (pid));
  inferior_ptid = pid_to_ptid (pid);
  push_target (&m3_ops);
}

void
deallocate_inferior_ports (void)
{
  kern_return_t ret;
  thread_array_t thread_list;
  int thread_count, index;

  if (!MACH_PORT_VALID (inferior_task))
    return;

  ret = task_threads (inferior_task, &thread_list, &thread_count);
  if (ret != KERN_SUCCESS)
    {
      warning ("deallocate_inferior_ports: task_threads",
	       mach_error_string (ret));
      return;
    }

  /* Get rid of send rights to task threads */
  for (index = 0; index < thread_count; index++)
    {
      int rights;
      ret = mach_port_get_refs (mach_task_self (),
				thread_list[index],
				MACH_PORT_RIGHT_SEND,
				&rights);
      CHK ("deallocate_inferior_ports: get refs", ret);

      if (rights > 0)
	{
	  ret = mach_port_mod_refs (mach_task_self (),
				    thread_list[index],
				    MACH_PORT_RIGHT_SEND,
				    -rights);
	  CHK ("deallocate_inferior_ports: mod refs", ret);
	}
    }

  ret = mach_port_mod_refs (mach_task_self (),
			    inferior_exception_port,
			    MACH_PORT_RIGHT_RECEIVE,
			    -1);
  CHK ("deallocate_inferior_ports: cannot get rid of exception port", ret);

  ret = mach_port_deallocate (mach_task_self (),
			      inferior_task);
  CHK ("deallocate_task_port: deallocating inferior_task", ret);

  current_thread = MACH_PORT_NULL;
  inferior_task = MACH_PORT_NULL;
}

/* Stop debugging the process whose number is PID
   and continue it with signal number SIGNAL.
   SIGNAL = 0 means just continue it.  */

static void
m3_do_detach (int signal)
{
  kern_return_t ret;

  MACH_ERROR_NO_INFERIOR;

  if (current_thread != MACH_PORT_NULL)
    {
      /* Store the gdb's view of the thread we are deselecting
       * before we detach.
       * @@ I am really not sure if this is ever needeed.
       */
      target_prepare_to_store ();
      target_store_registers (-1);
    }

  ret = task_set_special_port (inferior_task,
			       TASK_EXCEPTION_PORT,
			       inferior_old_exception_port);
  CHK ("task_set_special_port", ret);

  /* Discard all requested notifications */
  setup_notify_port (0);

  if (remove_breakpoints ())
    warning ("Could not remove breakpoints when detaching");

  if (signal && PIDGET (inferior_ptid) > 0)
    kill (PIDGET (inferior_ptid), signal);

  /* the task might be dead by now */
  (void) task_resume (inferior_task);

  deallocate_inferior_ports ();

  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 (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_ptid));
      gdb_flush (gdb_stdout);
    }
  if (args)
    siggnal = atoi (args);

  m3_do_detach (siggnal);
  inferior_ptid = null_ptid;
  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 (void)
{
#ifdef CHILD_PREPARE_TO_STORE
  CHILD_PREPARE_TO_STORE ();
#endif
}

/* Print status information about what we're accessing.  */

static void
m3_files_info (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_ptid));
}

static void
m3_open (char *arg, int from_tty)
{
  error ("Use the \"run\" command to start a Unix child process.");
}

#ifdef DUMP_SYSCALL
#define STR(x) #x

char *bsd1_names[] =
{
  "execve",
  "fork",
  "take_signal",
  "sigreturn",
  "getrusage",
  "chdir",
  "chroot",
  "open",
  "creat",
  "mknod",
  "link",
  "symlink",
  "unlink",
  "access",
  "stat",
  "readlink",
  "chmod",
  "chown",
  "utimes",
  "truncate",
  "rename",
  "mkdir",
  "rmdir",
  "xutimes",
  "mount",
  "umount",
  "acct",
  "setquota",
  "write_short",
  "write_long",
  "send_short",
  "send_long",
  "sendto_short",
  "sendto_long",
  "select",
  "task_by_pid",
  "recvfrom_short",
  "recvfrom_long",
  "setgroups",
  "setrlimit",
  "sigvec",
  "sigstack",
  "settimeofday",
  "adjtime",
  "setitimer",
  "sethostname",
  "bind",
  "accept",
  "connect",
  "setsockopt",
  "getsockopt",
  "getsockname",
  "getpeername",
  "init_process",
  "table_set",
  "table_get",
  "pioctl",
  "emulator_error",
  "readwrite",
  "share_wakeup",
  0,
  "maprw_request_it",
  "maprw_release_it",
  "maprw_remap",
  "pid_by_task",
};

int bsd1_nnames = sizeof (bsd1_names) / sizeof (bsd1_names[0]);

char *
name_str (int name, char *buf)
{
  switch (name)
    {
    case MACH_MSG_TYPE_BOOLEAN:
      return "boolean";
    case MACH_MSG_TYPE_INTEGER_16:
      return "short";
    case MACH_MSG_TYPE_INTEGER_32:
      return "long";
    case MACH_MSG_TYPE_CHAR:
      return "char";
    case MACH_MSG_TYPE_BYTE:
      return "byte";
    case MACH_MSG_TYPE_REAL:
      return "real";
    case MACH_MSG_TYPE_STRING:
      return "string";
    default:
      sprintf (buf, "%d", name);
      return buf;
    }
}

char *
id_str (int id, char *buf)
{
  char *p;
  if (id >= 101000 && id < 101000 + bsd1_nnames)
    {
      if (p = bsd1_names[id - 101000])
	return p;
    }
  if (id == 102000)
    return "psignal_retry";
  if (id == 100000)
    return "syscall";
  sprintf (buf, "%d", id);
  return buf;
}

print_msg (mach_msg_header_t *mp)
{
  char *fmt_x = "%20s : 0x%08x\n";
  char *fmt_d = "%20s : %10d\n";
  char *fmt_s = "%20s : %s\n";
  char buf[100];

  puts_filtered ("\n");
#define pr(fmt,h,x) printf_filtered(fmt,STR(x),(h).x)
  pr (fmt_x, (*mp), msgh_bits);
  pr (fmt_d, (*mp), msgh_size);
  pr (fmt_x, (*mp), msgh_remote_port);
  pr (fmt_x, (*mp), msgh_local_port);
  pr (fmt_d, (*mp), msgh_kind);
  printf_filtered (fmt_s, STR (msgh_id), id_str (mp->msgh_id, buf));

  if (debug_level > 1)
    {
      char *p, *ep, *dp;
      int plen;
      p = (char *) mp;
      ep = p + mp->msgh_size;
      p += sizeof (*mp);
      for (; p < ep; p += plen)
	{
	  mach_msg_type_t *tp;
	  mach_msg_type_long_t *tlp;
	  int name, size, number;
	  tp = (mach_msg_type_t *) p;
	  if (tp->msgt_longform)
	    {
	      tlp = (mach_msg_type_long_t *) tp;
	      name = tlp->msgtl_name;
	      size = tlp->msgtl_size;
	      number = tlp->msgtl_number;
	      plen = sizeof (*tlp);
	    }
	  else
	    {
	      name = tp->msgt_name;
	      size = tp->msgt_size;
	      number = tp->msgt_number;
	      plen = sizeof (*tp);
	    }
	  printf_filtered ("name=%-16s size=%2d number=%7d inline=%d long=%d deal=%d\n",
			name_str (name, buf), size, number, tp->msgt_inline,
			   tp->msgt_longform, tp->msgt_deallocate);
	  dp = p + plen;
	  if (tp->msgt_inline)
	    {
	      int l;
	      l = size * number / 8;
	      l = (l + sizeof (long) - 1) & ~((sizeof (long)) - 1);
	      plen += l;
	      print_data (dp, size, number);
	    }
	  else
	    {
	      plen += sizeof (int *);
	    }
	  printf_filtered ("plen=%d\n", plen);
	}
    }
}

print_data (char *p, int size, int number)
{
  int *ip;
  short *sp;
  int i;

  switch (size)
    {
    case 8:
      for (i = 0; i < number; i++)
	{
	  printf_filtered (" %02x", p[i]);
	}
      break;
    case 16:
      sp = (short *) p;
      for (i = 0; i < number; i++)
	{
	  printf_filtered (" %04x", sp[i]);
	}
      break;
    case 32:
      ip = (int *) p;
      for (i = 0; i < number; i++)
	{
	  printf_filtered (" %08x", ip[i]);
	}
      break;
    }
  puts_filtered ("\n");
}
#endif /* DUMP_SYSCALL */

static void
m3_stop (void)
{
  error ("to_stop target function not implemented");
}

static char *
m3_pid_to_exec_file (int pid)
{
  error ("to_pid_to_exec_file target function not implemented");
  return NULL;			/* To keep all compilers happy. */
}

static void
init_m3_ops (void)
{
  m3_ops.to_shortname = "mach";
  m3_ops.to_longname = "Mach child process";
  m3_ops.to_doc = "Mach child process (started by the \"run\" command).";
  m3_ops.to_open = m3_open;
  m3_ops.to_attach = m3_attach;
  m3_ops.to_detach = m3_detach;
  m3_ops.to_resume = m3_resume;
  m3_ops.to_wait = mach_really_wait;
  m3_ops.to_fetch_registers = fetch_inferior_registers;
  m3_ops.to_store_registers = store_inferior_registers;
  m3_ops.to_prepare_to_store = m3_prepare_to_store;
  m3_ops.to_xfer_memory = m3_xfer_memory;
  m3_ops.to_files_info = m3_files_info;
  m3_ops.to_insert_breakpoint = memory_insert_breakpoint;
  m3_ops.to_remove_breakpoint = memory_remove_breakpoint;
  m3_ops.to_terminal_init = terminal_init_inferior;
  m3_ops.to_terminal_inferior = terminal_inferior;
  m3_ops.to_terminal_ours_for_output = terminal_ours_for_output;
  m3_ops.to_terminal_save_ours = terminal_save_ours;
  m3_ops.to_terminal_ours = terminal_ours;
  m3_ops.to_terminal_info = child_terminal_info;
  m3_ops.to_kill = m3_kill_inferior;
  m3_ops.to_create_inferior = m3_create_inferior;
  m3_ops.to_mourn_inferior = m3_mourn_inferior;
  m3_ops.to_can_run = m3_can_run;
  m3_ops.to_stop = m3_stop;
  m3_ops.to_pid_to_exec_file = m3_pid_to_exec_file;
  m3_ops.to_stratum = process_stratum;
  m3_ops.to_has_all_memory = 1;
  m3_ops.to_has_memory = 1;
  m3_ops.to_has_stack = 1;
  m3_ops.to_has_registers = 1;
  m3_ops.to_has_execution = 1;
  m3_ops.to_magic = OPS_MAGIC;
}

void
_initialize_m3_nat (void)
{
  kern_return_t ret;

  init_m3_ops ();
  add_target (&m3_ops);

  ret = mach_port_allocate (mach_task_self (),
			    MACH_PORT_RIGHT_PORT_SET,
			    &inferior_wait_port_set);
  if (ret != KERN_SUCCESS)
    internal_error (__FILE__, __LINE__,
		    "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 ();
}
