/* Darwin support for GDB, the GNU debugger.
   Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.

   Contributed by AdaCore.

   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 3 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, see <http://www.gnu.org/licenses/>.
*/

#include "defs.h"
#include "top.h"
#include "inferior.h"
#include "target.h"
#include "symfile.h"
#include "symtab.h"
#include "objfiles.h"
#include "gdb.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "gdbthread.h"
#include "regcache.h"
#include "event-top.h"
#include "inf-loop.h"
#include "gdb_stat.h"
#include "exceptions.h"
#include "inf-child.h"
#include "value.h"
#include "arch-utils.h"
#include "bfd.h"

#include <sys/ptrace.h>
#include <sys/signal.h>
#include <machine/setjmp.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <ctype.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
#include <libproc.h>
#include <sys/syscall.h>
#include <spawn.h>

#include <mach/mach_error.h>
#include <mach/mach_vm.h>
#include <mach/mach_init.h>
#include <mach/vm_map.h>
#include <mach/task.h>
#include <mach/mach_port.h>
#include <mach/thread_act.h>
#include <mach/port.h>

#include "darwin-nat.h"

/* Quick overview.
   Darwin kernel is Mach + BSD derived kernel.  Note that they share the
   same memory space and are linked together (ie there is no micro-kernel).

   Although ptrace(2) is available on Darwin, it is not complete.  We have
   to use Mach calls to read and write memory and to modify registers.  We
   also use Mach to get inferior faults.  As we cannot use select(2) or
   signals with Mach port (the Mach communication channel), signals are
   reported to gdb as an exception.  Furthermore we detect death of the
   inferior through a Mach notification message.  This way we only wait
   on Mach ports.

   Some Mach documentation is available for Apple xnu source package or
   from the web.  */


#define PTRACE(CMD, PID, ADDR, SIG) \
 darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG))

extern boolean_t exc_server (mach_msg_header_t *in, mach_msg_header_t *out);

static void darwin_stop (ptid_t);

static void darwin_resume_to (struct target_ops *ops, ptid_t ptid, int step,
                              enum target_signal signal);
static void darwin_resume (ptid_t ptid, int step,
			   enum target_signal signal);

static ptid_t darwin_wait_to (struct target_ops *ops, ptid_t ptid,
                              struct target_waitstatus *status, int options);
static ptid_t darwin_wait (ptid_t ptid, struct target_waitstatus *status);

static void darwin_mourn_inferior (struct target_ops *ops);

static void darwin_kill_inferior (struct target_ops *ops);

static void darwin_ptrace_me (void);

static void darwin_ptrace_him (int pid);

static void darwin_create_inferior (struct target_ops *ops, char *exec_file,
				    char *allargs, char **env, int from_tty);

static void darwin_files_info (struct target_ops *ops);

static char *darwin_pid_to_str (struct target_ops *ops, ptid_t tpid);

static int darwin_thread_alive (struct target_ops *ops, ptid_t tpid);

/* Target operations for Darwin.  */
static struct target_ops *darwin_ops;

/* Task identifier of gdb.  */
static task_t gdb_task;

/* A copy of mach_host_self ().  */
mach_port_t darwin_host_self;

/* Exception port.  */
mach_port_t darwin_ex_port;

/* Port set.  */
mach_port_t darwin_port_set;

/* Page size.  */
static vm_size_t mach_page_size;

/* If Set, catch all mach exceptions (before they are converted to signals
   by the kernel).  */
static int enable_mach_exceptions;

/* Inferior that should report a fake stop event.  */
static struct inferior *darwin_inf_fake_stop;

#define PAGE_TRUNC(x) ((x) & ~(mach_page_size - 1))
#define PAGE_ROUND(x) PAGE_TRUNC((x) + mach_page_size - 1)

/* This controls output of inferior debugging.  */
static int darwin_debug_flag = 0;

/* Create a __TEXT __info_plist section in the executable so that gdb could
   be signed.  This is required to get an authorization for task_for_pid.

   Once gdb is built, you can either:
   * make it setgid procmod
   * or codesign it with any system-trusted signing authority.
   See taskgated(8) for details.  */
static const unsigned char info_plist[]
__attribute__ ((section ("__TEXT,__info_plist"),used)) =
  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
  " \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
  "<plist version=\"1.0\">\n"
  "<dict>\n"
  "  <key>CFBundleIdentifier</key>\n"
  "  <string>org.gnu.gdb</string>\n"
  "  <key>CFBundleName</key>\n"
  "  <string>gdb</string>\n"
  "  <key>CFBundleVersion</key>\n"
  "  <string>1.0</string>\n"
  "  <key>SecTaskAccess</key>\n"
  "  <array>\n"
  "    <string>allowed</string>\n"
  "    <string>debug</string>\n"
  "  </array>\n"
  "</dict>\n"
  "</plist>\n";

static void
inferior_debug (int level, const char *fmt, ...)
{
  va_list ap;

  if (darwin_debug_flag < level)
    return;

  va_start (ap, fmt);
  printf_unfiltered (_("[%d inferior]: "), getpid ());
  vprintf_unfiltered (fmt, ap);
  va_end (ap);
}

void
mach_check_error (kern_return_t ret, const char *file,
                  unsigned int line, const char *func)
{
  if (ret == KERN_SUCCESS)
    return;
  if (func == NULL)
    func = _("[UNKNOWN]");

  warning (_("Mach error at \"%s:%u\" in function \"%s\": %s (0x%lx)"),
	   file, line, func, mach_error_string (ret), (unsigned long) ret);
}

static const char *
unparse_exception_type (unsigned int i)
{
  static char unknown_exception_buf[32];

  switch (i)
    {
    case EXC_BAD_ACCESS:
      return "EXC_BAD_ACCESS";
    case EXC_BAD_INSTRUCTION:
      return "EXC_BAD_INSTRUCTION";
    case EXC_ARITHMETIC:
      return "EXC_ARITHMETIC";
    case EXC_EMULATION:
      return "EXC_EMULATION";
    case EXC_SOFTWARE:
      return "EXC_SOFTWARE";
    case EXC_BREAKPOINT:
      return "EXC_BREAKPOINT";
    case EXC_SYSCALL:
      return "EXC_SYSCALL";
    case EXC_MACH_SYSCALL:
      return "EXC_MACH_SYSCALL";
    case EXC_RPC_ALERT:
      return "EXC_RPC_ALERT";
    case EXC_CRASH:
      return "EXC_CRASH";
    default:
      snprintf (unknown_exception_buf, 32, _("unknown (%d)"), i);
      return unknown_exception_buf;
    }
}

/* Set errno to zero, and then call ptrace with the given arguments.
   If inferior debugging traces are on, then also print a debug
   trace.

   The returned value is the same as the value returned by ptrace,
   except in the case where that value is -1 but errno is zero.
   This case is documented to be a non-error situation, so we
   return zero in that case. */

static int
darwin_ptrace (const char *name,
	       int request, int pid, PTRACE_TYPE_ARG3 arg3, int arg4)
{
  int ret;

  errno = 0;
  ret = ptrace (request, pid, (caddr_t) arg3, arg4);
  if (ret == -1 && errno == 0)
    ret = 0;

  inferior_debug (4, _("ptrace (%s, %d, 0x%x, %d): %d (%s)\n"),
                  name, pid, arg3, arg4, ret,
                  (ret != 0) ? safe_strerror (errno) : _("no error"));
  return ret;
}

static int
cmp_thread_t (const void *l, const void *r)
{
  thread_t tl = *(const thread_t *)l;
  thread_t tr = *(const thread_t *)r;
  return (int)(tl - tr);
}

