/* Darwin support for GDB, the GNU debugger.
   Copyright (C) 2008-2022 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 "gdbcmd.h"
#include "gdbcore.h"
#include "gdbthread.h"
#include "regcache.h"
#include "event-top.h"
#include "inf-loop.h"
#include <sys/stat.h>
#include "inf-child.h"
#include "value.h"
#include "arch-utils.h"
#include "bfd.h"
#include "bfd/mach-o.h"
#include "gdbarch.h"

#include <copyfile.h>
#include <sys/ptrace.h>
#include <sys/signal.h>
#include <setjmp.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.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"
#include "filenames.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/gdb_unlinker.h"
#include "gdbsupport/pathstuff.h"
#include "gdbsupport/scoped_fd.h"
#include "nat/fork-inferior.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))

static void darwin_ptrace_me (void);

static void darwin_encode_reply (mig_reply_error_t *reply,
				 mach_msg_header_t *hdr, integer_t code);

static void darwin_setup_request_notification (struct inferior *inf);
static void darwin_deallocate_exception_ports (darwin_inferior *inf);
static void darwin_setup_exceptions (struct inferior *inf);
static void darwin_deallocate_threads (struct inferior *inf);

/* 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, to wait for answer on all ports.  */
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 bool enable_mach_exceptions;

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

/* If non-NULL, the shell we actually invoke.  See maybe_cache_shell
   for details.  */
static const char *copied_shell;

#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 unsigned 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 must 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, ...)
  ATTRIBUTE_PRINTF (2, 3);

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

  if (darwin_debug_flag < level)
    return;

  va_start (ap, fmt);
  gdb_printf (gdb_stdlog, _("[%d inferior]: "), getpid ());
  gdb_vprintf (gdb_stdlog, 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, caddr_t arg3, int arg4)
{
  int ret;

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

  inferior_debug (4, _("ptrace (%s, %d, 0x%lx, %d): %d (%s)\n"),
		  name, pid, (unsigned long) 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);
}

void
darwin_nat_target::check_new_threads (inferior *inf)
{
  kern_return_t kret;
  thread_array_t thread_list;
  unsigned int new_nbr;
  unsigned int old_nbr;
  unsigned int new_ix, old_ix;
  darwin_inferior *darwin_inf = get_darwin_inferior (inf);
  std::vector<darwin_thread_t *> new_thread_vec;

  if (darwin_inf == nullptr)
    return;

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

  old_nbr = darwin_inf->threads.size ();

  /* Quick check for no changes.  */
  if (old_nbr == new_nbr)
    {
      size_t i;

      for (i = 0; i < new_nbr; i++)
	if (thread_list[i] != darwin_inf->threads[i]->gdb_port)
	  break;
      if (i == new_nbr)
	{
	  /* Deallocate ports.  */
	  for (i = 0; i < new_nbr; i++)
	    {
	      kret = mach_port_deallocate (mach_task_self (), thread_list[i]);
	      MACH_CHECK_ERROR (kret);
	    }

	  /* Deallocate the buffer.  */
	  kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
				new_nbr * sizeof (int));
	  MACH_CHECK_ERROR (kret);

	  return;
	}
    }

  /* Full handling: detect new threads, remove dead threads.  */

  new_thread_vec.reserve (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) ? darwin_inf->threads[old_ix] : NULL;
      thread_t old_id = old != NULL ? old->gdb_port : THREAD_NULL;

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

      if (old_id == new_id)
	{
	  /* Thread still exist.  */
	  new_thread_vec.push_back (old);
	  new_ix++;
	  old_ix++;

	  /* Deallocate the port.  */
	  kret = mach_port_deallocate (gdb_task, new_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.  */
	  darwin_thread_info *pti = new darwin_thread_info;

	  pti->gdb_port = new_id;
	  pti->msg_state = DARWIN_RUNNING;

	  /* Add the new thread.  */
	  add_thread_with_info (this, ptid_t (inf->pid, 0, new_id), pti);
	  new_thread_vec.push_back (pti);
	  new_ix++;
	  continue;
	}
      if (old_ix < old_nbr && (new_ix == new_nbr || new_id > old_id))
	{
	  /* A thread was removed.  */
	  struct thread_info *thr
	    = find_thread_ptid (this, ptid_t (inf->pid, 0, old_id));
	  delete_thread (thr);
	  kret = mach_port_deallocate (gdb_task, old_id);
	  MACH_CHECK_ERROR (kret);
	  old_ix++;
	  continue;
	}
      gdb_assert_not_reached ("unexpected thread case");
    }

  darwin_inf->threads = std::move (new_thread_vec);

  /* Deallocate the buffer.  */
  kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
			new_nbr * sizeof (int));
  MACH_CHECK_ERROR (kret);
}

/* Return an inferior by task port.  */
static struct inferior *
darwin_find_inferior_by_task (task_t port)
{
  for (inferior *inf : all_inferiors ())
    {
      darwin_inferior *priv = get_darwin_inferior (inf);

      if (priv != nullptr && priv->task == port)
	return inf;
    }
  return nullptr;
}

/* Return an inferior by pid port.  */
static struct inferior *
darwin_find_inferior_by_pid (int pid)
{
  for (inferior *inf : all_inferiors ())
    {
      if (inf->pid == pid)
	return inf;
    }
  return nullptr;
}