static void
darwin_check_new_threads (struct inferior *inf)
{
  kern_return_t kret;
  unsigned int i;
  thread_array_t thread_list;
  unsigned int new_nbr;
  unsigned int old_nbr;
  unsigned int new_ix, old_ix;
  darwin_inferior *darwin_inf = inf->private;
  VEC (darwin_thread_t) *thread_vec;

  /* Get list of threads.  */
  kret = task_threads (darwin_inf->task, &thread_list, &new_nbr);
  MACH_CHECK_ERROR (kret);
  if (kret != KERN_SUCCESS)
    return;

  /* Sort the list.  */
  if (new_nbr > 1)
    qsort (thread_list, new_nbr, sizeof (thread_t), cmp_thread_t);

  if (darwin_inf->threads)
    old_nbr = VEC_length (darwin_thread_t, darwin_inf->threads);
  else
    old_nbr = 0;

  /* Quick check for no changes.  */
  if (old_nbr == new_nbr)
    {
      for (i = 0; i < new_nbr; i++)
	if (thread_list[i]
	    != VEC_index (darwin_thread_t, darwin_inf->threads, i)->gdb_port)
	  break;
      if (i == new_nbr)
	{
	  kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
				new_nbr * sizeof (int));
	  MACH_CHECK_ERROR (kret);
	  return;
	}
    }

  thread_vec = VEC_alloc (darwin_thread_t, new_nbr);

  for (new_ix = 0, old_ix = 0; new_ix < new_nbr || old_ix < old_nbr;)
    {
      thread_t new_id = (new_ix < new_nbr) ?
	thread_list[new_ix] : THREAD_NULL;
      darwin_thread_t *old = (old_ix < old_nbr) ?
	VEC_index (darwin_thread_t, darwin_inf->threads, old_ix) : NULL;
      thread_t old_id = old ? old->gdb_port : THREAD_NULL;

      inferior_debug
	(12, _(" new_ix:%d/%d, old_ix:%d/%d, new_id:%x old_id:%x\n"),
	 new_ix, new_nbr, old_ix, old_nbr, new_id, old_id);

      if (old_id == new_id)
	{
	  /* Thread still exist.  */
	  VEC_safe_push (darwin_thread_t, thread_vec, old);
	  new_ix++;
	  old_ix++;

	  kret = mach_port_deallocate (gdb_task, old_id);
	  MACH_CHECK_ERROR (kret);
	  continue;
	}
      if (new_ix < new_nbr && new_id == MACH_PORT_DEAD)
	{
	  /* Ignore dead ports.
	     In some weird cases, we might get dead ports.  They should
	     correspond to dead thread so they could safely be ignored.  */
	  new_ix++;
	  continue;
	}
      if (new_ix < new_nbr && (old_ix == old_nbr || new_id < old_id))
	{
	  /* A thread was created.  */
	  struct thread_info *tp;
	  struct private_thread_info *pti;

	  pti = XZALLOC (struct private_thread_info);
	  pti->gdb_port = new_id;
	  pti->msg_state = DARWIN_RUNNING;

	  /* Add a new thread unless this is the first one ever met.  */
	  if (!(old_nbr == 0 && new_ix == 0))
	    tp = add_thread_with_info (ptid_build (inf->pid, 0, new_id), pti);
	  else
	    {
	      tp = find_thread_ptid (ptid_build (inf->pid, 0, 0));
	      gdb_assert (tp);
	      tp->private = pti;
	    }
	  VEC_safe_push (darwin_thread_t, thread_vec, pti);
	  new_ix++;
	  continue;
	}
      if (old_ix < old_nbr && (new_ix == new_nbr || new_id > old_id))
	{
	  /* A thread was removed.  */
	  delete_thread (ptid_build (inf->pid, 0, old_id));
	  kret = mach_port_deallocate (gdb_task, old_id);
	  MACH_CHECK_ERROR (kret);
	  old_ix++;
	  continue;
	}
      gdb_assert_not_reached ("unexpected thread case");
    }

  if (darwin_inf->threads)
    VEC_free (darwin_thread_t, darwin_inf->threads);
  darwin_inf->threads = thread_vec;

  kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
			new_nbr * sizeof (int));
  MACH_CHECK_ERROR (kret);
}

static int
find_inferior_task_it (struct inferior *inf, void *port_ptr)
{
  return inf->private->task == *(task_t*)port_ptr;
}

static int
find_inferior_notify_it (struct inferior *inf, void *port_ptr)
{
  return inf->private->notify_port == *(task_t*)port_ptr;
}

/* Return an inferior by task port.  */
static struct inferior *
darwin_find_inferior_by_task (task_t port)
{
  return iterate_over_inferiors (&find_inferior_task_it, &port);
}

/* Return an inferior by notification port.  */
static struct inferior *
darwin_find_inferior_by_notify (mach_port_t port)
{
  return iterate_over_inferiors (&find_inferior_notify_it, &port);
}

/* Return a thread by port.  */
static darwin_thread_t *
darwin_find_thread (struct inferior *inf, thread_t thread)
{
  darwin_thread_t *t;
  int k;

  for (k = 0;
       VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
       k++)
    if (t->gdb_port == thread)
      return t;
  return NULL;
}

/* Suspend (ie stop) an inferior at Mach level.  */

static void
darwin_suspend_inferior (struct inferior *inf)
{
  if (!inf->private->suspended)
    {
      kern_return_t kret;

      kret = task_suspend (inf->private->task);
      MACH_CHECK_ERROR (kret);

      inf->private->suspended = 1;
    }
}

/* Resume an inferior at Mach level.  */

static void
darwin_resume_inferior (struct inferior *inf)
{
  if (inf->private->suspended)
    {
      kern_return_t kret;

      kret = task_resume (inf->private->task);
      MACH_CHECK_ERROR (kret);

      inf->private->suspended = 0;
    }
}

/* Iterator functions.  */

static int
darwin_suspend_inferior_it (struct inferior *inf, void *arg)
{
  darwin_suspend_inferior (inf);
  darwin_check_new_threads (inf);
  return 0;
}

static int
darwin_resume_inferior_it (struct inferior *inf, void *arg)
{
  darwin_resume_inferior (inf);
  return 0;
}

static void
darwin_dump_message (mach_msg_header_t *hdr, int disp_body)
{
  printf_unfiltered (_("message header:\n"));
  printf_unfiltered (_(" bits: 0x%x\n"), hdr->msgh_bits);
  printf_unfiltered (_(" size: 0x%x\n"), hdr->msgh_size);
  printf_unfiltered (_(" remote-port: 0x%x\n"), hdr->msgh_remote_port);
  printf_unfiltered (_(" local-port: 0x%x\n"), hdr->msgh_local_port);
  printf_unfiltered (_(" reserved: 0x%x\n"), hdr->msgh_reserved);
  printf_unfiltered (_(" id: 0x%x\n"), hdr->msgh_id);

  if (disp_body)
    {
      const unsigned char *data;
      const unsigned long *ldata;
      int size;
      int i;

      data = (unsigned char *)(hdr + 1);
      size = hdr->msgh_size - sizeof (mach_msg_header_t);

      if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
	{
	  mach_msg_body_t *bod = (mach_msg_body_t*)data;
	  mach_msg_port_descriptor_t *desc =
	    (mach_msg_port_descriptor_t *)(bod + 1);
	  int k;
	  NDR_record_t *ndr;
	  printf_unfiltered (_("body: descriptor_count=%u\n"),
			     bod->msgh_descriptor_count);
	  data += sizeof (mach_msg_body_t);
	  size -= sizeof (mach_msg_body_t);
	  for (k = 0; k < bod->msgh_descriptor_count; k++)
	    switch (desc[k].type)
	      {
	      case MACH_MSG_PORT_DESCRIPTOR:
		printf_unfiltered
		  (_(" descr %d: type=%u (port) name=0x%x, dispo=%d\n"),
		   k, desc[k].type, desc[k].name, desc[k].disposition);
		break;
	      default:
		printf_unfiltered (_(" descr %d: type=%u\n"),
				   k, desc[k].type);
		break;
	      }
	  data += bod->msgh_descriptor_count
	    * sizeof (mach_msg_port_descriptor_t);
	  size -= bod->msgh_descriptor_count
	    * sizeof (mach_msg_port_descriptor_t);
	  ndr = (NDR_record_t *)(desc + bod->msgh_descriptor_count);
	  printf_unfiltered
	    (_("NDR: mig=%02x if=%02x encod=%02x "
	       "int=%02x char=%02x float=%02x\n"),
	     ndr->mig_vers, ndr->if_vers, ndr->mig_encoding,
	     ndr->int_rep, ndr->char_rep, ndr->float_rep);
	  data += sizeof (NDR_record_t);
	  size -= sizeof (NDR_record_t);
	}

      printf_unfiltered (_("  data:"));
      ldata = (const unsigned long *)data;
      for (i = 0; i < size / sizeof (unsigned long); i++)
	printf_unfiltered (" %08lx", ldata[i]);
      printf_unfiltered (_("\n"));
    }
}

static int
darwin_decode_exception_message (mach_msg_header_t *hdr,
				 struct inferior **pinf,
				 darwin_thread_t **pthread)
{
  mach_msg_body_t *bod = (mach_msg_body_t*)(hdr + 1);
  mach_msg_port_descriptor_t *desc = (mach_msg_port_descriptor_t *)(bod + 1);
  NDR_record_t *ndr;
  integer_t *data;
  struct inferior *inf;
  darwin_thread_t *thread;
  task_t task_port;
  thread_t thread_port;
  kern_return_t kret;
  int i;

  /* Check message identifier.  2401 is exc.  */
  if (hdr->msgh_id != 2401)
    return -1;

  /* Check message header.  */
  if (!(hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX))
    return -1;

  /* Check descriptors.  */
  if (hdr->msgh_size < (sizeof (*hdr) + sizeof (*bod) + 2 * sizeof (*desc)
			+ sizeof (*ndr) + 2 * sizeof (integer_t))
      || bod->msgh_descriptor_count != 2
      || desc[0].type != MACH_MSG_PORT_DESCRIPTOR
      || desc[0].disposition != MACH_MSG_TYPE_MOVE_SEND
      || desc[1].type != MACH_MSG_PORT_DESCRIPTOR
      || desc[1].disposition != MACH_MSG_TYPE_MOVE_SEND)
    return -1;

  /* Check data representation.  */
  ndr = (NDR_record_t *)(desc + 2);
  if (ndr->mig_vers != NDR_PROTOCOL_2_0
      || ndr->if_vers != NDR_PROTOCOL_2_0
      || ndr->mig_encoding != NDR_record.mig_encoding
      || ndr->int_rep != NDR_record.int_rep
      || ndr->char_rep != NDR_record.char_rep
      || ndr->float_rep != NDR_record.float_rep)
    return -1;

  /* Ok, the hard work.  */
  data = (integer_t *)(ndr + 1);

  /* Find process by port.  */
  task_port = desc[1].name;
  thread_port = desc[0].name;
  inf = darwin_find_inferior_by_task (task_port);
  if (inf == NULL)
    return -1;
  *pinf = inf;

  /* Find thread by port.  */
  /* Check for new threads.  Do it early so that the port in the exception
     message can be deallocated.  */
  darwin_check_new_threads (inf);

  /* We got new rights to the task and the thread.  Get rid of them.  */
  kret = mach_port_deallocate (mach_task_self (), task_port);
  MACH_CHECK_ERROR (kret);
  kret = mach_port_deallocate (mach_task_self (), thread_port);
  MACH_CHECK_ERROR (kret);

  thread = darwin_find_thread (inf, thread_port);
  if (thread == NULL)
    return -1;
  *pthread = thread;

  /* The thread should be running.  However we have observed cases where a thread
     got a SIGTTIN message after being stopped.  */
  gdb_assert (thread->msg_state != DARWIN_MESSAGE);

  /* Finish decoding.  */
  thread->event.header = *hdr;
  thread->event.thread_port = thread_port;
  thread->event.task_port = task_port;
  thread->event.ex_type = data[0];
  thread->event.data_count = data[1];

  if (hdr->msgh_size < (sizeof (*hdr) + sizeof (*bod) + 2 * sizeof (*desc)
			+ sizeof (*ndr) + 2 * sizeof (integer_t)
			+ data[1] * sizeof (integer_t)))
      return -1;
  for (i = 0; i < data[1]; i++)
    thread->event.ex_data[i] = data[2 + i];

  thread->msg_state = DARWIN_MESSAGE;

  return 0;
}

static void
darwin_encode_reply (mig_reply_error_t *reply, mach_msg_header_t *hdr,
		     integer_t code)
{
  mach_msg_header_t *rh = &reply->Head;
  rh->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(hdr->msgh_bits), 0);
  rh->msgh_remote_port = hdr->msgh_remote_port;
  rh->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t);
  rh->msgh_local_port = MACH_PORT_NULL;
  rh->msgh_id = hdr->msgh_id + 100;

  reply->NDR = NDR_record;
  reply->RetCode = code;
}

static void
darwin_send_reply (struct inferior *inf, darwin_thread_t *thread)
{
  kern_return_t kret;
  mig_reply_error_t reply;

  darwin_encode_reply (&reply, &thread->event.header, KERN_SUCCESS);

  kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
		   reply.Head.msgh_size, 0,
		   MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
		   MACH_PORT_NULL);
  MACH_CHECK_ERROR (kret);

  inf->private->pending_messages--;
}

static void
darwin_resume_thread (struct inferior *inf, darwin_thread_t *thread,
		      int step, int nsignal)
{
  kern_return_t kret;
  int res;

  inferior_debug
    (3, _("darwin_resume_thread: state=%d, thread=0x%x, step=%d nsignal=%d\n"),
     thread->msg_state, thread->gdb_port, step, nsignal);

  switch (thread->msg_state)
    {
    case DARWIN_MESSAGE:
      if (thread->event.ex_type == EXC_SOFTWARE
	  && thread->event.ex_data[0] == EXC_SOFT_SIGNAL)
	{
	  /* Either deliver a new signal or cancel the signal received.  */
	  res = PTRACE (PT_THUPDATE, inf->pid,
			(void *)(uintptr_t)thread->gdb_port, nsignal);
	  if (res < 0)
	    inferior_debug (1, _("ptrace THUP: res=%d\n"), res);
	}
      else if (nsignal)
	{
	  /* Note: ptrace is allowed only if the process is stopped.
	     Directly send the signal to the thread.  */
	  res = syscall (SYS___pthread_kill, thread->gdb_port, nsignal);
	  inferior_debug (4, _("darwin_resume_thread: kill 0x%x %d: %d\n"),
			  thread->gdb_port, nsignal, res);
	  thread->signaled = 1;
	}

      /* Set single step.  */
      inferior_debug (4, _("darwin_set_sstep (thread=%x, enable=%d)\n"),
                      thread->gdb_port, step);
      darwin_set_sstep (thread->gdb_port, step);
      thread->single_step = step;

      darwin_send_reply (inf, thread);
      thread->msg_state = DARWIN_RUNNING;
      break;

    case DARWIN_RUNNING:
      break;

    case DARWIN_STOPPED:
      kret = thread_resume (thread->gdb_port);
      MACH_CHECK_ERROR (kret);

      thread->msg_state = DARWIN_RUNNING;
      break;
    }
}

/* Resume all threads of the inferior.  */

static void
darwin_resume_inferior_threads (struct inferior *inf, int step, int nsignal)
{
  darwin_thread_t *thread;
  int k;

  for (k = 0;
       VEC_iterate (darwin_thread_t, inf->private->threads, k, thread);
       k++)
    darwin_resume_thread (inf, thread, step, nsignal);
}

struct resume_inferior_threads_param
{
  int step;
  int nsignal;
};

static int
darwin_resume_inferior_threads_it (struct inferior *inf, void *param)
{
  int step = ((struct resume_inferior_threads_param *)param)->step;
  int nsignal = ((struct resume_inferior_threads_param *)param)->nsignal;

  darwin_resume_inferior_threads (inf, step, nsignal);

  return 0;
}

/* Suspend all threads of INF.  */