/* Return a thread by port.  */
static darwin_thread_t *
darwin_find_thread (struct inferior *inf, thread_t thread)
{
  darwin_inferior *priv = get_darwin_inferior (inf);

  if (priv != nullptr)
    for (darwin_thread_t *t : priv->threads)
      {
	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)
{
  darwin_inferior *priv = get_darwin_inferior (inf);

  if (priv != nullptr && !priv->suspended)
    {
      kern_return_t kret;

      kret = task_suspend (priv->task);
      MACH_CHECK_ERROR (kret);

      priv->suspended = 1;
    }
}

/* Resume an inferior at Mach level.  */

static void
darwin_resume_inferior (struct inferior *inf)
{
  darwin_inferior *priv = get_darwin_inferior (inf);

  if (priv != nullptr && priv->suspended)
    {
      kern_return_t kret;

      kret = task_resume (priv->task);
      MACH_CHECK_ERROR (kret);

      priv->suspended = 0;
    }
}

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

  if (disp_body)
    {
      const unsigned char *data;
      const unsigned int *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;
	  gdb_printf (gdb_stdlog,
		      _("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:
		gdb_printf
		  (gdb_stdlog,
		   _(" descr %d: type=%u (port) name=0x%x, dispo=%d\n"),
		   k, desc[k].type, desc[k].name, desc[k].disposition);
		break;
	      default:
		gdb_printf (gdb_stdlog,
			    _(" 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);
	  gdb_printf
	    (gdb_stdlog,
	     _("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);
	}

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

/* Adjust inferior data when a new task was created.  */

static struct inferior *
darwin_find_new_inferior (task_t task_port, thread_t thread_port)
{
  int task_pid;
  struct inferior *inf;
  kern_return_t kret;
  mach_port_t prev;

  /* Find the corresponding pid.  */
  kret = pid_for_task (task_port, &task_pid);
  if (kret != KERN_SUCCESS)
    {
      MACH_CHECK_ERROR (kret);
      return NULL;
    }

  /* Find the inferior for this pid.  */
  inf = darwin_find_inferior_by_pid (task_pid);
  if (inf == NULL)
    return NULL;

  darwin_inferior *priv = get_darwin_inferior (inf);

  /* Deallocate saved exception ports.  */
  darwin_deallocate_exception_ports (priv);

  /* No need to remove dead_name notification, but still...  */
  kret = mach_port_request_notification (gdb_task, priv->task,
					 MACH_NOTIFY_DEAD_NAME, 0,
					 MACH_PORT_NULL,
					 MACH_MSG_TYPE_MAKE_SEND_ONCE,
					 &prev);
  if (kret != KERN_INVALID_ARGUMENT)
    MACH_CHECK_ERROR (kret);

  /* Replace old task port.  */
  kret = mach_port_deallocate (gdb_task, priv->task);
  MACH_CHECK_ERROR (kret);
  priv->task = task_port;

  darwin_setup_request_notification (inf);
  darwin_setup_exceptions (inf);

  return inf;
}

/* Check data representation.  */

static int
darwin_check_message_ndr (NDR_record_t *ndr)
{
  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;
  return 0;
}

/* Decode an exception message.  */

int
darwin_nat_target::decode_exception_message (mach_msg_header_t *hdr,
					     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 destination.  */
  if (hdr->msgh_local_port != darwin_ex_port)
    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 (darwin_check_message_ndr (ndr) != 0)
    return -1;

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

  task_port = desc[1].name;
  thread_port = desc[0].name;

  /* Find process by port.  */
  inf = darwin_find_inferior_by_task (task_port);
  *pinf = inf;

  if (inf == NULL && data[0] == EXC_SOFTWARE && data[1] == 2
      && data[2] == EXC_SOFT_SIGNAL && data[3] == SIGTRAP)
    {
      /* Not a known inferior, but a sigtrap.  This happens on darwin 16.1.0,
	 as a new Mach task is created when a process exec.  */
      inf = darwin_find_new_inferior (task_port, thread_port);
      *pinf = inf;

      if (inf == NULL)
	{
	  /* Deallocate task_port, unless it was saved.  */
	  kret = mach_port_deallocate (mach_task_self (), task_port);
	  MACH_CHECK_ERROR (kret);
	}
    }
  else
    {
      /* We got new rights to the task, get rid of it.  Do not get rid of
	 thread right, as we will need it to find the thread.  */
      kret = mach_port_deallocate (mach_task_self (), task_port);
      MACH_CHECK_ERROR (kret);
    }

  if (inf == NULL)
    {
      /* Not a known inferior.  This could happen if the child fork, as
	 the created process will inherit its exception port.
	 FIXME: should the exception port be restored ?  */
      mig_reply_error_t reply;

      inferior_debug
	(4, _("darwin_decode_exception_message: unknown task 0x%x\n"),
	 task_port);

      /* Free thread port (we don't know it).  */
      kret = mach_port_deallocate (mach_task_self (), thread_port);
      MACH_CHECK_ERROR (kret);

      darwin_encode_reply (&reply, hdr, 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);

      return 0;
    }

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

  /* Free the thread port (as gdb knows the thread, it has already has a right
     for it, so this just decrement a reference counter).  */
  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;
}

/* Decode dead_name notify message.  */

static int
darwin_decode_notify_message (mach_msg_header_t *hdr, struct inferior **pinf)
{
  NDR_record_t *ndr = (NDR_record_t *)(hdr + 1);
  integer_t *data = (integer_t *)(ndr + 1);
  struct inferior *inf;
  task_t task_port;

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

  /* Check descriptors.  */
  if (hdr->msgh_size < (sizeof (*hdr) + sizeof (*ndr) + sizeof (integer_t)))
    return -2;

  /* Check data representation.  */
  if (darwin_check_message_ndr (ndr) != 0)
    return -3;

  task_port = data[0];

  /* Find process by port.  */
  inf = darwin_find_inferior_by_task (task_port);
  *pinf = inf;

  /* Check message destination.  */
  if (inf != NULL)
    {
      darwin_inferior *priv = get_darwin_inferior (inf);
      if (hdr->msgh_local_port != priv->notify_port)
	return -4;
    }

  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_inferior *priv = get_darwin_inferior (inf);

  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);

  priv->pending_messages--;
}

/* Wrapper around the __pthread_kill syscall.  We use this instead of the
   pthread_kill function to be able to send a signal to any kind of thread,
   including GCD threads.  */

static int
darwin_pthread_kill (darwin_thread_t *thread, int nsignal)
{
  DIAGNOSTIC_PUSH;
  DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS;
  int res = syscall (SYS___pthread_kill, thread->gdb_port, nsignal);
  DIAGNOSTIC_POP;
  return res;
}

static void
darwin_resume_thread (struct inferior *inf, darwin_thread_t *thread,
		      int step, int nsignal)
{
  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.  */
	  int res = PTRACE (PT_THUPDATE, inf->pid,
			    (caddr_t) (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.  */
	  int res = darwin_pthread_kill (thread, nsignal);
	  inferior_debug (4, _("darwin_resume_thread: kill 0x%x %d: %d\n"),
			  thread->gdb_port, nsignal, res);
	  thread->signaled = 1;
	}

      /* Set or reset single step.  */
      inferior_debug (4, _("darwin_set_sstep (thread=0x%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:
      kern_return_t 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_inferior *priv = get_darwin_inferior (inf);

  if (priv != nullptr)
    for (darwin_thread_t *thread : priv->threads)
      darwin_resume_thread (inf, thread, step, nsignal);
}

/* Suspend all threads of INF.  */

static void
darwin_suspend_inferior_threads (struct inferior *inf)
{
  darwin_inferior *priv = get_darwin_inferior (inf);

  for (darwin_thread_t *thread : priv->threads)
    {
      switch (thread->msg_state)
	{
	case DARWIN_STOPPED:
	case DARWIN_MESSAGE:
	  break;
	case DARWIN_RUNNING:
	  {
	    kern_return_t kret = thread_suspend (thread->gdb_port);
	    MACH_CHECK_ERROR (kret);
	    thread->msg_state = DARWIN_STOPPED;
	    break;
	  }
	}
    }
}

void
darwin_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
{
  int nsignal;

  inferior_debug
    (2, _("darwin_resume: ptid=%s, step=%d, signal=%d\n"),
     ptid.to_string ().c_str (), step, signal);

  if (signal == GDB_SIGNAL_0)
    nsignal = 0;
  else
    nsignal = gdb_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 == minus_one_ptid)
    {
      /* Resume threads.  */
      for (inferior *inf : all_inferiors ())
	darwin_resume_inferior_threads (inf, step, nsignal);

      /* Resume tasks.  */
      for (inferior *inf : all_inferiors ())
	darwin_resume_inferior (inf);
    }
  else
    {
      inferior *inf = find_inferior_ptid (this, ptid);
      long tid = ptid.tid ();

      /* 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);
    }
}

ptid_t
darwin_nat_target::decode_message (mach_msg_header_t *hdr,
				   darwin_thread_t **pthread,
				   inferior **pinf,
				   target_waitstatus *status)
{
  darwin_thread_t *thread;
  struct inferior *inf;

  /* Exception message.  2401 == 0x961 is exc.  */
  if (hdr->msgh_id == 2401)
    {
      int res;

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

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

      darwin_inferior *priv = get_darwin_inferior (inf);

      priv->pending_messages++;

      thread->msg_state = DARWIN_MESSAGE;

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

      switch (thread->event.ex_type)
	{
	case EXC_BAD_ACCESS:
	  status->set_stopped (GDB_EXC_BAD_ACCESS);
	  break;
	case EXC_BAD_INSTRUCTION:
	  status->set_stopped (GDB_EXC_BAD_INSTRUCTION);
	  break;
	case EXC_ARITHMETIC:
	  status->set_stopped (GDB_EXC_ARITHMETIC);
	  break;
	case EXC_EMULATION:
	  status->set_stopped (GDB_EXC_EMULATION);
	  break;
	case EXC_SOFTWARE:
	  if (thread->event.ex_data[0] == EXC_SOFT_SIGNAL)
	    {
	      status->set_stopped
		(gdb_signal_from_host (thread->event.ex_data[1]));
	      inferior_debug (5, _("  (signal %d: %s)\n"),
			      thread->event.ex_data[1],
			      gdb_signal_to_name (status->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->set_ignore ();
		}
	    }
	  else
	    status->set_stopped (GDB_EXC_SOFTWARE);
	  break;
	case EXC_BREAKPOINT:
	  /* Many internal GDB routines expect breakpoints to be reported
	     as GDB_SIGNAL_TRAP, and will report GDB_EXC_BREAKPOINT
	     as a spurious signal.  */
	  status->set_stopped (GDB_SIGNAL_TRAP);
	  break;
	default:
	  status->set_stopped (GDB_SIGNAL_UNKNOWN);
	  break;
	}

      return ptid_t (inf->pid, 0, thread->gdb_port);
    }
  else if (hdr->msgh_id == 0x48)
    {
      /* MACH_NOTIFY_DEAD_NAME: notification for exit *or* WIFSTOPPED.  */
      int res;

      res = darwin_decode_notify_message (hdr, &inf);

      if (res < 0)
	{
	  /* Should not happen...  */
	  warning
	    (_("darwin_wait: ill-formatted message (id=0x%x, res=%d)\n"),
	     hdr->msgh_id, res);
	}

      *pinf = NULL;
      *pthread = NULL;

      if (res < 0 || inf == NULL)
	{
	  status->set_ignore ();
	  return minus_one_ptid;
	}

      if (inf != NULL)
	{
	  darwin_inferior *priv = get_darwin_inferior (inf);

	  if (!priv->no_ptrace)
	    {
	      pid_t res_pid;
	      int wstatus;

	      res_pid = wait4 (inf->pid, &wstatus, 0, NULL);
	      if (res_pid < 0 || res_pid != inf->pid)
		{
		  warning (_("wait4: res=%d: %s\n"),
			   res_pid, safe_strerror (errno));
		  status->set_ignore ();
		  return minus_one_ptid;
		}
	      if (WIFEXITED (wstatus))
		{
		  status->set_exited (WEXITSTATUS (wstatus));
	          inferior_debug (4, _("darwin_wait: pid=%d exit, status=0x%x\n"),
				  res_pid, wstatus);
		}
	      else if (WIFSTOPPED (wstatus))
		{
		  /* Ignore stopped state, it will be handled by the next
		     exception.  */
		  status->set_ignore ();
		  inferior_debug (4, _("darwin_wait: pid %d received WIFSTOPPED\n"),
				  res_pid);
		  return minus_one_ptid;
		}
	      else if (WIFSIGNALED (wstatus))
		{
		  status->set_signalled
		    (gdb_signal_from_host (WTERMSIG (wstatus)));
		  inferior_debug (4, _("darwin_wait: pid=%d received signal %d\n"),
				  res_pid, status->sig());
		}
	      else
		{
		  status->set_ignore ();
		  warning (_("Unexpected wait status after MACH_NOTIFY_DEAD_NAME "
		             "notification: 0x%x"), wstatus);
		  return minus_one_ptid;
		}

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

  /* Unknown message.  */
  warning (_("darwin: got unknown message, id: 0x%x"), hdr->msgh_id);
  status->set_ignore ();
  return minus_one_ptid;
}

int
darwin_nat_target::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 (this, ptid);
  struct gdbarch *gdbarch = regcache->arch ();
  CORE_ADDR pc;

  pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch);
  if (breakpoint_inserted_here_p (regcache->aspace (), pc))
    {
      inferior_debug (4, "cancel_breakpoint for thread 0x%lx\n",
		      (unsigned long) ptid.tid ());

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

      return 1;
    }
  return 0;
}

ptid_t
darwin_nat_target::wait_1 (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;

  inferior_debug
    (2, _("darwin_wait: waiting for a message ptid=%s\n"),
     ptid.to_string ().c_str ());

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

      darwin_inferior *priv = get_darwin_inferior (inf);

      status->set_stopped (GDB_SIGNAL_TRAP);
      thread = priv->threads[0];
      thread->msg_state = DARWIN_STOPPED;
      return ptid_t (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->set_ignore ();
	  return minus_one_ptid;
	}

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

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

      inferior *inf;
      res = decode_message (hdr, &thread, &inf, status);
      if (res == minus_one_ptid)
	continue;

      /* Early return in case an inferior has exited.  */
      if (inf == NULL)
	return res;
    }
  while (status->kind () == TARGET_WAITKIND_IGNORE);

  /* Stop all tasks.  */
  for (inferior *inf : all_inferiors (this))
    {
      darwin_suspend_inferior (inf);
      check_new_threads (inf);
    }

  /* 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=0x%x\n"), kret);
	  break;
	}

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

      inferior *inf;
      ptid2 = decode_message (hdr, &thread, &inf, &status2);

      if (inf != NULL && thread != NULL
	  && thread->event.ex_type == EXC_BREAKPOINT)
	{
	  if (thread->single_step
	      || cancel_breakpoint (ptid_t (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 0x%x hit a non-gdb breakpoint\n"),
	       thread->gdb_port);
	}
      else
	inferior_debug (3, _("darwin_wait: unhandled pending message\n"));
    }
  return res;
}

ptid_t
darwin_nat_target::wait (ptid_t ptid, struct target_waitstatus *status,
			 target_wait_flags options)
{
  return wait_1 (ptid, status);
}

void
darwin_nat_target::interrupt ()
{
  struct inferior *inf = current_inferior ();
  darwin_inferior *priv = get_darwin_inferior (inf);

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

/* Deallocate threads port and vector.  */

static void
darwin_deallocate_threads (struct inferior *inf)
{
  darwin_inferior *priv = get_darwin_inferior (inf);

  for (darwin_thread_t *t : priv->threads)
    {
      kern_return_t kret = mach_port_deallocate (gdb_task, t->gdb_port);
      MACH_CHECK_ERROR (kret);
    }

  priv->threads.clear ();
}

void
darwin_nat_target::mourn_inferior ()
{
  struct inferior *inf = current_inferior ();
  darwin_inferior *priv = get_darwin_inferior (inf);
  kern_return_t kret;
  mach_port_t prev;

  /* Deallocate threads.  */
  darwin_deallocate_threads (inf);

  /* Remove notify_port from darwin_port_set.  */
  kret = mach_port_move_member (gdb_task,
				priv->notify_port, MACH_PORT_NULL);
  MACH_CHECK_ERROR (kret);

  /* Remove task port dead_name notification.  */
  kret = mach_port_request_notification (gdb_task, priv->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=0x%x, prev=0x%x, notify_port=0x%x\n",
		  priv->task, prev, priv->notify_port);

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

  /* Destroy notify_port.  */
  kret = mach_port_destroy (gdb_task, priv->notify_port);
  MACH_CHECK_ERROR (kret);

  /* Deallocate saved exception ports.  */
  darwin_deallocate_exception_ports (priv);

  /* Deallocate task port.  */
  kret = mach_port_deallocate (gdb_task, priv->task);
  MACH_CHECK_ERROR (kret);

  inf->priv = NULL;

  inf_child_target::mourn_inferior ();
}

static void
darwin_reply_to_all_pending_messages (struct inferior *inf)
{
  darwin_inferior *priv = get_darwin_inferior (inf);

  for (darwin_thread_t *t : priv->threads)
    {
      if (t->msg_state == DARWIN_MESSAGE)
	darwin_resume_thread (inf, t, 0, 0);
    }
}

void
darwin_nat_target::stop_inferior (inferior *inf)
{
  struct target_waitstatus wstatus;
  ptid_t ptid;
  int res;
  darwin_inferior *priv = get_darwin_inferior (inf);

  gdb_assert (inf != NULL);

  darwin_suspend_inferior (inf);

  darwin_reply_to_all_pending_messages (inf);

  if (priv->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 = wait_1 (ptid_t (inf->pid), &wstatus);
      if (wstatus.kind () == TARGET_WAITKIND_STOPPED
	  && wstatus.sig () == GDB_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;
}

/* Deallocate saved exception ports.  */

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

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

static void
darwin_setup_exceptions (struct inferior *inf)
{
  darwin_inferior *priv = get_darwin_inferior (inf);
  kern_return_t kret;
  exception_mask_t mask;

  kret = darwin_save_exception_ports (priv);
  if (kret != KERN_SUCCESS)
    error (_("Unable to save exception ports, task_get_exception_ports"
	     "returned: %d"),
	   kret);

  /* Set exception port.  */
  if (enable_mach_exceptions)
    mask = EXC_MASK_ALL;
  else
    mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
  kret = task_set_exception_ports (priv->task, mask, darwin_ex_port,
				   EXCEPTION_DEFAULT, THREAD_STATE_NONE);
  if (kret != KERN_SUCCESS)
    error (_("Unable to set exception ports, task_set_exception_ports"
	     "returned: %d"),
	   kret);
}

void
darwin_nat_target::kill ()
{
  struct inferior *inf = current_inferior ();
  darwin_inferior *priv = get_darwin_inferior (inf);
  struct target_waitstatus wstatus;
  ptid_t ptid;
  kern_return_t kret;
  int res;

  if (inferior_ptid == null_ptid)
    return;

  gdb_assert (inf != NULL);

  kret = darwin_restore_exception_ports (priv);
  MACH_CHECK_ERROR (kret);

  darwin_reply_to_all_pending_messages (inf);

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

  if (res == 0)
    {
      /* On MacOS version Sierra, the darwin_restore_exception_ports call
	 does not work as expected.
	 When the kill function is called, the SIGKILL signal is received
	 by gdb whereas it should have been received by the kernel since
	 the exception ports have been restored.
	 This behavior is not the expected one thus gdb does not reply to
	 the received SIGKILL message. This situation leads to a "busy"
	 resource from the kernel point of view and the inferior is never
	 released, causing it to remain as a zombie process, even after
	 GDB exits.
	 To work around this, we mark all the threads of the inferior as
	 signaled thus darwin_decode_message function knows that the kill
	 signal was sent by gdb and will take the appropriate action
	 (cancel signal and reply to the signal message).  */
      for (darwin_thread_t *thread : priv->threads)
	thread->signaled = 1;

      darwin_resume_inferior (inf);

      ptid = wait_1 (ptid_t (inf->pid), &wstatus);
    }
  else if (errno != ESRCH)
    warning (_("Failed to kill inferior: kill (%d, 9) returned [%s]"),
	     inf->pid, safe_strerror (errno));

  target_mourn_inferior (ptid_t (inf->pid));
}

static void
darwin_setup_request_notification (struct inferior *inf)
{
  darwin_inferior *priv = get_darwin_inferior (inf);
  kern_return_t kret;
  mach_port_t prev_not;

  kret = mach_port_request_notification (gdb_task, priv->task,
					 MACH_NOTIFY_DEAD_NAME, 0,
					 priv->notify_port,
					 MACH_MSG_TYPE_MAKE_SEND_ONCE,
					 &prev_not);
  if (kret != KERN_SUCCESS)
    error (_("Termination notification request failed, "
	     "mach_port_request_notification\n"
	     "returned: %d"),
	   kret);
  if (prev_not != MACH_PORT_NULL)
    {
      /* This is unexpected, as there should not be any previously
	 registered notification request.  But this is not a fatal
	 issue, so just emit a warning.  */
      warning (_("\
A task termination request was registered before the debugger registered\n\
its own.  This is unexpected, but should otherwise not have any actual\n\
impact on the debugging session."));
    }
}

static void
darwin_attach_pid (struct inferior *inf)
{
  kern_return_t kret;

  darwin_inferior *priv = new darwin_inferior;
  inf->priv.reset (priv);

  try
    {
      kret = task_for_pid (gdb_task, inf->pid, &priv->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"),
		      priv->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);
	  if (kret != KERN_SUCCESS)
	    error (_("Unable to create exception port, mach_port_allocate "
		     "returned: %d"),
		   kret);

	  kret = mach_port_insert_right (gdb_task, darwin_ex_port,
					 darwin_ex_port,
					 MACH_MSG_TYPE_MAKE_SEND);
	  if (kret != KERN_SUCCESS)
	    error (_("Unable to create exception port, mach_port_insert_right "
		     "returned: %d"),
		   kret);

	  /* Create a port set and put ex_port in it.  */
	  kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_PORT_SET,
				     &darwin_port_set);
	  if (kret != KERN_SUCCESS)
	    error (_("Unable to create port set, mach_port_allocate "
		     "returned: %d"),
		   kret);

	  kret = mach_port_move_member (gdb_task, darwin_ex_port,
					darwin_port_set);
	  if (kret != KERN_SUCCESS)
	    error (_("Unable to move exception port into new port set, "
		     "mach_port_move_member\n"
		     "returned: %d"),
		   kret);
	}

      /* Create a port to be notified when the child task terminates.  */
      kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
				 &priv->notify_port);
      if (kret != KERN_SUCCESS)
	error (_("Unable to create notification port, mach_port_allocate "
		 "returned: %d"),
	       kret);

      kret = mach_port_move_member (gdb_task,
				    priv->notify_port, darwin_port_set);
      if (kret != KERN_SUCCESS)
	error (_("Unable to move notification port into new port set, "
		 "mach_port_move_member\n"
		 "returned: %d"),
	       kret);

      darwin_setup_request_notification (inf);

      darwin_setup_exceptions (inf);
    }
  catch (const gdb_exception &ex)
    {
      exit_inferior (inf);
      switch_to_no_thread ();

      throw;
    }

  target_ops *darwin_ops = get_native_target ();
  if (!inf->target_is_pushed (darwin_ops))
    inf->push_target (darwin_ops);
}

/* Get the thread_info object corresponding to this darwin_thread_info.  */

static struct thread_info *
thread_info_from_private_thread_info (darwin_thread_info *pti)
{
  for (struct thread_info *it : all_threads ())
    {
      darwin_thread_info *iter_pti = get_darwin_thread_info (it);

      if (iter_pti->gdb_port == pti->gdb_port)
	return it;
    }

  gdb_assert_not_reached ("did not find gdb thread for darwin thread");
}

void
darwin_nat_target::init_thread_list (inferior *inf)
{
  check_new_threads (inf);

  darwin_inferior *priv = get_darwin_inferior (inf);

  gdb_assert (!priv->threads.empty ());

  darwin_thread_info *first_pti = priv->threads.front ();
  struct thread_info *first_thread
    = thread_info_from_private_thread_info (first_pti);

  switch_to_thread (first_thread);
}

/* 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.  */
  if (close (ptrace_fds[1]) < 0)
    trace_start_error_with_name ("close");

  /* Wait until gdb is ready.  */
  res = read (ptrace_fds[0], &c, 1);
  if (res != 0)
    trace_start_error (_("unable to read from pipe, read returned: %d"), res);

  if (close (ptrace_fds[0]) < 0)
    trace_start_error_with_name ("close");

  /* Get rid of privileges.  */
  if (setegid (getgid ()) < 0)
    trace_start_error_with_name ("setegid");

  /* Set TRACEME.  */
  if (PTRACE (PT_TRACE_ME, 0, 0, 0) < 0)
    trace_start_error_with_name ("PTRACE");

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

/* 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));
    }

  mark_fd_no_cloexec (ptrace_fds[0]);
  mark_fd_no_cloexec (ptrace_fds[1]);
}

void
darwin_nat_target::ptrace_him (int pid)
{
  struct inferior *inf = current_inferior ();

  darwin_attach_pid (inf);

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

  unmark_fd_no_cloexec (ptrace_fds[0]);
  unmark_fd_no_cloexec (ptrace_fds[1]);

  init_thread_list (inf);

  gdb_startup_inferior (pid, 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)
    {
      gdb_printf
	(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)
    {
      gdb_printf (gdb_stderr, "Cannot set posix_spawn flags\n");
      return;
    }

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

/* Read kernel version, and return TRUE if this host may have System
   Integrity Protection (Sierra or later).  */

static bool
may_have_sip ()
{
  char str[16];
  size_t sz = sizeof (str);
  int ret;

  ret = sysctlbyname ("kern.osrelease", str, &sz, NULL, 0);
  if (ret == 0 && sz < sizeof (str))
    {
      unsigned long ver = strtoul (str, NULL, 10);
      if (ver >= 16)
	return true;
    }
  return false;
}

/* A helper for maybe_cache_shell.  This copies the shell to the
   cache.  It will throw an exception on any failure.  */

static void
copy_shell_to_cache (const char *shell, const std::string &new_name)
{
  scoped_fd from_fd = gdb_open_cloexec (shell, O_RDONLY, 0);
  if (from_fd.get () < 0)
    error (_("Could not open shell (%s) for reading: %s"),
	   shell, safe_strerror (errno));

  std::string new_dir = ldirname (new_name.c_str ());
  if (!mkdir_recursive (new_dir.c_str ()))
    error (_("Could not make cache directory \"%s\": %s"),
	   new_dir.c_str (), safe_strerror (errno));

  gdb::char_vector temp_name = make_temp_filename (new_name);
  scoped_fd to_fd = gdb_mkostemp_cloexec (&temp_name[0]);
  gdb::unlinker unlink_file_on_error (temp_name.data ());

  if (to_fd.get () < 0)
    error (_("Could not open temporary file \"%s\" for writing: %s"),
	   temp_name.data (), safe_strerror (errno));

  if (fcopyfile (from_fd.get (), to_fd.get (), nullptr,
		 COPYFILE_STAT | COPYFILE_DATA) != 0)
    error (_("Could not copy shell to cache as \"%s\": %s"),
	   temp_name.data (), safe_strerror (errno));

  /* Be sure that the caching is atomic so that we don't get bad
     results from multiple copies of gdb running at the same time.  */
  if (rename (temp_name.data (), new_name.c_str ()) != 0)
    error (_("Could not rename shell cache file to \"%s\": %s"),
	   new_name.c_str (), safe_strerror (errno));

  unlink_file_on_error.keep ();
}

/* If $SHELL is restricted, try to cache a copy.  Starting with El
   Capitan, macOS introduced System Integrity Protection.  Among other
   things, this prevents certain executables from being ptrace'd.  In
   particular, executables in /bin, like most shells, are affected.
   To work around this, while preserving command-line glob expansion
   and redirections, gdb will cache a copy of the shell.  Return true
   if all is well -- either the shell is not subject to SIP or it has
   been successfully cached.  Returns false if something failed.  */

static bool
maybe_cache_shell ()
{
  /* SF_RESTRICTED is defined in sys/stat.h and lets us determine if a
     given file is subject to SIP.  */
#ifdef SF_RESTRICTED

  /* If a check fails we want to revert -- maybe the user deleted the
     cache while gdb was running, or something like that.  */
  copied_shell = nullptr;

  const char *shell = get_shell ();
  if (!IS_ABSOLUTE_PATH (shell))
    {
      warning (_("This version of macOS has System Integrity Protection.\n\
Normally gdb would try to work around this by caching a copy of your shell,\n\
but because your shell (%s) is not an absolute path, this is being skipped."),
	       shell);
      return false;
    }

  struct stat sb;
  if (stat (shell, &sb) < 0)
    {
      warning (_("This version of macOS has System Integrity Protection.\n\
Normally gdb would try to work around this by caching a copy of your shell,\n\
but because gdb could not stat your shell (%s), this is being skipped.\n\
The error was: %s"),
	       shell, safe_strerror (errno));
      return false;
    }

  if ((sb.st_flags & SF_RESTRICTED) == 0)
    return true;

  /* Put the copy somewhere like ~/Library/Caches/gdb/bin/sh.  */
  std::string new_name = get_standard_cache_dir ();
  /* There's no need to insert a directory separator here, because
     SHELL is known to be absolute.  */
  new_name.append (shell);

  /* Maybe it was cached by some earlier gdb.  */
  if (stat (new_name.c_str (), &sb) != 0 || !S_ISREG (sb.st_mode))
    {
      try
	{
	  copy_shell_to_cache (shell, new_name);
	}
      catch (const gdb_exception_error &ex)
	{
	  warning (_("This version of macOS has System Integrity Protection.\n\
Because `startup-with-shell' is enabled, gdb tried to work around SIP by\n\
caching a copy of your shell.  However, this failed:\n\
%s\n\
If you correct the problem, gdb will automatically try again the next time\n\
you \"run\".  To prevent these attempts, you can use:\n\
    set startup-with-shell off"),
		   ex.what ());
	  return false;
	}

      gdb_printf (_("Note: this version of macOS has System Integrity Protection.\n\
Because `startup-with-shell' is enabled, gdb has worked around this by\n\
caching a copy of your shell.  The shell used by \"run\" is now:\n\
    %s\n"),
		  new_name.c_str ());
    }

  /* We need to make sure that the new name has the correct lifetime.  */
  static std::string saved_shell = std::move (new_name);
  copied_shell = saved_shell.c_str ();

#endif /* SF_RESTRICTED */

  return true;
}

void
darwin_nat_target::create_inferior (const char *exec_file,
				    const std::string &allargs,
				    char **env, int from_tty)
{
  gdb::optional<scoped_restore_tmpl<bool>> restore_startup_with_shell;
  darwin_nat_target *the_target = this;

  if (startup_with_shell && may_have_sip ())
    {
      if (!maybe_cache_shell ())
	{
	  warning (_("startup-with-shell is now temporarily disabled"));
	  restore_startup_with_shell.emplace (&startup_with_shell, 0);
	}
    }

  /* Do the hard work.  */
  fork_inferior (exec_file, allargs, env, darwin_ptrace_me,
		 [the_target] (int pid)
		   {
		     the_target->ptrace_him (pid);
		   },
		 darwin_pre_ptrace, copied_shell,
		 darwin_execvp);
}


/* Set things up such that the next call to darwin_wait will immediately
   return a fake stop event for inferior INF.

   This assumes that the inferior's thread list has been initialized,
   as it will suspend the inferior's first thread.  */

static void
darwin_setup_fake_stop_event (struct inferior *inf)
{
  darwin_inferior *priv = get_darwin_inferior (inf);
  darwin_thread_t *thread;
  kern_return_t kret;

  gdb_assert (darwin_inf_fake_stop == NULL);
  darwin_inf_fake_stop = inf;

  /* When detecting a fake pending stop event, darwin_wait returns
     an event saying that the first thread is in a DARWIN_STOPPED
     state.  To make that accurate, we need to suspend that thread
     as well.  Otherwise, we'll try resuming it when resuming the
     inferior, and get a warning because the thread's suspend count
     is already zero, making the resume request useless.  */
  thread = priv->threads[0];
  kret = thread_suspend (thread->gdb_port);
  MACH_CHECK_ERROR (kret);
}

/* Attach to process PID, then initialize for debugging it
   and wait for the trace-trap that results from attaching.  */
void
darwin_nat_target::attach (const char *args, int from_tty)
{
  pid_t pid;
  struct inferior *inf;

  pid = parse_pid_to_attach (args);

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

  target_announce_attach (from_tty, pid);

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

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

  darwin_attach_pid (inf);

  darwin_suspend_inferior (inf);

  init_thread_list (inf);

  darwin_inferior *priv = get_darwin_inferior (inf);

  darwin_check_osabi (priv, inferior_ptid.tid ());

  darwin_setup_fake_stop_event (inf);

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

void
darwin_nat_target::detach (inferior *inf, int from_tty)
{
  darwin_inferior *priv = get_darwin_inferior (inf);
  kern_return_t kret;
  int res;

  /* Display message.  */
  target_announce_detach (from_tty);

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

  kret = darwin_restore_exception_ports (priv);
  MACH_CHECK_ERROR (kret);

  if (!priv->no_ptrace)
    {
      res = PTRACE (PT_DETACH, inf->pid, 0, 0);
      if (res != 0)
	warning (_("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 (priv->no_ptrace)
    darwin_resume_inferior (inf);

  mourn_inferior ();
}

std::string
darwin_nat_target::pid_to_str (ptid_t ptid)
{
  long tid = ptid.tid ();

  if (tid != 0)
    return string_printf (_("Thread 0x%lx of process %u"),
			  tid, ptid.pid ());

  return normal_pid_to_str (ptid);
}

bool
darwin_nat_target::thread_alive (ptid_t ptid)
{
  return true;
}

/* 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 / written otherwise.  */

static int
darwin_read_write_inferior (task_t task, CORE_ADDR addr,
			    gdb_byte *rdaddr, const gdb_byte *wraddr,
			    ULONGEST length)
{
  kern_return_t kret;
  mach_vm_size_t res_length = 0;

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

  /* First read.  */
  if (rdaddr != NULL)
    {
      mach_vm_size_t count;

      /* According to target.h(to_xfer_partial), one and only one may be
	 non-null.  */
      gdb_assert (wraddr == NULL);

      kret = mach_vm_read_overwrite (task, addr, length,
				     (mach_vm_address_t) rdaddr, &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;
	}
      return count;
    }

  /* See above.  */
  gdb_assert (wraddr != NULL);

  while (length != 0)
    {
      mach_vm_address_t offset = addr & (mach_page_size - 1);
      mach_vm_address_t region_address = (mach_vm_address_t) (addr - offset);
      mach_vm_size_t aligned_length =
	(mach_vm_size_t) PAGE_ROUND (offset + length);
      vm_region_submap_short_info_data_64_t info;
      mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
      natural_t region_depth = 1000;
      mach_vm_address_t region_start = region_address;
      mach_vm_size_t region_length;
      mach_vm_size_t write_length;

      /* Read page protection.  */
      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));
	  return res_length;
	}

      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);
	  return res_length;
	}

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

      /* Make the pages RW.  */
      if (!(info.protection & VM_PROT_WRITE))
	{
	  vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;

	  kret = mach_vm_protect (task, region_address, region_length,
				  FALSE, prot);
	  if (kret != KERN_SUCCESS)
	    {
	      prot |= VM_PROT_COPY;
	      kret = mach_vm_protect (task, region_address, region_length,
				      FALSE, prot);
	    }
	  if (kret != KERN_SUCCESS)
	    {
	      warning (_("darwin_read_write_inferior: "
			 "mach_vm_protect failed at %s "
			 "(len=0x%lx, prot=0x%x): %s"),
		       core_addr_to_string (region_address),
		       (unsigned long) region_length, (unsigned) prot,
		       mach_error_string (kret));
	      return res_length;
	    }
	}

      if (offset + length > region_length)
	write_length = region_length - offset;
      else
	write_length = length;

      /* Write.  */
      kret = mach_vm_write (task, addr, (vm_offset_t) wraddr, write_length);
      if (kret != KERN_SUCCESS)
	{
	  warning (_("darwin_read_write_inferior: mach_vm_write failed: %s"),
		   mach_error_string (kret));
	  return res_length;
	}

      /* Restore page rights.  */
      if (!(info.protection & VM_PROT_WRITE))
	{
	  kret = mach_vm_protect (task, region_address, region_length,
				  FALSE, info.protection);
	  if (kret != KERN_SUCCESS)
	    {
	      warning (_("darwin_read_write_inferior: "
			 "mach_vm_protect restore failed at %s "
			 "(len=0x%lx): %s"),
		       core_addr_to_string (region_address),
		       (unsigned long) region_length,
		       mach_error_string (kret));
	    }
	}

      addr += write_length;
      wraddr += write_length;
      res_length += write_length;
      length -= write_length;
    }

  return res_length;
}

/* Read LENGTH bytes at offset ADDR of task_dyld_info for TASK, and copy them
   to RDADDR (in big endian).
   Return 0 on failure; number of bytes read / written otherwise.  */

#ifdef TASK_DYLD_INFO_COUNT
/* This is not available in Darwin 9.  */
static enum target_xfer_status
darwin_read_dyld_info (task_t task, CORE_ADDR addr, gdb_byte *rdaddr,
		       ULONGEST length, ULONGEST *xfered_len)
{
  struct task_dyld_info task_dyld_info;
  mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
  kern_return_t kret;

  if (addr != 0 || length > sizeof (mach_vm_address_t))
    return TARGET_XFER_EOF;

  kret = task_info (task, TASK_DYLD_INFO,
		    (task_info_t) &task_dyld_info, &count);
  MACH_CHECK_ERROR (kret);
  if (kret != KERN_SUCCESS)
    return TARGET_XFER_E_IO;

  store_unsigned_integer (rdaddr, length, BFD_ENDIAN_BIG,
			  task_dyld_info.all_image_info_addr);
  *xfered_len = (ULONGEST) length;
  return TARGET_XFER_OK;
}
#endif



enum target_xfer_status
darwin_nat_target::xfer_partial (enum target_object object, const char *annex,
				 gdb_byte *readbuf, const gdb_byte *writebuf,
				 ULONGEST offset, ULONGEST len,
				 ULONGEST *xfered_len)
{
  struct inferior *inf = current_inferior ();
  darwin_inferior *priv = get_darwin_inferior (inf);

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

  switch (object)
    {
    case TARGET_OBJECT_MEMORY:
      {
	int l = darwin_read_write_inferior (priv->task, offset,
					    readbuf, writebuf, len);

	if (l == 0)
	  return TARGET_XFER_EOF;
	else
	  {
	    gdb_assert (l > 0);
	    *xfered_len = (ULONGEST) l;
	    return TARGET_XFER_OK;
	  }
      }
#ifdef TASK_DYLD_INFO_COUNT
    case TARGET_OBJECT_DARWIN_DYLD_INFO:
      if (writebuf != NULL || readbuf == NULL)
	{
	  /* Support only read.  */
	  return TARGET_XFER_E_IO;
	}
      return darwin_read_dyld_info (priv->task, offset, readbuf, len,
				    xfered_len);
#endif
    default:
      return TARGET_XFER_E_IO;
    }

}

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

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

const char *
darwin_nat_target::pid_to_exec_file (int pid)
{
  static char path[PATH_MAX];
  int res;

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

ptid_t
darwin_nat_target::get_ada_task_ptid (long lwp, ULONGEST thread)
{
  struct inferior *inf = current_inferior ();
  darwin_inferior *priv = get_darwin_inferior (inf);
  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 (darwin_thread_t *t : priv->threads)
    {
      if (t->inf_port == lwp)
	return ptid_t (inferior_ptid.pid (), 0, t->gdb_port);
    }

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

  /* First get inferior port names.  */
  kret = mach_port_names (priv->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 (int 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 (priv->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 (darwin_thread_t *t : priv->threads)
	{
	  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_t (current_inferior ()->pid, 0, res);
  else
    return null_ptid;
}

bool
darwin_nat_target::supports_multi_process ()
{
  return true;
}

void _initialize_darwin_nat ();
void
_initialize_darwin_nat ()
{
  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);
    }

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

  add_setshow_zuinteger_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);
}