static void
darwin_suspend_inferior_threads (struct inferior *inf)
{
  darwin_thread_t *thread;
  kern_return_t kret;
  int k;

  for (k = 0;
       VEC_iterate (darwin_thread_t, inf->private->threads, k, thread);
       k++)
    switch (thread->msg_state)
      {
      case DARWIN_STOPPED:
      case DARWIN_MESSAGE:
	break;
      case DARWIN_RUNNING:
	kret = thread_suspend (thread->gdb_port);
	MACH_CHECK_ERROR (kret);
	thread->msg_state = DARWIN_STOPPED;
	break;
      }
}

static void
darwin_resume (ptid_t ptid, int step, enum target_signal signal)
{
  struct target_waitstatus status;
  int pid;

  kern_return_t kret;
  int res;
  int nsignal;
  struct inferior *inf;

  inferior_debug
    (2, _("darwin_resume: pid=%d, tid=0x%x, step=%d, signal=%d\n"),
     ptid_get_pid (ptid), ptid_get_tid (ptid), step, signal);

  if (signal == TARGET_SIGNAL_0)
    nsignal = 0;
  else
    nsignal = target_signal_to_host (signal);

  /* Don't try to single step all threads.  */
  if (step)
    ptid = inferior_ptid;

  /* minus_one_ptid is RESUME_ALL.  */
  if (ptid_equal (ptid, minus_one_ptid))
    {
      struct resume_inferior_threads_param param;

      param.nsignal = nsignal;
      param.step = step;

      /* Resume threads.  */
      iterate_over_inferiors (darwin_resume_inferior_threads_it, &param);
      /* Resume tasks.  */
      iterate_over_inferiors (darwin_resume_inferior_it, NULL);
    }
  else
    {
      struct inferior *inf = find_inferior_pid (ptid_get_pid (ptid));
      long tid = ptid_get_tid (ptid);

      /* Stop the inferior (should be useless).  */
      darwin_suspend_inferior (inf);

      if (tid == 0)
        darwin_resume_inferior_threads (inf, step, nsignal);
      else
        {
          darwin_thread_t *thread;

          /* Suspend threads of the task.  */
          darwin_suspend_inferior_threads (inf);

          /* Resume the selected thread.  */
          thread = darwin_find_thread (inf, tid);
          gdb_assert (thread);
          darwin_resume_thread (inf, thread, step, nsignal);
        }

      /* Resume the task.  */
      darwin_resume_inferior (inf);
    }
}

static void
darwin_resume_to (struct target_ops *ops, ptid_t ptid, int step,
                  enum target_signal signal)
{
  return darwin_resume (ptid, step, signal);
}

static ptid_t
darwin_decode_message (mach_msg_header_t *hdr,
		       darwin_thread_t **pthread,
		       struct inferior **pinf,
		       struct target_waitstatus *status)
{
  darwin_thread_t *thread;
  struct inferior *inf;

  /* Exception message.  */
  if (hdr->msgh_local_port == darwin_ex_port)
    {
      int res;

      /* Decode message.  */
      res = darwin_decode_exception_message (hdr, &inf, &thread);

      if (res < 0)
	{
	  /* Should not happen...  */
	  printf_unfiltered (_("darwin_wait: ill-formatted message (id=%x)\n"),
			     hdr->msgh_id);
	  /* FIXME: send a failure reply?  */
	  status->kind = TARGET_WAITKIND_SPURIOUS;
	  return minus_one_ptid;
	}
      *pinf = inf;
      *pthread = thread;
      inf->private->pending_messages++;

      status->kind = TARGET_WAITKIND_STOPPED;
      thread->msg_state = DARWIN_MESSAGE;

      inferior_debug (4, _("darwin_wait: thread=%x, got %s\n"),
		      thread->gdb_port,
		      unparse_exception_type (thread->event.ex_type));

      switch (thread->event.ex_type)
	{
	case EXC_BAD_ACCESS:
	  status->value.sig = TARGET_EXC_BAD_ACCESS;
	  break;
	case EXC_BAD_INSTRUCTION:
	  status->value.sig = TARGET_EXC_BAD_INSTRUCTION;
	  break;
	case EXC_ARITHMETIC:
	  status->value.sig = TARGET_EXC_ARITHMETIC;
	  break;
	case EXC_EMULATION:
	  status->value.sig = TARGET_EXC_EMULATION;
	  break;
	case EXC_SOFTWARE:
	  if (thread->event.ex_data[0] == EXC_SOFT_SIGNAL)
	    {
	      status->value.sig =
		target_signal_from_host (thread->event.ex_data[1]);
	      inferior_debug (5, _("  (signal %d: %s)\n"),
			      thread->event.ex_data[1],
			      target_signal_to_name (status->value.sig));

	      /* If the thread is stopped because it has received a signal
		 that gdb has just sent, continue.  */
	      if (thread->signaled)
		{
		  thread->signaled = 0;
		  darwin_send_reply (inf, thread);
		  thread->msg_state = DARWIN_RUNNING;
		  status->kind = TARGET_WAITKIND_IGNORE;
		}
	    }
	  else
	    status->value.sig = TARGET_EXC_SOFTWARE;
	  break;
	case EXC_BREAKPOINT:
	  /* Many internal GDB routines expect breakpoints to be reported
	     as TARGET_SIGNAL_TRAP, and will report TARGET_EXC_BREAKPOINT
	     as a spurious signal.  */
	  status->value.sig = TARGET_SIGNAL_TRAP;
	  break;
	default:
	  status->value.sig = TARGET_SIGNAL_UNKNOWN;
	  break;
	}

      return ptid_build (inf->pid, 0, thread->gdb_port);
    }

  *pinf = NULL;
  *pthread = NULL;

  inf = darwin_find_inferior_by_notify (hdr->msgh_local_port);
  if (inf != NULL)
    {
      if (!inf->private->no_ptrace)
	{
	  pid_t res;
	  int wstatus;

	  res = wait4 (inf->pid, &wstatus, 0, NULL);
	  if (res < 0 || res != inf->pid)
	    {
	      printf_unfiltered (_("wait4: res=%d: %s\n"),
				 res, safe_strerror (errno));
	      status->kind = TARGET_WAITKIND_SPURIOUS;
	      return minus_one_ptid;
	    }
	  if (WIFEXITED (wstatus))
	    {
	      status->kind = TARGET_WAITKIND_EXITED;
	      status->value.integer = WEXITSTATUS (wstatus);
	    }
	  else
	    {
	      status->kind = TARGET_WAITKIND_SIGNALLED;
	      status->value.sig = WTERMSIG (wstatus);
	    }

	  inferior_debug (4, _("darwin_wait: pid=%d exit, status=%x\n"),
			  res, wstatus);

	  /* Looks necessary on Leopard and harmless...  */
	  wait4 (inf->pid, &wstatus, 0, NULL);

	  return ptid_build (inf->pid, 0, 0);
	}
      else
	{
	  inferior_debug (4, _("darwin_wait: pid=%d\n"), inf->pid);
	  status->kind = TARGET_WAITKIND_EXITED;
	  status->value.integer = 0; /* Don't know.  */
	  return ptid_build (inf->pid, 0, 0);
	}
    }

  printf_unfiltered (_("Bad local-port: %x\n"), hdr->msgh_local_port);
  status->kind = TARGET_WAITKIND_SPURIOUS;
  return minus_one_ptid;
}

static int
cancel_breakpoint (ptid_t ptid)
{
  /* Arrange for a breakpoint to be hit again later.  We will handle
     the current event, eventually we will resume this thread, and this
     breakpoint will trap again.

     If we do not do this, then we run the risk that the user will
     delete or disable the breakpoint, but the thread will have already
     tripped on it.  */

  struct regcache *regcache = get_thread_regcache (ptid);
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  CORE_ADDR pc;

  pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch);
  if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
    {
      inferior_debug (4, "cancel_breakpoint for thread %x\n",
		      ptid_get_tid (ptid));

      /* Back up the PC if necessary.  */
      if (gdbarch_decr_pc_after_break (gdbarch))
	regcache_write_pc (regcache, pc);

      return 1;
    }
  return 0;
}

static ptid_t
darwin_wait (ptid_t ptid, struct target_waitstatus *status)
{
  kern_return_t kret;
  union
  {
    mach_msg_header_t hdr;
    char data[0x100];
  } msgin;
  mach_msg_header_t *hdr = &msgin.hdr;
  ptid_t res;
  darwin_thread_t *thread;
  struct inferior *inf;

  inferior_debug
    (2, _("darwin_wait: waiting for a message pid=%d thread=%lx\n"),
     ptid_get_pid (ptid), ptid_get_tid (ptid));

  /* Handle fake stop events at first.  */
  if (darwin_inf_fake_stop != NULL)
    {
      inf = darwin_inf_fake_stop;
      darwin_inf_fake_stop = NULL;

      status->kind = TARGET_WAITKIND_STOPPED;
      status->value.sig = TARGET_SIGNAL_TRAP;
      thread = VEC_index (darwin_thread_t, inf->private->threads, 0);
      thread->msg_state = DARWIN_STOPPED;
      return ptid_build (inf->pid, 0, thread->gdb_port);
    }

  do
    {
      /* set_sigint_trap (); */

      /* Wait for a message.  */
      kret = mach_msg (&msgin.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0,
		       sizeof (msgin.data), darwin_port_set, 0, MACH_PORT_NULL);

      /* clear_sigint_trap (); */

      if (kret == MACH_RCV_INTERRUPTED)
	{
	  status->kind = TARGET_WAITKIND_IGNORE;
	  return minus_one_ptid;
	}

      if (kret != MACH_MSG_SUCCESS)
	{
	  inferior_debug (5, _("mach_msg: ret=%x\n"), kret);
	  status->kind = TARGET_WAITKIND_SPURIOUS;
	  return minus_one_ptid;
	}

      /* Debug: display message.  */
      if (darwin_debug_flag > 10)
	darwin_dump_message (hdr, darwin_debug_flag > 11);

      res = darwin_decode_message (hdr, &thread, &inf, status);

      if (inf == NULL)
	return res;
    }
  while (status->kind == TARGET_WAITKIND_IGNORE);

  /* Stop all tasks.  */
  iterate_over_inferiors (darwin_suspend_inferior_it, NULL);

  /* Read pending messages.  */
  while (1)
    {
      struct target_waitstatus status2;
      ptid_t ptid2;

      kret = mach_msg (&msgin.hdr,
		       MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
		       sizeof (msgin.data), darwin_port_set, 1, MACH_PORT_NULL);

      if (kret == MACH_RCV_TIMED_OUT)
	break;
      if (kret != MACH_MSG_SUCCESS)
	{
	  inferior_debug
	    (5, _("darwin_wait: mach_msg(pending) ret=%x\n"), kret);
	  break;
	}

      ptid2 = darwin_decode_message (hdr, &thread, &inf, &status2);

      if (inf != NULL && thread != NULL
	  && thread->event.ex_type == EXC_BREAKPOINT)
	{
	  if (thread->single_step
	      || cancel_breakpoint (ptid_build (inf->pid, 0, thread->gdb_port)))
	    {
	      gdb_assert (thread->msg_state == DARWIN_MESSAGE);
	      darwin_send_reply (inf, thread);
	      thread->msg_state = DARWIN_RUNNING;
	    }
	  else
	    inferior_debug
	      (3, _("darwin_wait: thread %x hit a non-gdb breakpoint\n"),
	       thread->gdb_port);
	}
      else
	inferior_debug (3, _("darwin_wait: unhandled pending message\n"));
    }
  return res;
}

static ptid_t
darwin_wait_to (struct target_ops *ops, 
                ptid_t ptid, struct target_waitstatus *status, int options)
{
  return darwin_wait (ptid, status);
}

static void
darwin_stop (ptid_t t)
{
  struct inferior *inf = current_inferior ();

  /* FIXME: handle in no_ptrace mode.  */
  gdb_assert (!inf->private->no_ptrace);
  kill (inf->pid, SIGINT);
}

static void
darwin_mourn_inferior (struct target_ops *ops)
{
  struct inferior *inf = current_inferior ();
  kern_return_t kret;
  mach_port_t prev;
  int i;

  unpush_target (darwin_ops);

  /* Deallocate threads.  */
  if (inf->private->threads)
    {
      int k;
      darwin_thread_t *t;
      for (k = 0;
	   VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
	   k++)
	{
	  kret = mach_port_deallocate (gdb_task, t->gdb_port);
	  MACH_CHECK_ERROR (kret);
	}
      VEC_free (darwin_thread_t, inf->private->threads);
      inf->private->threads = NULL;
    }

  kret = mach_port_move_member (gdb_task,
				inf->private->notify_port, MACH_PORT_NULL);
  gdb_assert (kret == KERN_SUCCESS);

  kret = mach_port_request_notification (gdb_task, inf->private->task,
					 MACH_NOTIFY_DEAD_NAME, 0,
					 MACH_PORT_NULL,
					 MACH_MSG_TYPE_MAKE_SEND_ONCE,
					 &prev);
  /* This can fail if the task is dead.  */
  inferior_debug (4, "task=%x, prev=%x, notify_port=%x\n",
		  inf->private->task, prev, inf->private->notify_port);

  if (kret == KERN_SUCCESS)
    {
      kret = mach_port_deallocate (gdb_task, prev);
      MACH_CHECK_ERROR (kret);
    }

  kret = mach_port_destroy (gdb_task, inf->private->notify_port);
  MACH_CHECK_ERROR (kret);


  /* Deallocate saved exception ports.  */
  for (i = 0; i < inf->private->exception_info.count; i++)
    {
      kret = mach_port_deallocate
	(gdb_task, inf->private->exception_info.ports[i]);
      MACH_CHECK_ERROR (kret);
    }
  inf->private->exception_info.count = 0;

  kret = mach_port_deallocate (gdb_task, inf->private->task);
  MACH_CHECK_ERROR (kret);

  xfree (inf->private);
  inf->private = NULL;

  generic_mourn_inferior ();
}

static void
darwin_reply_to_all_pending_messages (struct inferior *inf)
{
  int k;
  darwin_thread_t *t;

  for (k = 0;
       VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
       k++)
    {
      if (t->msg_state == DARWIN_MESSAGE)
	darwin_resume_thread (inf, t, 0, 0);
    }
}

static void
darwin_stop_inferior (struct inferior *inf)
{
  struct target_waitstatus wstatus;
  ptid_t ptid;
  kern_return_t kret;
  int status;
  int res;

  gdb_assert (inf != NULL);

  darwin_suspend_inferior (inf);

  darwin_reply_to_all_pending_messages (inf);

  if (inf->private->no_ptrace)
    return;

  res = kill (inf->pid, SIGSTOP);
  if (res != 0)
    warning (_("cannot kill: %s"), safe_strerror (errno));

  /* Wait until the process is really stopped.  */
  while (1)
    {
      ptid = darwin_wait (inferior_ptid, &wstatus);
      if (wstatus.kind == TARGET_WAITKIND_STOPPED
	  && wstatus.value.sig == TARGET_SIGNAL_STOP)
	break;
    }
}

static kern_return_t
darwin_save_exception_ports (darwin_inferior *inf)
{
  kern_return_t kret;

  inf->exception_info.count =
    sizeof (inf->exception_info.ports) / sizeof (inf->exception_info.ports[0]);

  kret = task_get_exception_ports
    (inf->task, EXC_MASK_ALL, inf->exception_info.masks,
     &inf->exception_info.count, inf->exception_info.ports,
     inf->exception_info.behaviors, inf->exception_info.flavors);
  return kret;
}

static kern_return_t
darwin_restore_exception_ports (darwin_inferior *inf)
{
  int i;
  kern_return_t kret;

  for (i = 0; i < inf->exception_info.count; i++)
    {
      kret = task_set_exception_ports
        (inf->task, inf->exception_info.masks[i], inf->exception_info.ports[i],
	 inf->exception_info.behaviors[i], inf->exception_info.flavors[i]);
      if (kret != KERN_SUCCESS)
        return kret;
    }

  return KERN_SUCCESS;
}

static void
darwin_kill_inferior (struct target_ops *ops)
{
  struct inferior *inf = current_inferior ();
  struct target_waitstatus wstatus;
  ptid_t ptid;
  kern_return_t kret;
  int status;
  int res;

  if (ptid_equal (inferior_ptid, null_ptid))
    return;

  gdb_assert (inf != NULL);

  if (!inf->private->no_ptrace)
    {
      darwin_stop_inferior (inf);

      res = PTRACE (PT_KILL, inf->pid, 0, 0);
      if (res != 0)
        warning (_("Failed to kill inferior: ptrace returned %d "
	           "[%s] (pid=%d)"),
		 res, safe_strerror (errno), inf->pid);

      darwin_reply_to_all_pending_messages (inf);

      darwin_resume_inferior (inf);

      ptid = darwin_wait (inferior_ptid, &wstatus);
    }
  else
    {
      kret = darwin_restore_exception_ports (inf->private);
      MACH_CHECK_ERROR (kret);

      darwin_reply_to_all_pending_messages (inf);

      darwin_resume_inferior (inf);

      res = kill (inf->pid, 9);

      ptid = darwin_wait (inferior_ptid, &wstatus);
    }

  target_mourn_inferior ();
}

static void
darwin_attach_pid (struct inferior *inf)
{
  kern_return_t kret;
  mach_port_t prev_port;
  int traps_expected;
  mach_port_t prev_not;
  exception_mask_t mask;

  inf->private = XZALLOC (darwin_inferior);

  kret = task_for_pid (gdb_task, inf->pid, &inf->private->task);
  if (kret != KERN_SUCCESS)
    {
      int status;

      if (!inf->attach_flag)
	{
	  kill (inf->pid, 9);
	  waitpid (inf->pid, &status, 0);
	}

      error (_("Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
	       " (please check gdb is codesigned - see taskgated(8))"),
             inf->pid, mach_error_string (kret), (unsigned long) kret);
    }

  inferior_debug (2, _("inferior task: 0x%x, pid: %d\n"),
		  inf->private->task, inf->pid);

  if (darwin_ex_port == MACH_PORT_NULL)
    {
      /* Create a port to get exceptions.  */
      kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
				 &darwin_ex_port);
      gdb_assert (kret == KERN_SUCCESS);

      kret = mach_port_insert_right (gdb_task, darwin_ex_port, darwin_ex_port,
				     MACH_MSG_TYPE_MAKE_SEND);
      gdb_assert (kret == KERN_SUCCESS);

      /* Create a port set and put ex_port in it.  */
      kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_PORT_SET,
				 &darwin_port_set);
      gdb_assert (kret == KERN_SUCCESS);

      kret = mach_port_move_member (gdb_task, darwin_ex_port, darwin_port_set);
      gdb_assert (kret == KERN_SUCCESS);
    }

  /* Create a port to be notified when the child task terminates.  */
  kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
			     &inf->private->notify_port);
  gdb_assert (kret == KERN_SUCCESS);

  kret = mach_port_move_member (gdb_task,
				inf->private->notify_port, darwin_port_set);
  gdb_assert (kret == KERN_SUCCESS);

  kret = mach_port_request_notification (gdb_task, inf->private->task,
					 MACH_NOTIFY_DEAD_NAME, 0,
					 inf->private->notify_port,
					 MACH_MSG_TYPE_MAKE_SEND_ONCE,
					 &prev_not);
  gdb_assert (kret == KERN_SUCCESS);
  gdb_assert (prev_not == MACH_PORT_NULL);

  kret = darwin_save_exception_ports (inf->private);
  gdb_assert (kret == KERN_SUCCESS);

  /* Set exception port.  */
  if (enable_mach_exceptions)
    mask = EXC_MASK_ALL;
  else
    mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
  kret = task_set_exception_ports (inf->private->task, mask, darwin_ex_port,
				   EXCEPTION_DEFAULT, THREAD_STATE_NONE);
  gdb_assert (kret == KERN_SUCCESS);

  push_target (darwin_ops);
}

static void
darwin_init_thread_list (struct inferior *inf)
{
  darwin_thread_t *thread;
  ptid_t new_ptid;

  darwin_check_new_threads (inf);

  gdb_assert (inf->private->threads
	      && VEC_length (darwin_thread_t, inf->private->threads) > 0);
  thread = VEC_index (darwin_thread_t, inf->private->threads, 0);

  /* Note: fork_inferior automatically add a thead but it uses a wrong ptid.
     Fix up.  */
  new_ptid = ptid_build (inf->pid, 0, thread->gdb_port);
  thread_change_ptid (inferior_ptid, new_ptid);
  inferior_ptid = new_ptid;
}

/* The child must synchronize with gdb: gdb must set the exception port
   before the child call PTRACE_SIGEXC.  We use a pipe to achieve this.
   FIXME: is there a lighter way ?  */
static int ptrace_fds[2];

static void
darwin_ptrace_me (void)
{
  int res;
  char c;

  /* Close write end point.  */
  close (ptrace_fds[1]);

  /* Wait until gdb is ready.  */
  res = read (ptrace_fds[0], &c, 1);
  gdb_assert (res == 0);
  close (ptrace_fds[0]);

  /* Get rid of privileges.  */
  setegid (getgid ());

  /* Set TRACEME.  */
  PTRACE (PT_TRACE_ME, 0, 0, 0);

  /* Redirect signals to exception port.  */
  PTRACE (PT_SIGEXC, 0, 0, 0);
}

/* Dummy function to be sure fork_inferior uses fork(2) and not vfork(2).  */
static void
darwin_pre_ptrace (void)
{
  if (pipe (ptrace_fds) != 0)
    {
      ptrace_fds[0] = -1;
      ptrace_fds[1] = -1;
      error (_("unable to create a pipe: %s"), safe_strerror (errno));
    }
}

static void
darwin_ptrace_him (int pid)
{
  task_t itask;
  kern_return_t kret;
  mach_port_t prev_port;
  int traps_expected;
  struct inferior *inf = current_inferior ();

  darwin_attach_pid (inf);

  /* Let's the child run.  */
  close (ptrace_fds[0]);
  close (ptrace_fds[1]);

  darwin_init_thread_list (inf);

  startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
}

static void
darwin_execvp (const char *file, char * const argv[], char * const env[])
{
  posix_spawnattr_t attr;
  short ps_flags = 0;
  int res;

  res = posix_spawnattr_init (&attr);
  if (res != 0)
    {
      fprintf_unfiltered
        (gdb_stderr, "Cannot initialize attribute for posix_spawn\n");
      return;
    }

  /* Do like execve: replace the image.  */
  ps_flags = POSIX_SPAWN_SETEXEC;

  /* Disable ASLR.  The constant doesn't look to be available outside the
     kernel include files.  */
#ifndef _POSIX_SPAWN_DISABLE_ASLR
#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
#endif
  ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
  res = posix_spawnattr_setflags (&attr, ps_flags);
  if (res != 0)
    {
      fprintf_unfiltered (gdb_stderr, "Cannot set posix_spawn flags\n");
      return;
    }

  posix_spawnp (NULL, argv[0], NULL, &attr, argv, env);
}

static void
darwin_create_inferior (struct target_ops *ops, char *exec_file,
			char *allargs, char **env, int from_tty)
{
  /* Do the hard work.  */
  fork_inferior (exec_file, allargs, env, darwin_ptrace_me, darwin_ptrace_him,
		 darwin_pre_ptrace, NULL, darwin_execvp);

  /* Return now in case of error.  */
  if (ptid_equal (inferior_ptid, null_ptid))
    return;
}


/* Attach to process PID, then initialize for debugging it
   and wait for the trace-trap that results from attaching.  */
static void
darwin_attach (struct target_ops *ops, char *args, int from_tty)
{
  pid_t pid;
  pid_t pid2;
  int wstatus;
  int res;
  struct inferior *inf;
  kern_return_t kret;

  pid = parse_pid_to_attach (args);

  if (pid == getpid ())		/* Trying to masturbate?  */
    error (_("I refuse to debug myself!"));

  if (from_tty)
    {
      char *exec_file = 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);
    }

  if (pid == 0 || kill (pid, 0) < 0)
    error (_("Can't attach to process %d: %s (%d)"),
           pid, safe_strerror (errno), errno);

  inferior_ptid = pid_to_ptid (pid);
  inf = current_inferior ();
  inferior_appeared (inf, pid);
  inf->attach_flag = 1;

  /* Always add a main thread.  */
  add_thread_silent (inferior_ptid);

  darwin_attach_pid (inf);

  darwin_suspend_inferior (inf);

  darwin_init_thread_list (inf);

  darwin_check_osabi (inf->private, ptid_get_tid (inferior_ptid));

  gdb_assert (darwin_inf_fake_stop == NULL);
  darwin_inf_fake_stop = inf;
  inf->private->no_ptrace = 1;
}

/* 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
darwin_detach (struct target_ops *ops, char *args, int from_tty)
{
  pid_t pid = ptid_get_pid (inferior_ptid);
  struct inferior *inf = current_inferior ();
  kern_return_t kret;
  int res;

  /* Display message.  */
  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 (pid_to_ptid (pid)));
      gdb_flush (gdb_stdout);
    }

  /* If ptrace() is in use, stop the process.  */
  if (!inf->private->no_ptrace)
    darwin_stop_inferior (inf);

  kret = darwin_restore_exception_ports (inf->private);
  MACH_CHECK_ERROR (kret);

  if (!inf->private->no_ptrace)
    {
      res = PTRACE (PT_DETACH, inf->pid, 0, 0);
      if (res != 0)
	printf_unfiltered (_("Unable to detach from process-id %d: %s (%d)"),
			   inf->pid, safe_strerror (errno), errno);
    }

  darwin_reply_to_all_pending_messages (inf);

  /* When using ptrace, we have just performed a PT_DETACH, which
     resumes the inferior.  On the other hand, when we are not using
     ptrace, we need to resume its execution ourselves.  */
  if (inf->private->no_ptrace)
    darwin_resume_inferior (inf);

  darwin_mourn_inferior (ops);
}

static void
darwin_files_info (struct target_ops *ops)
{
}

static char *
darwin_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
  static char buf[80];
  long tid = ptid_get_tid (ptid);

  if (tid != 0)
    {
      snprintf (buf, sizeof (buf), _("Thread 0x%lx of process %u"),
		tid, ptid_get_pid (ptid));
      return buf;
    }

  return normal_pid_to_str (ptid);
}

static int
darwin_thread_alive (struct target_ops *ops, ptid_t ptid)
{
  return 1;
}

/* If RDADDR is not NULL, read inferior task's LEN bytes from ADDR and
   copy it to RDADDR in gdb's address space.
   If WRADDR is not NULL, write gdb's LEN bytes from WRADDR and copy it
   to ADDR in inferior task's address space.
   Return 0 on failure; number of bytes read / writen otherwise.  */
static int
darwin_read_write_inferior (task_t task, CORE_ADDR addr,
			    char *rdaddr, const char *wraddr, int length)
{
  kern_return_t kret;
  mach_vm_address_t offset = addr & (mach_page_size - 1);
  mach_vm_address_t low_address = (mach_vm_address_t) (addr - offset);
  mach_vm_size_t aligned_length = (mach_vm_size_t) PAGE_ROUND (offset + length);
  pointer_t copied;
  int copy_count;
  mach_vm_size_t remaining_length;
  mach_vm_address_t region_address;
  mach_vm_size_t region_length;

  inferior_debug (8, _("darwin_read_write_inferior(task=%x, %s, len=%d)\n"),
		  task, core_addr_to_string (addr), length);

  /* Get memory from inferior with page aligned addresses.  */
  kret = mach_vm_read (task, low_address, aligned_length,
		      &copied, &copy_count);
  if (kret != KERN_SUCCESS)
    {
      inferior_debug
	(1, _("darwin_read_write_inferior: mach_vm_read failed at %s: %s"),
	 core_addr_to_string (addr), mach_error_string (kret));
      return 0;
    }

  if (rdaddr != NULL)
    memcpy (rdaddr, (char *)copied + offset, length);

  if (wraddr == NULL)
    goto out;

  memcpy ((char *)copied + offset, wraddr, length);

  /* Do writes atomically.
     First check for holes and unwritable memory.  */
  for (region_address = low_address, remaining_length = aligned_length;
       region_address < low_address + aligned_length;
       region_address += region_length, remaining_length -= region_length)
    {
      vm_region_submap_short_info_data_64_t info;
      mach_vm_address_t region_start = region_address;
      mach_msg_type_number_t count;
      natural_t region_depth;

      region_depth = 100000;
      count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
      kret = mach_vm_region_recurse
	(task, &region_start, &region_length, &region_depth,
	 (vm_region_recurse_info_t) &info, &count);

      if (kret != KERN_SUCCESS)
	{
	  inferior_debug (1, _("darwin_read_write_inferior: "
			       "mach_vm_region_recurse failed at %s: %s\n"),
			  core_addr_to_string (region_address),
			  mach_error_string (kret));
	  goto out;
	}

      inferior_debug
	(9, _("darwin_read_write_inferior: "
	      "mach_vm_region_recurse addr=%s, start=%s, len=%s\n"),
	 core_addr_to_string (region_address),
	 core_addr_to_string (region_start),
	 core_addr_to_string (region_length));

      /* Check for holes in memory.  */
      if (region_start > region_address)
	{
	  warning (_("No memory at %s (vs %s+0x%x).  Nothing written"),
		   core_addr_to_string (region_address),
		   core_addr_to_string (region_start),
		   (unsigned)region_length);
	  length = 0;
	  goto out;
	}

      /* Adjust the length.  */
      region_length -= (region_address - region_start);

      if (!(info.max_protection & VM_PROT_WRITE))
	{
	  kret = mach_vm_protect
	    (task, region_address, region_length,
	     TRUE, info.max_protection | VM_PROT_WRITE | VM_PROT_COPY);
	  if (kret != KERN_SUCCESS)
	    {
	      warning (_("darwin_read_write_inf: "
			 "mach_vm_protect max failed at %s: %s"),
		       core_addr_to_string (region_address),
		       mach_error_string (kret));
	      length = 0;
	      goto out;
	    }
	}

      if (!(info.protection & VM_PROT_WRITE))
	{
	  kret = mach_vm_protect (task, region_address, region_length,
				 FALSE, info.protection | VM_PROT_WRITE);
	  if (kret != KERN_SUCCESS)
	    {
	      warning (_("darwin_read_write_inf: "
			 "mach_vm_protect failed at %s (len=0x%lx): %s"),
		       core_addr_to_string (region_address),
		       (unsigned long)region_length, mach_error_string (kret));
	      length = 0;
	      goto out;
	    }
	}
    }

  kret = mach_vm_write (task, low_address, copied, aligned_length);

  if (kret != KERN_SUCCESS)
    {
      warning (_("darwin_read_write_inferior: mach_vm_write failed: %s"),
	       mach_error_string (kret));
      length = 0;
    }
out:
  mach_vm_deallocate (mach_task_self (), copied, copy_count);
  return length;
}

/* Read LENGTH bytes at offset ADDR of task_dyld_info for TASK, and copy them
   to RDADDR.
   Return 0 on failure; number of bytes read / writen otherwise.  */

static int
darwin_read_dyld_info (task_t task, CORE_ADDR addr, char *rdaddr, int length)
{
  struct task_dyld_info task_dyld_info;
  mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
  int sz = TASK_DYLD_INFO_COUNT * sizeof (natural_t);
  kern_return_t kret;

  if (addr >= sz)
    return 0;

  kret = task_info (task, TASK_DYLD_INFO, (task_info_t) &task_dyld_info, &count);
  MACH_CHECK_ERROR (kret);
  if (kret != KERN_SUCCESS)
    return -1;
  /* Truncate.  */
  if (addr + length > sz)
    length = sz - addr;
  memcpy (rdaddr, (char *)&task_dyld_info + addr, length);
  return length;
}


/* Return 0 on failure, number of bytes handled otherwise.  TARGET
   is ignored.  */
static int
darwin_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
		    struct mem_attrib *attrib, struct target_ops *target)
{
  struct inferior *inf = current_inferior ();
  task_t task = inf->private->task;

  if (task == MACH_PORT_NULL)
    return 0;

  inferior_debug (8, _("darwin_xfer_memory(%s, %d, %c)\n"),
		  core_addr_to_string (memaddr), len, write ? 'w' : 'r');

  if (write)
    return darwin_read_write_inferior (task, memaddr, NULL, myaddr, len);
  else
    return darwin_read_write_inferior (task, memaddr, myaddr, NULL, len);
}

static LONGEST
darwin_xfer_partial (struct target_ops *ops,
		     enum target_object object, const char *annex,
		     gdb_byte *readbuf, const gdb_byte *writebuf,
		     ULONGEST offset, LONGEST len)
{
  struct inferior *inf = current_inferior ();

  inferior_debug
    (8, _("darwin_xfer_partial(%s, %d, rbuf=%s, wbuf=%s) pid=%u\n"),
     core_addr_to_string (offset), (int)len,
     host_address_to_string (readbuf), host_address_to_string (writebuf),
     inf->pid);

  switch (object)
    {
    case TARGET_OBJECT_MEMORY:
      return darwin_read_write_inferior (inf->private->task, offset,
                                         readbuf, writebuf, len);
    case TARGET_OBJECT_DARWIN_DYLD_INFO:
      if (writebuf != NULL || readbuf == NULL)
        {
          /* Support only read.  */
          return -1;
        }
      return darwin_read_dyld_info (inf->private->task, offset, readbuf, len);
    default:
      return -1;
    }

}

static void
set_enable_mach_exceptions (char *args, int from_tty,
			    struct cmd_list_element *c)
{
  if (!ptid_equal (inferior_ptid, null_ptid))
    {
      struct inferior *inf = current_inferior ();
      exception_mask_t mask;
      kern_return_t kret;

      if (enable_mach_exceptions)
	mask = EXC_MASK_ALL;
      else
	{
	  darwin_restore_exception_ports (inf->private);
	  mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
	}
      kret = task_set_exception_ports (inf->private->task, mask, darwin_ex_port,
				       EXCEPTION_DEFAULT, THREAD_STATE_NONE);
      MACH_CHECK_ERROR (kret);
    }
}

static char *
darwin_pid_to_exec_file (int pid)
{
  char *path;
  int res;

  path = xmalloc (MAXPATHLEN);
  make_cleanup (xfree, path);

  res = proc_pidinfo (pid, PROC_PIDPATHINFO, 0, path, MAXPATHLEN);
  if (res >= 0)
    return path;
  else
    return NULL;
}

static ptid_t
darwin_get_ada_task_ptid (long lwp, long thread)
{
  int i;
  darwin_thread_t *t;
  int k;
  struct inferior *inf = current_inferior ();
  kern_return_t kret;
  mach_port_name_array_t names;
  mach_msg_type_number_t names_count;
  mach_port_type_array_t types;
  mach_msg_type_number_t types_count;
  long res = 0;

  /* First linear search.  */
  for (k = 0;
       VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
       k++)
    if (t->inf_port == lwp)
      return ptid_build (ptid_get_pid (inferior_ptid), 0, t->gdb_port);

  /* Maybe the port was never extract.  Do it now.  */

  /* First get inferior port names.  */
  kret = mach_port_names (inf->private->task, &names, &names_count, &types,
			  &types_count);
  MACH_CHECK_ERROR (kret);
  if (kret != KERN_SUCCESS)
    return null_ptid;

  /* For each name, copy the right in the gdb space and then compare with
     our view of the inferior threads.  We don't forget to deallocate the
     right.  */
  for (i = 0; i < names_count; i++)
    {
      mach_port_t local_name;
      mach_msg_type_name_t local_type;

      /* We just need to know the corresponding name in gdb name space.
	 So extract and deallocate the right.  */
      kret = mach_port_extract_right (inf->private->task, names[i],
				      MACH_MSG_TYPE_COPY_SEND,
				      &local_name, &local_type);
      if (kret != KERN_SUCCESS)
	continue;
      mach_port_deallocate (gdb_task, local_name);

      for (k = 0;
	   VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
	   k++)
	if (t->gdb_port == local_name)
	  {
	    t->inf_port = names[i];
	    if (names[i] == lwp)
	      res = t->gdb_port;
	  }
    }

  vm_deallocate (gdb_task, (vm_address_t) names,
                 names_count * sizeof (mach_port_t));

  if (res)
    return ptid_build (ptid_get_pid (inferior_ptid), 0, res);
  else
    return null_ptid;
}

static int
darwin_supports_multi_process (void)
{
  return 1;
}

void
_initialize_darwin_inferior (void)
{
  kern_return_t kret;

  gdb_task = mach_task_self ();
  darwin_host_self = mach_host_self ();

  /* Read page size.  */
  kret = host_page_size (darwin_host_self, &mach_page_size);
  if (kret != KERN_SUCCESS)
    {
      mach_page_size = 0x1000;
      MACH_CHECK_ERROR (kret);
    }

  darwin_ops = inf_child_target ();

  darwin_ops->to_shortname = "darwin-child";
  darwin_ops->to_longname = _("Darwin child process");
  darwin_ops->to_doc =
    _("Darwin child process (started by the \"run\" command).");
  darwin_ops->to_create_inferior = darwin_create_inferior;
  darwin_ops->to_attach = darwin_attach;
  darwin_ops->to_attach_no_wait = 0;
  darwin_ops->to_detach = darwin_detach;
  darwin_ops->to_files_info = darwin_files_info;
  darwin_ops->to_wait = darwin_wait_to;
  darwin_ops->to_mourn_inferior = darwin_mourn_inferior;
  darwin_ops->to_kill = darwin_kill_inferior;
  darwin_ops->to_stop = darwin_stop;
  darwin_ops->to_resume = darwin_resume_to;
  darwin_ops->to_thread_alive = darwin_thread_alive;
  darwin_ops->to_pid_to_str = darwin_pid_to_str;
  darwin_ops->to_pid_to_exec_file = darwin_pid_to_exec_file;
  darwin_ops->to_load = NULL;
  darwin_ops->deprecated_xfer_memory = darwin_xfer_memory;
  darwin_ops->to_xfer_partial = darwin_xfer_partial;
  darwin_ops->to_supports_multi_process = darwin_supports_multi_process;
  darwin_ops->to_get_ada_task_ptid = darwin_get_ada_task_ptid;

  darwin_complete_target (darwin_ops);

  add_target (darwin_ops);

  inferior_debug (2, _("GDB task: 0x%lx, pid: %d\n"), mach_task_self (),
                  getpid ());

  add_setshow_zinteger_cmd ("darwin", class_obscure,
			    &darwin_debug_flag, _("\
Set if printing inferior communication debugging statements."), _("\
Show if printing inferior communication debugging statements."), NULL,
			    NULL, NULL,
			    &setdebuglist, &showdebuglist);

  add_setshow_boolean_cmd ("mach-exceptions", class_support,
			   &enable_mach_exceptions, _("\
Set if mach exceptions are caught."), _("\
Show if mach exceptions are caught."), _("\
When this mode is on, all low level exceptions are reported before being\n\
reported by the kernel."),
			   &set_enable_mach_exceptions, NULL,
			   &setlist, &showlist);
}
