/* Native-dependent code for FreeBSD.

   Copyright (C) 2002-2023 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 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 "gdbsupport/block-signals.h"
#include "gdbsupport/byte-vector.h"
#include "gdbsupport/event-loop.h"
#include "gdbcore.h"
#include "inferior.h"
#include "regcache.h"
#include "regset.h"
#include "gdbarch.h"
#include "gdbcmd.h"
#include "gdbthread.h"
#include "gdbsupport/buildargv.h"
#include "gdbsupport/gdb_wait.h"
#include "inf-loop.h"
#include "inf-ptrace.h"
#include <sys/types.h>
#ifdef HAVE_SYS_PROCCTL_H
#include <sys/procctl.h>
#endif
#include <sys/procfs.h>
#include <sys/ptrace.h>
#include <sys/signal.h>
#include <sys/sysctl.h>
#include <sys/user.h>
#include <libutil.h>

#include "elf-bfd.h"
#include "fbsd-nat.h"
#include "fbsd-tdep.h"

#ifndef PT_GETREGSET
#define	PT_GETREGSET	42	/* Get a target register set */
#define	PT_SETREGSET	43	/* Set a target register set */
#endif

/* Information stored about each inferior.  */
struct fbsd_inferior : public private_inferior
{
  /* Filter for resumed LWPs which can report events from wait.  */
  ptid_t resumed_lwps = null_ptid;

  /* Number of LWPs this process contains.  */
  unsigned int num_lwps = 0;

  /* Number of LWPs currently running.  */
  unsigned int running_lwps = 0;

  /* Have a pending SIGSTOP event that needs to be discarded.  */
  bool pending_sigstop = false;
};

/* Return the fbsd_inferior attached to INF.  */

static inline fbsd_inferior *
get_fbsd_inferior (inferior *inf)
{
  return gdb::checked_static_cast<fbsd_inferior *> (inf->priv.get ());
}

/* See fbsd-nat.h.  */

void
fbsd_nat_target::add_pending_event (const ptid_t &ptid,
				    const target_waitstatus &status)
{
  gdb_assert (find_inferior_ptid (this, ptid) != nullptr);
  m_pending_events.emplace_back (ptid, status);
}

/* See fbsd-nat.h.  */

bool
fbsd_nat_target::have_pending_event (ptid_t filter)
{
  for (const pending_event &event : m_pending_events)
    if (event.ptid.matches (filter))
      return true;
  return false;
}

/* See fbsd-nat.h.  */

gdb::optional<fbsd_nat_target::pending_event>
fbsd_nat_target::take_pending_event (ptid_t filter)
{
  for (auto it = m_pending_events.begin (); it != m_pending_events.end (); it++)
    if (it->ptid.matches (filter))
      {
	inferior *inf = find_inferior_ptid (this, it->ptid);
	fbsd_inferior *fbsd_inf = get_fbsd_inferior (inf);
	if (it->ptid.matches (fbsd_inf->resumed_lwps))
	  {
	    pending_event event = *it;
	    m_pending_events.erase (it);
	    return event;
	  }
      }
  return {};
}

/* Return the name of a file that can be opened to get the symbols for
   the child process identified by PID.  */

const char *
fbsd_nat_target::pid_to_exec_file (int pid)
{
  static char buf[PATH_MAX];
  size_t buflen;
  int mib[4];

  mib[0] = CTL_KERN;
  mib[1] = KERN_PROC;
  mib[2] = KERN_PROC_PATHNAME;
  mib[3] = pid;
  buflen = sizeof buf;
  if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0)
    /* The kern.proc.pathname.<pid> sysctl returns a length of zero
       for processes without an associated executable such as kernel
       processes.  */
    return buflen == 0 ? NULL : buf;

  return NULL;
}

/* Iterate over all the memory regions in the current inferior,
   calling FUNC for each memory region.  DATA is passed as the last
   argument to FUNC.  */

int
fbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
				      void *data)
{
  pid_t pid = inferior_ptid.pid ();
  struct kinfo_vmentry *kve;
  uint64_t size;
  int i, nitems;

  gdb::unique_xmalloc_ptr<struct kinfo_vmentry>
    vmentl (kinfo_getvmmap (pid, &nitems));
  if (vmentl == NULL)
    perror_with_name (_("Couldn't fetch VM map entries"));

  for (i = 0, kve = vmentl.get (); i < nitems; i++, kve++)
    {
      /* Skip unreadable segments and those where MAP_NOCORE has been set.  */
      if (!(kve->kve_protection & KVME_PROT_READ)
	  || kve->kve_flags & KVME_FLAG_NOCOREDUMP)
	continue;

      /* Skip segments with an invalid type.  */
      if (kve->kve_type != KVME_TYPE_DEFAULT
	  && kve->kve_type != KVME_TYPE_VNODE
	  && kve->kve_type != KVME_TYPE_SWAP
	  && kve->kve_type != KVME_TYPE_PHYS)
	continue;

      size = kve->kve_end - kve->kve_start;
      if (info_verbose)
	{
	  gdb_printf ("Save segment, %ld bytes at %s (%c%c%c)\n",
		      (long) size,
		      paddress (target_gdbarch (), kve->kve_start),
		      kve->kve_protection & KVME_PROT_READ ? 'r' : '-',
		      kve->kve_protection & KVME_PROT_WRITE ? 'w' : '-',
		      kve->kve_protection & KVME_PROT_EXEC ? 'x' : '-');
	}

      /* Invoke the callback function to create the corefile segment.
	 Pass MODIFIED as true, we do not know the real modification state.  */
      func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ,
	    kve->kve_protection & KVME_PROT_WRITE,
	    kve->kve_protection & KVME_PROT_EXEC, 1, false, data);
    }
  return 0;
}

/* Fetch the command line for a running process.  */

static gdb::unique_xmalloc_ptr<char>
fbsd_fetch_cmdline (pid_t pid)
{
  size_t len;
  int mib[4];

  len = 0;
  mib[0] = CTL_KERN;
  mib[1] = KERN_PROC;
  mib[2] = KERN_PROC_ARGS;
  mib[3] = pid;
  if (sysctl (mib, 4, NULL, &len, NULL, 0) == -1)
    return nullptr;

  if (len == 0)
    return nullptr;

  gdb::unique_xmalloc_ptr<char> cmdline ((char *) xmalloc (len));
  if (sysctl (mib, 4, cmdline.get (), &len, NULL, 0) == -1)
    return nullptr;

  /* Join the arguments with spaces to form a single string.  */
  char *cp = cmdline.get ();
  for (size_t i = 0; i < len - 1; i++)
    if (cp[i] == '\0')
      cp[i] = ' ';
  cp[len - 1] = '\0';

  return cmdline;
}

/* Fetch the external variant of the kernel's internal process
   structure for the process PID into KP.  */

static bool
fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp)
{
  size_t len;
  int mib[4];

  len = sizeof *kp;
  mib[0] = CTL_KERN;
  mib[1] = KERN_PROC;
  mib[2] = KERN_PROC_PID;
  mib[3] = pid;
  return (sysctl (mib, 4, kp, &len, NULL, 0) == 0);
}

/* Implement the "info_proc" target_ops method.  */

bool
fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
{
  gdb::unique_xmalloc_ptr<struct kinfo_file> fdtbl;
  int nfd = 0;
  struct kinfo_proc kp;
  pid_t pid;
  bool do_cmdline = false;
  bool do_cwd = false;
  bool do_exe = false;
  bool do_files = false;
  bool do_mappings = false;
  bool do_status = false;

  switch (what)
    {
    case IP_MINIMAL:
      do_cmdline = true;
      do_cwd = true;
      do_exe = true;
      break;
    case IP_MAPPINGS:
      do_mappings = true;
      break;
    case IP_STATUS:
    case IP_STAT:
      do_status = true;
      break;
    case IP_CMDLINE:
      do_cmdline = true;
      break;
    case IP_EXE:
      do_exe = true;
      break;
    case IP_CWD:
      do_cwd = true;
      break;
    case IP_FILES:
      do_files = true;
      break;
    case IP_ALL:
      do_cmdline = true;
      do_cwd = true;
      do_exe = true;
      do_files = true;
      do_mappings = true;
      do_status = true;
      break;
    default:
      error (_("Not supported on this target."));
    }

  gdb_argv built_argv (args);
  if (built_argv.count () == 0)
    {
      pid = inferior_ptid.pid ();
      if (pid == 0)
	error (_("No current process: you must name one."));
    }
  else if (built_argv.count () == 1 && isdigit (built_argv[0][0]))
    pid = strtol (built_argv[0], NULL, 10);
  else
    error (_("Invalid arguments."));

  gdb_printf (_("process %d\n"), pid);
  if (do_cwd || do_exe || do_files)
    fdtbl.reset (kinfo_getfile (pid, &nfd));

  if (do_cmdline)
    {
      gdb::unique_xmalloc_ptr<char> cmdline = fbsd_fetch_cmdline (pid);
      if (cmdline != nullptr)
	gdb_printf ("cmdline = '%s'\n", cmdline.get ());
      else
	warning (_("unable to fetch command line"));
    }
  if (do_cwd)
    {
      const char *cwd = NULL;
      struct kinfo_file *kf = fdtbl.get ();
      for (int i = 0; i < nfd; i++, kf++)
	{
	  if (kf->kf_type == KF_TYPE_VNODE && kf->kf_fd == KF_FD_TYPE_CWD)
	    {
	      cwd = kf->kf_path;
	      break;
	    }
	}
      if (cwd != NULL)
	gdb_printf ("cwd = '%s'\n", cwd);
      else
	warning (_("unable to fetch current working directory"));
    }
  if (do_exe)
    {
      const char *exe = NULL;
      struct kinfo_file *kf = fdtbl.get ();
      for (int i = 0; i < nfd; i++, kf++)
	{
	  if (kf->kf_type == KF_TYPE_VNODE && kf->kf_fd == KF_FD_TYPE_TEXT)
	    {
	      exe = kf->kf_path;
	      break;
	    }
	}
      if (exe == NULL)
	exe = pid_to_exec_file (pid);
      if (exe != NULL)
	gdb_printf ("exe = '%s'\n", exe);
      else
	warning (_("unable to fetch executable path name"));
    }
  if (do_files)
    {
      struct kinfo_file *kf = fdtbl.get ();

      if (nfd > 0)
	{
	  fbsd_info_proc_files_header ();
	  for (int i = 0; i < nfd; i++, kf++)
	    fbsd_info_proc_files_entry (kf->kf_type, kf->kf_fd, kf->kf_flags,
					kf->kf_offset, kf->kf_vnode_type,
					kf->kf_sock_domain, kf->kf_sock_type,
					kf->kf_sock_protocol, &kf->kf_sa_local,
					&kf->kf_sa_peer, kf->kf_path);
	}
      else
	warning (_("unable to fetch list of open files"));
    }
  if (do_mappings)
    {
      int nvment;
      gdb::unique_xmalloc_ptr<struct kinfo_vmentry>
	vmentl (kinfo_getvmmap (pid, &nvment));

      if (vmentl != nullptr)
	{
	  int addr_bit = TARGET_CHAR_BIT * sizeof (void *);
	  fbsd_info_proc_mappings_header (addr_bit);

	  struct kinfo_vmentry *kve = vmentl.get ();
	  for (int i = 0; i < nvment; i++, kve++)
	    fbsd_info_proc_mappings_entry (addr_bit, kve->kve_start,
					   kve->kve_end, kve->kve_offset,
					   kve->kve_flags, kve->kve_protection,
					   kve->kve_path);
	}
      else
	warning (_("unable to fetch virtual memory map"));
    }
  if (do_status)
    {
      if (!fbsd_fetch_kinfo_proc (pid, &kp))
	warning (_("Failed to fetch process information"));
      else
	{
	  const char *state;
	  int pgtok;

	  gdb_printf ("Name: %s\n", kp.ki_comm);
	  switch (kp.ki_stat)
	    {
	    case SIDL:
	      state = "I (idle)";
	      break;
	    case SRUN:
	      state = "R (running)";
	      break;
	    case SSTOP:
	      state = "T (stopped)";
	      break;
	    case SZOMB:
	      state = "Z (zombie)";
	      break;
	    case SSLEEP:
	      state = "S (sleeping)";
	      break;
	    case SWAIT:
	      state = "W (interrupt wait)";
	      break;
	    case SLOCK:
	      state = "L (blocked on lock)";
	      break;
	    default:
	      state = "? (unknown)";
	      break;
	    }
	  gdb_printf ("State: %s\n", state);
	  gdb_printf ("Parent process: %d\n", kp.ki_ppid);
	  gdb_printf ("Process group: %d\n", kp.ki_pgid);
	  gdb_printf ("Session id: %d\n", kp.ki_sid);
	  gdb_printf ("TTY: %s\n", pulongest (kp.ki_tdev));
	  gdb_printf ("TTY owner process group: %d\n", kp.ki_tpgid);
	  gdb_printf ("User IDs (real, effective, saved): %d %d %d\n",
		      kp.ki_ruid, kp.ki_uid, kp.ki_svuid);
	  gdb_printf ("Group IDs (real, effective, saved): %d %d %d\n",
		      kp.ki_rgid, kp.ki_groups[0], kp.ki_svgid);
	  gdb_printf ("Groups: ");
	  for (int i = 0; i < kp.ki_ngroups; i++)
	    gdb_printf ("%d ", kp.ki_groups[i]);
	  gdb_printf ("\n");
	  gdb_printf ("Minor faults (no memory page): %ld\n",
		      kp.ki_rusage.ru_minflt);
	  gdb_printf ("Minor faults, children: %ld\n",
		      kp.ki_rusage_ch.ru_minflt);
	  gdb_printf ("Major faults (memory page faults): %ld\n",
		      kp.ki_rusage.ru_majflt);
	  gdb_printf ("Major faults, children: %ld\n",
		      kp.ki_rusage_ch.ru_majflt);
	  gdb_printf ("utime: %s.%06ld\n",
		      plongest (kp.ki_rusage.ru_utime.tv_sec),
		      kp.ki_rusage.ru_utime.tv_usec);
	  gdb_printf ("stime: %s.%06ld\n",
		      plongest (kp.ki_rusage.ru_stime.tv_sec),
		      kp.ki_rusage.ru_stime.tv_usec);
	  gdb_printf ("utime, children: %s.%06ld\n",
		      plongest (kp.ki_rusage_ch.ru_utime.tv_sec),
		      kp.ki_rusage_ch.ru_utime.tv_usec);
	  gdb_printf ("stime, children: %s.%06ld\n",
		      plongest (kp.ki_rusage_ch.ru_stime.tv_sec),
		      kp.ki_rusage_ch.ru_stime.tv_usec);
	  gdb_printf ("'nice' value: %d\n", kp.ki_nice);
	  gdb_printf ("Start time: %s.%06ld\n",
		      plongest (kp.ki_start.tv_sec),
		      kp.ki_start.tv_usec);
	  pgtok = getpagesize () / 1024;
	  gdb_printf ("Virtual memory size: %s kB\n",
		      pulongest (kp.ki_size / 1024));
	  gdb_printf ("Data size: %s kB\n",
		      pulongest (kp.ki_dsize * pgtok));
	  gdb_printf ("Stack size: %s kB\n",
		      pulongest (kp.ki_ssize * pgtok));
	  gdb_printf ("Text size: %s kB\n",
		      pulongest (kp.ki_tsize * pgtok));
	  gdb_printf ("Resident set size: %s kB\n",
		      pulongest (kp.ki_rssize * pgtok));
	  gdb_printf ("Maximum RSS: %s kB\n",
		      pulongest (kp.ki_rusage.ru_maxrss));
	  gdb_printf ("Pending Signals: ");
	  for (int i = 0; i < _SIG_WORDS; i++)
	    gdb_printf ("%08x ", kp.ki_siglist.__bits[i]);
	  gdb_printf ("\n");
	  gdb_printf ("Ignored Signals: ");
	  for (int i = 0; i < _SIG_WORDS; i++)
	    gdb_printf ("%08x ", kp.ki_sigignore.__bits[i]);
	  gdb_printf ("\n");
	  gdb_printf ("Caught Signals: ");
	  for (int i = 0; i < _SIG_WORDS; i++)
	    gdb_printf ("%08x ", kp.ki_sigcatch.__bits[i]);
	  gdb_printf ("\n");
	}
    }

  return true;
}

/* Return the size of siginfo for the current inferior.  */

#ifdef __LP64__
union sigval32 {
  int sival_int;
  uint32_t sival_ptr;
};

/* This structure matches the naming and layout of `siginfo_t' in
   <sys/signal.h>.  In particular, the `si_foo' macros defined in that
   header can be used with both types to copy fields in the `_reason'
   union.  */

struct siginfo32
{
  int si_signo;
  int si_errno;
  int si_code;
  __pid_t si_pid;
  __uid_t si_uid;
  int si_status;
  uint32_t si_addr;
  union sigval32 si_value;
  union
  {
    struct
    {
      int _trapno;
    } _fault;
    struct
    {
      int _timerid;
      int _overrun;
    } _timer;
    struct
    {
      int _mqd;
    } _mesgq;
    struct
    {
      int32_t _band;
    } _poll;
    struct
    {
      int32_t __spare1__;
      int __spare2__[7];
    } __spare__;
  } _reason;
};
#endif

static size_t
fbsd_siginfo_size ()
{
#ifdef __LP64__
  struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());

  /* Is the inferior 32-bit?  If so, use the 32-bit siginfo size.  */
  if (gdbarch_long_bit (gdbarch) == 32)
    return sizeof (struct siginfo32);
#endif
  return sizeof (siginfo_t);
}

/* Convert a native 64-bit siginfo object to a 32-bit object.  Note
   that FreeBSD doesn't support writing to $_siginfo, so this only
   needs to convert one way.  */

static void
fbsd_convert_siginfo (siginfo_t *si)
{
#ifdef __LP64__
  struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());

  /* Is the inferior 32-bit?  If not, nothing to do.  */
  if (gdbarch_long_bit (gdbarch) != 32)
    return;

  struct siginfo32 si32;

  si32.si_signo = si->si_signo;
  si32.si_errno = si->si_errno;
  si32.si_code = si->si_code;
  si32.si_pid = si->si_pid;
  si32.si_uid = si->si_uid;
  si32.si_status = si->si_status;
  si32.si_addr = (uintptr_t) si->si_addr;

  /* If sival_ptr is being used instead of sival_int on a big-endian
     platform, then sival_int will be zero since it holds the upper
     32-bits of the pointer value.  */
#if _BYTE_ORDER == _BIG_ENDIAN
  if (si->si_value.sival_int == 0)
    si32.si_value.sival_ptr = (uintptr_t) si->si_value.sival_ptr;
  else
    si32.si_value.sival_int = si->si_value.sival_int;
#else
  si32.si_value.sival_int = si->si_value.sival_int;
#endif

  /* Always copy the spare fields and then possibly overwrite them for
     signal-specific or code-specific fields.  */
  si32._reason.__spare__.__spare1__ = si->_reason.__spare__.__spare1__;
  for (int i = 0; i < 7; i++)
    si32._reason.__spare__.__spare2__[i] = si->_reason.__spare__.__spare2__[i];
  switch (si->si_signo) {
  case SIGILL:
  case SIGFPE:
  case SIGSEGV:
  case SIGBUS:
    si32.si_trapno = si->si_trapno;
    break;
  }
  switch (si->si_code) {
  case SI_TIMER:
    si32.si_timerid = si->si_timerid;
    si32.si_overrun = si->si_overrun;
    break;
  case SI_MESGQ:
    si32.si_mqd = si->si_mqd;
    break;
  }

  memcpy(si, &si32, sizeof (si32));
#endif
}

/* Implement the "xfer_partial" target_ops method.  */

enum target_xfer_status
fbsd_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)
{
  pid_t pid = inferior_ptid.pid ();

  switch (object)
    {
    case TARGET_OBJECT_SIGNAL_INFO:
      {
	struct ptrace_lwpinfo pl;
	size_t siginfo_size;

	/* FreeBSD doesn't support writing to $_siginfo.  */
	if (writebuf != NULL)
	  return TARGET_XFER_E_IO;

	if (inferior_ptid.lwp_p ())
	  pid = inferior_ptid.lwp ();

	siginfo_size = fbsd_siginfo_size ();
	if (offset > siginfo_size)
	  return TARGET_XFER_E_IO;

	if (ptrace (PT_LWPINFO, pid, (PTRACE_TYPE_ARG3) &pl, sizeof (pl)) == -1)
	  return TARGET_XFER_E_IO;

	if (!(pl.pl_flags & PL_FLAG_SI))
	  return TARGET_XFER_E_IO;

	fbsd_convert_siginfo (&pl.pl_siginfo);
	if (offset + len > siginfo_size)
	  len = siginfo_size - offset;

	memcpy (readbuf, ((gdb_byte *) &pl.pl_siginfo) + offset, len);
	*xfered_len = len;
	return TARGET_XFER_OK;
      }
#ifdef KERN_PROC_AUXV
    case TARGET_OBJECT_AUXV:
      {
	gdb::byte_vector buf_storage;
	gdb_byte *buf;
	size_t buflen;
	int mib[4];

	if (writebuf != NULL)
	  return TARGET_XFER_E_IO;
	mib[0] = CTL_KERN;
	mib[1] = KERN_PROC;
	mib[2] = KERN_PROC_AUXV;
	mib[3] = pid;
	if (offset == 0)
	  {
	    buf = readbuf;
	    buflen = len;
	  }
	else
	  {
	    buflen = offset + len;
	    buf_storage.resize (buflen);
	    buf = buf_storage.data ();
	  }
	if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0)
	  {
	    if (offset != 0)
	      {
		if (buflen > offset)
		  {
		    buflen -= offset;
		    memcpy (readbuf, buf + offset, buflen);
		  }
		else
		  buflen = 0;
	      }
	    *xfered_len = buflen;
	    return (buflen == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
	  }
	return TARGET_XFER_E_IO;
      }
#endif
#if defined(KERN_PROC_VMMAP) && defined(KERN_PROC_PS_STRINGS)
    case TARGET_OBJECT_FREEBSD_VMMAP:
    case TARGET_OBJECT_FREEBSD_PS_STRINGS:
      {
	gdb::byte_vector buf_storage;
	gdb_byte *buf;
	size_t buflen;
	int mib[4];

	int proc_target;
	uint32_t struct_size;
	switch (object)
	  {
	  case TARGET_OBJECT_FREEBSD_VMMAP:
	    proc_target = KERN_PROC_VMMAP;
	    struct_size = sizeof (struct kinfo_vmentry);
	    break;
	  case TARGET_OBJECT_FREEBSD_PS_STRINGS:
	    proc_target = KERN_PROC_PS_STRINGS;
	    struct_size = sizeof (void *);
	    break;
	  }

	if (writebuf != NULL)
	  return TARGET_XFER_E_IO;

	mib[0] = CTL_KERN;
	mib[1] = KERN_PROC;
	mib[2] = proc_target;
	mib[3] = pid;

	if (sysctl (mib, 4, NULL, &buflen, NULL, 0) != 0)
	  return TARGET_XFER_E_IO;
	buflen += sizeof (struct_size);

	if (offset >= buflen)
	  {
	    *xfered_len = 0;
	    return TARGET_XFER_EOF;
	  }

	buf_storage.resize (buflen);
	buf = buf_storage.data ();

	memcpy (buf, &struct_size, sizeof (struct_size));
	buflen -= sizeof (struct_size);
	if (sysctl (mib, 4, buf + sizeof (struct_size), &buflen, NULL, 0) != 0)
	  return TARGET_XFER_E_IO;
	buflen += sizeof (struct_size);

	if (buflen - offset < len)
	  len = buflen - offset;
	memcpy (readbuf, buf + offset, len);
	*xfered_len = len;
	return TARGET_XFER_OK;
      }
#endif
    default:
      return inf_ptrace_target::xfer_partial (object, annex,
					      readbuf, writebuf, offset,
					      len, xfered_len);
    }
}

static bool debug_fbsd_lwp;
static bool debug_fbsd_nat;

static void
show_fbsd_lwp_debug (struct ui_file *file, int from_tty,
		     struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Debugging of FreeBSD lwp module is %s.\n"), value);
}

static void
show_fbsd_nat_debug (struct ui_file *file, int from_tty,
		     struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Debugging of FreeBSD native target is %s.\n"),
	      value);
}

#define fbsd_lwp_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (debug_fbsd_lwp, "fbsd-lwp", fmt, ##__VA_ARGS__)

#define fbsd_nat_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (debug_fbsd_nat, "fbsd-nat", fmt, ##__VA_ARGS__)

#define fbsd_nat_debug_start_end(fmt, ...) \
  scoped_debug_start_end (debug_fbsd_nat, "fbsd-nat", fmt, ##__VA_ARGS__)

/*
  FreeBSD's first thread support was via a "reentrant" version of libc
  (libc_r) that first shipped in 2.2.7.  This library multiplexed all
  of the threads in a process onto a single kernel thread.  This
  library was supported via the bsd-uthread target.

  FreeBSD 5.1 introduced two new threading libraries that made use of
  multiple kernel threads.  The first (libkse) scheduled M user
  threads onto N (<= M) kernel threads (LWPs).  The second (libthr)
  bound each user thread to a dedicated kernel thread.  libkse shipped
  as the default threading library (libpthread).

  FreeBSD 5.3 added a libthread_db to abstract the interface across
  the various thread libraries (libc_r, libkse, and libthr).

  FreeBSD 7.0 switched the default threading library from from libkse
  to libpthread and removed libc_r.

  FreeBSD 8.0 removed libkse and the in-kernel support for it.  The
  only threading library supported by 8.0 and later is libthr which
  ties each user thread directly to an LWP.  To simplify the
  implementation, this target only supports LWP-backed threads using
  ptrace directly rather than libthread_db.

  FreeBSD 11.0 introduced LWP event reporting via PT_LWP_EVENTS.
*/

/* Return true if PTID is still active in the inferior.  */

bool
fbsd_nat_target::thread_alive (ptid_t ptid)
{
  if (ptid.lwp_p ())
    {
      struct ptrace_lwpinfo pl;

      if (ptrace (PT_LWPINFO, ptid.lwp (), (caddr_t) &pl, sizeof pl)
	  == -1)
	{
	  /* EBUSY means the associated process is running which means
	     the LWP does exist and belongs to a running process.  */
	  if (errno == EBUSY)
	    return true;
	  return false;
	}
#ifdef PL_FLAG_EXITED
      if (pl.pl_flags & PL_FLAG_EXITED)
	return false;
#endif
    }

  return true;
}

/* Convert PTID to a string.  */

std::string
fbsd_nat_target::pid_to_str (ptid_t ptid)
{
  lwpid_t lwp;

  lwp = ptid.lwp ();
  if (lwp != 0)
    {
      int pid = ptid.pid ();

      return string_printf ("LWP %d of process %d", lwp, pid);
    }

  return normal_pid_to_str (ptid);
}

#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME
/* Return the name assigned to a thread by an application.  Returns
   the string in a static buffer.  */

const char *
fbsd_nat_target::thread_name (struct thread_info *thr)
{
  struct ptrace_lwpinfo pl;
  struct kinfo_proc kp;
  int pid = thr->ptid.pid ();
  long lwp = thr->ptid.lwp ();
  static char buf[sizeof pl.pl_tdname + 1];

  /* Note that ptrace_lwpinfo returns the process command in pl_tdname
     if a name has not been set explicitly.  Return a NULL name in
     that case.  */
  if (!fbsd_fetch_kinfo_proc (pid, &kp))
    return nullptr;
  if (ptrace (PT_LWPINFO, lwp, (caddr_t) &pl, sizeof pl) == -1)
    return nullptr;
  if (strcmp (kp.ki_comm, pl.pl_tdname) == 0)
    return NULL;
  xsnprintf (buf, sizeof buf, "%s", pl.pl_tdname);
  return buf;
}
#endif

/* Enable additional event reporting on new processes.

   To catch fork events, PTRACE_FORK is set on every traced process
   to enable stops on returns from fork or vfork.  Note that both the
   parent and child will always stop, even if system call stops are
   not enabled.

   To catch LWP events, PTRACE_EVENTS is set on every traced process.
   This enables stops on the birth for new LWPs (excluding the "main" LWP)
   and the death of LWPs (excluding the last LWP in a process).  Note
   that unlike fork events, the LWP that creates a new LWP does not
   report an event.  */

static void
fbsd_enable_proc_events (pid_t pid)
{
#ifdef PT_GET_EVENT_MASK
  int events;

  if (ptrace (PT_GET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3) &events,
	      sizeof (events)) == -1)
    perror_with_name (("ptrace (PT_GET_EVENT_MASK)"));
  events |= PTRACE_FORK | PTRACE_LWP;
#ifdef PTRACE_VFORK
  events |= PTRACE_VFORK;
#endif
  if (ptrace (PT_SET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3) &events,
	      sizeof (events)) == -1)
    perror_with_name (("ptrace (PT_SET_EVENT_MASK)"));
#else
#ifdef TDP_RFPPWAIT
  if (ptrace (PT_FOLLOW_FORK, pid, (PTRACE_TYPE_ARG3) 0, 1) == -1)
    perror_with_name (("ptrace (PT_FOLLOW_FORK)"));
#endif
#ifdef PT_LWP_EVENTS
  if (ptrace (PT_LWP_EVENTS, pid, (PTRACE_TYPE_ARG3) 0, 1) == -1)
    perror_with_name (("ptrace (PT_LWP_EVENTS)"));
#endif
#endif
}

/* Add threads for any new LWPs in a process.

   When LWP events are used, this function is only used to detect existing
   threads when attaching to a process.  On older systems, this function is
   called to discover new threads each time the thread list is updated.  */

static void
fbsd_add_threads (fbsd_nat_target *target, pid_t pid)
{
  int i, nlwps;

  gdb_assert (!in_thread_list (target, ptid_t (pid)));
  nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0);
  if (nlwps == -1)
    perror_with_name (("ptrace (PT_GETNUMLWPS)"));

  gdb::unique_xmalloc_ptr<lwpid_t[]> lwps (XCNEWVEC (lwpid_t, nlwps));

  nlwps = ptrace (PT_GETLWPLIST, pid, (caddr_t) lwps.get (), nlwps);
  if (nlwps == -1)
    perror_with_name (("ptrace (PT_GETLWPLIST)"));

  inferior *inf = find_inferior_ptid (target, ptid_t (pid));
  fbsd_inferior *fbsd_inf = get_fbsd_inferior (inf);
  gdb_assert (fbsd_inf != nullptr);
  for (i = 0; i < nlwps; i++)
    {
      ptid_t ptid = ptid_t (pid, lwps[i]);

      if (!in_thread_list (target, ptid))
	{
#ifdef PT_LWP_EVENTS
	  struct ptrace_lwpinfo pl;

	  /* Don't add exited threads.  Note that this is only called
	     when attaching to a multi-threaded process.  */
	  if (ptrace (PT_LWPINFO, lwps[i], (caddr_t) &pl, sizeof pl) == -1)
	    perror_with_name (("ptrace (PT_LWPINFO)"));
	  if (pl.pl_flags & PL_FLAG_EXITED)
	    continue;
#endif
	  fbsd_lwp_debug_printf ("adding thread for LWP %u", lwps[i]);
	  add_thread (target, ptid);
#ifdef PT_LWP_EVENTS
	  fbsd_inf->num_lwps++;
#endif
	}
    }
#ifndef PT_LWP_EVENTS
  fbsd_inf->num_lwps = nlwps;
#endif
}

/* Implement the "update_thread_list" target_ops method.  */

void
fbsd_nat_target::update_thread_list ()
{
#ifdef PT_LWP_EVENTS
  /* With support for thread events, threads are added/deleted from the
     list as events are reported, so just try deleting exited threads.  */
  delete_exited_threads ();
#else
  prune_threads ();

  fbsd_add_threads (this, inferior_ptid.pid ());
#endif
}

/* Async mode support.  */

/* Implement the "can_async_p" target method.  */

bool
fbsd_nat_target::can_async_p ()
{
  /* This flag should be checked in the common target.c code.  */
  gdb_assert (target_async_permitted);

  /* Otherwise, this targets is always able to support async mode.  */
  return true;
}

/* SIGCHLD handler notifies the event-loop in async mode.  */

static void
sigchld_handler (int signo)
{
  int old_errno = errno;

  fbsd_nat_target::async_file_mark_if_open ();

  errno = old_errno;
}

/* Callback registered with the target events file descriptor.  */

static void
handle_target_event (int error, gdb_client_data client_data)
{
  inferior_event_handler (INF_REG_EVENT);
}

/* Implement the "async" target method.  */

void
fbsd_nat_target::async (bool enable)
{
  if (enable == is_async_p ())
    return;

  /* Block SIGCHILD while we create/destroy the pipe, as the handler
     writes to it.  */
  gdb::block_signals blocker;

  if (enable)
    {
      if (!async_file_open ())
	internal_error ("failed to create event pipe.");

      add_file_handler (async_wait_fd (), handle_target_event, NULL, "fbsd-nat");

      /* Trigger a poll in case there are pending events to
	 handle.  */
      async_file_mark ();
    }
  else
    {
      delete_file_handler (async_wait_fd ());
      async_file_close ();
    }
}

#ifdef TDP_RFPPWAIT
/*
  To catch fork events, PT_FOLLOW_FORK is set on every traced process
  to enable stops on returns from fork or vfork.  Note that both the
  parent and child will always stop, even if system call stops are not
  enabled.

  After a fork, both the child and parent process will stop and report
  an event.  However, there is no guarantee of order.  If the parent
  reports its stop first, then fbsd_wait explicitly waits for the new
  child before returning.  If the child reports its stop first, then
  the event is saved on a list and ignored until the parent's stop is
  reported.  fbsd_wait could have been changed to fetch the parent PID
  of the new child and used that to wait for the parent explicitly.
  However, if two threads in the parent fork at the same time, then
  the wait on the parent might return the "wrong" fork event.

  The initial version of PT_FOLLOW_FORK did not set PL_FLAG_CHILD for
  the new child process.  This flag could be inferred by treating any
  events for an unknown pid as a new child.

  In addition, the initial version of PT_FOLLOW_FORK did not report a
  stop event for the parent process of a vfork until after the child
  process executed a new program or exited.  The kernel was changed to
  defer the wait for exit or exec of the child until after posting the
  stop event shortly after the change to introduce PL_FLAG_CHILD.
  This could be worked around by reporting a vfork event when the
  child event posted and ignoring the subsequent event from the
  parent.

  This implementation requires both of these fixes for simplicity's
  sake.  FreeBSD versions newer than 9.1 contain both fixes.
*/

static std::list<ptid_t> fbsd_pending_children;

/* Record a new child process event that is reported before the
   corresponding fork event in the parent.  */

static void
fbsd_remember_child (ptid_t pid)
{
  fbsd_pending_children.push_front (pid);
}

/* Check for a previously-recorded new child process event for PID.
   If one is found, remove it from the list and return the PTID.  */

static ptid_t
fbsd_is_child_pending (pid_t pid)
{
  for (auto it = fbsd_pending_children.begin ();
       it != fbsd_pending_children.end (); it++)
    if (it->pid () == pid)
      {
	ptid_t ptid = *it;
	fbsd_pending_children.erase (it);
	return ptid;
      }
  return null_ptid;
}

/* Wait for a child of a fork to report its stop.  Returns the PTID of
   the new child process.  */

static ptid_t
fbsd_wait_for_fork_child (pid_t pid)
{
  ptid_t ptid = fbsd_is_child_pending (pid);
  if (ptid != null_ptid)
    return ptid;

  int status;
  pid_t wpid = waitpid (pid, &status, 0);
  if (wpid == -1)
    perror_with_name (("waitpid"));

  gdb_assert (wpid == pid);

  struct ptrace_lwpinfo pl;
  if (ptrace (PT_LWPINFO, wpid, (caddr_t) &pl, sizeof pl) == -1)
    perror_with_name (("ptrace (PT_LWPINFO)"));

  gdb_assert (pl.pl_flags & PL_FLAG_CHILD);
  return ptid_t (wpid, pl.pl_lwpid);
}

#ifndef PTRACE_VFORK
/* Record a pending vfork done event.  */

static void
fbsd_add_vfork_done (ptid_t pid)
{
  add_pending_event (ptid, target_waitstatus ().set_vfork_done ());

  /* If we're in async mode, need to tell the event loop there's
     something here to process.  */
  if (target_is_async_p ())
    async_file_mark ();
}
#endif
#endif

/* Resume a single process.  */

void
fbsd_nat_target::resume_one_process (ptid_t ptid, int step,
				     enum gdb_signal signo)
{
  fbsd_nat_debug_printf ("[%s], step %d, signo %d (%s)",
			 target_pid_to_str (ptid).c_str (), step, signo,
			 gdb_signal_to_name (signo));

  inferior *inf = find_inferior_ptid (this, ptid);
  fbsd_inferior *fbsd_inf = get_fbsd_inferior (inf);
  fbsd_inf->resumed_lwps = ptid;
  gdb_assert (fbsd_inf->running_lwps == 0);

  /* Don't PT_CONTINUE a thread or process which has a pending event.  */
  if (have_pending_event (ptid))
    {
      fbsd_nat_debug_printf ("found pending event");
      return;
    }

  for (thread_info *tp : inf->non_exited_threads ())
    {
      /* If ptid is a specific LWP, suspend all other LWPs in the
	 process, otherwise resume all LWPs in the process..  */
      if (!ptid.lwp_p() || tp->ptid.lwp () == ptid.lwp ())
	{
	  if (ptrace (PT_RESUME, tp->ptid.lwp (), NULL, 0) == -1)
	    perror_with_name (("ptrace (PT_RESUME)"));
	  low_prepare_to_resume (tp);
	  fbsd_inf->running_lwps++;
	}
      else
	{
	  if (ptrace (PT_SUSPEND, tp->ptid.lwp (), NULL, 0) == -1)
	    perror_with_name (("ptrace (PT_SUSPEND)"));
	}
    }

  if (ptid.pid () != inferior_ptid.pid ())
    {
      step = 0;
      signo = GDB_SIGNAL_0;
      gdb_assert (!ptid.lwp_p ());
    }
  else
    {
      ptid = inferior_ptid;
#if __FreeBSD_version < 1200052
      /* When multiple threads within a process wish to report STOPPED
	 events from wait(), the kernel picks one thread event as the
	 thread event to report.  The chosen thread event is retrieved
	 via PT_LWPINFO by passing the process ID as the request pid.
	 If multiple events are pending, then the subsequent wait()
	 after resuming a process will report another STOPPED event
	 after resuming the process to handle the next thread event
	 and so on.

	 A single thread event is cleared as a side effect of resuming
	 the process with PT_CONTINUE, PT_STEP, etc.  In older
	 kernels, however, the request pid was used to select which
	 thread's event was cleared rather than always clearing the
	 event that was just reported.  To avoid clearing the event of
	 the wrong LWP, always pass the process ID instead of an LWP
	 ID to PT_CONTINUE or PT_SYSCALL.

	 In the case of stepping, the process ID cannot be used with
	 PT_STEP since it would step the thread that reported an event
	 which may not be the thread indicated by PTID.  For stepping,
	 use PT_SETSTEP to enable stepping on the desired thread
	 before resuming the process via PT_CONTINUE instead of using
	 PT_STEP.  */
      if (step)
	{
	  if (ptrace (PT_SETSTEP, get_ptrace_pid (ptid), NULL, 0) == -1)
	    perror_with_name (("ptrace (PT_SETSTEP)"));
	  step = 0;
	}
      ptid = ptid_t (ptid.pid ());
#endif
    }

  inf_ptrace_target::resume (ptid, step, signo);
}

/* Implement the "resume" target_ops method.  */

void
fbsd_nat_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo)
{
  fbsd_nat_debug_start_end ("[%s], step %d, signo %d (%s)",
			    target_pid_to_str (scope_ptid).c_str (), step, signo,
			    gdb_signal_to_name (signo));

  gdb_assert (inferior_ptid.matches (scope_ptid));
  gdb_assert (!scope_ptid.tid_p ());

  if (scope_ptid == minus_one_ptid)
    {
      for (inferior *inf : all_non_exited_inferiors (this))
	resume_one_process (ptid_t (inf->pid), step, signo);
    }
  else
    {
      resume_one_process (scope_ptid, step, signo);
    }
}

#ifdef USE_SIGTRAP_SIGINFO
/* Handle breakpoint and trace traps reported via SIGTRAP.  If the
   trap was a breakpoint or trace trap that should be reported to the
   core, return true.  */

static bool
fbsd_handle_debug_trap (fbsd_nat_target *target, ptid_t ptid,
			const struct ptrace_lwpinfo &pl)
{

  /* Ignore traps without valid siginfo or for signals other than
     SIGTRAP.

     FreeBSD kernels prior to r341800 can return stale siginfo for at
     least some events, but those events can be identified by
     additional flags set in pl_flags.  True breakpoint and
     single-step traps should not have other flags set in
     pl_flags.  */
  if (pl.pl_flags != PL_FLAG_SI || pl.pl_siginfo.si_signo != SIGTRAP)
    return false;

  /* Trace traps are either a single step or a hardware watchpoint or
     breakpoint.  */
  if (pl.pl_siginfo.si_code == TRAP_TRACE)
    {
      fbsd_nat_debug_printf ("trace trap for LWP %ld", ptid.lwp ());
      return true;
    }

  if (pl.pl_siginfo.si_code == TRAP_BRKPT)
    {
      /* Fixup PC for the software breakpoint.  */
      struct regcache *regcache = get_thread_regcache (target, ptid);
      struct gdbarch *gdbarch = regcache->arch ();
      int decr_pc = gdbarch_decr_pc_after_break (gdbarch);

      fbsd_nat_debug_printf ("sw breakpoint trap for LWP %ld", ptid.lwp ());
      if (decr_pc != 0)
	{
	  CORE_ADDR pc;

	  pc = regcache_read_pc (regcache);
	  regcache_write_pc (regcache, pc - decr_pc);
	}
      return true;
    }

  return false;
}
#endif

/* Wait for the child specified by PTID to do something.  Return the
   process ID of the child, or MINUS_ONE_PTID in case of error; store
   the status in *OURSTATUS.  */

ptid_t
fbsd_nat_target::wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
			 target_wait_flags target_options)
{
  ptid_t wptid;

  while (1)
    {
      wptid = inf_ptrace_target::wait (ptid, ourstatus, target_options);
      if (ourstatus->kind () == TARGET_WAITKIND_STOPPED)
	{
	  struct ptrace_lwpinfo pl;
	  pid_t pid = wptid.pid ();
	  if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof pl) == -1)
	    perror_with_name (("ptrace (PT_LWPINFO)"));

	  wptid = ptid_t (pid, pl.pl_lwpid);

	  if (debug_fbsd_nat)
	    {
	      fbsd_nat_debug_printf ("stop for LWP %u event %d flags %#x",
				     pl.pl_lwpid, pl.pl_event, pl.pl_flags);
	      if (pl.pl_flags & PL_FLAG_SI)
		fbsd_nat_debug_printf ("si_signo %u si_code %u",
				       pl.pl_siginfo.si_signo,
				       pl.pl_siginfo.si_code);
	    }

	  /* There may not be an inferior for this pid if this is a
	     PL_FLAG_CHILD event.  */
	  inferior *inf = find_inferior_ptid (this, wptid);
	  fbsd_inferior *fbsd_inf = inf == nullptr ? nullptr
	    : get_fbsd_inferior (inf);
	  gdb_assert (fbsd_inf != nullptr || pl.pl_flags & PL_FLAG_CHILD);

#ifdef PT_LWP_EVENTS
	  if (pl.pl_flags & PL_FLAG_EXITED)
	    {
	      /* If GDB attaches to a multi-threaded process, exiting
		 threads might be skipped during post_attach that
		 have not yet reported their PL_FLAG_EXITED event.
		 Ignore EXITED events for an unknown LWP.  */
	      thread_info *thr = this->find_thread (wptid);
	      if (thr != nullptr)
		{
		  fbsd_lwp_debug_printf ("deleting thread for LWP %u",
					 pl.pl_lwpid);
		  low_delete_thread (thr);
		  delete_thread (thr);
		  fbsd_inf->num_lwps--;

		  /* If this LWP was the only resumed LWP from the
		     process, report an event to the core.  */
		  if (wptid == fbsd_inf->resumed_lwps)
		    {
		      ourstatus->set_spurious ();
		      return wptid;
		    }

		  /* During process exit LWPs that were not resumed
		     will report exit events.  */
		  if (wptid.matches (fbsd_inf->resumed_lwps))
		    fbsd_inf->running_lwps--;
		}
	      if (ptrace (PT_CONTINUE, pid, (caddr_t) 1, 0) == -1)
		perror_with_name (("ptrace (PT_CONTINUE)"));
	      continue;
	    }
#endif

	  /* Switch to an LWP PTID on the first stop in a new process.
	     This is done after handling PL_FLAG_EXITED to avoid
	     switching to an exited LWP.  It is done before checking
	     PL_FLAG_BORN in case the first stop reported after
	     attaching to an existing process is a PL_FLAG_BORN
	     event.  */
	  if (in_thread_list (this, ptid_t (pid)))
	    {
	      fbsd_lwp_debug_printf ("using LWP %u for first thread",
				     pl.pl_lwpid);
	      thread_change_ptid (this, ptid_t (pid), wptid);
	    }

#ifdef PT_LWP_EVENTS
	  if (pl.pl_flags & PL_FLAG_BORN)
	    {
	      /* If GDB attaches to a multi-threaded process, newborn
		 threads might be added by fbsd_add_threads that have
		 not yet reported their PL_FLAG_BORN event.  Ignore
		 BORN events for an already-known LWP.  */
	      if (!in_thread_list (this, wptid))
		{
		  fbsd_lwp_debug_printf ("adding thread for LWP %u",
					 pl.pl_lwpid);
		  add_thread (this, wptid);
		  fbsd_inf->num_lwps++;

		  if (wptid.matches(fbsd_inf->resumed_lwps))
		    fbsd_inf->running_lwps++;
		}
	      ourstatus->set_spurious ();
	      return wptid;
	    }
#endif

#ifdef TDP_RFPPWAIT
	  if (pl.pl_flags & PL_FLAG_FORKED)
	    {
#ifndef PTRACE_VFORK
	      struct kinfo_proc kp;
#endif
	      bool is_vfork = false;
	      ptid_t child_ptid;
	      pid_t child;

	      child = pl.pl_child_pid;
#ifdef PTRACE_VFORK
	      if (pl.pl_flags & PL_FLAG_VFORKED)
		is_vfork = true;
#endif

	      /* Make sure the other end of the fork is stopped too.  */
	      child_ptid = fbsd_wait_for_fork_child (child);

	      /* Enable additional events on the child process.  */
	      fbsd_enable_proc_events (child_ptid.pid ());

#ifndef PTRACE_VFORK
	      /* For vfork, the child process will have the P_PPWAIT
		 flag set.  */
	      if (fbsd_fetch_kinfo_proc (child, &kp))
		{
		  if (kp.ki_flag & P_PPWAIT)
		    is_vfork = true;
		}
	      else
		warning (_("Failed to fetch process information"));
#endif

	      low_new_fork (wptid, child);

	      if (is_vfork)
		ourstatus->set_vforked (child_ptid);
	      else
		ourstatus->set_forked (child_ptid);

	      return wptid;
	    }

	  if (pl.pl_flags & PL_FLAG_CHILD)
	    {
	      /* Remember that this child forked, but do not report it
		 until the parent reports its corresponding fork
		 event.  */
	      fbsd_remember_child (wptid);
	      continue;
	    }

#ifdef PTRACE_VFORK
	  if (pl.pl_flags & PL_FLAG_VFORK_DONE)
	    {
	      ourstatus->set_vfork_done ();
	      return wptid;
	    }
#endif
#endif

	  if (pl.pl_flags & PL_FLAG_EXEC)
	    {
	      ourstatus->set_execd
		(make_unique_xstrdup (pid_to_exec_file (pid)));
	      return wptid;
	    }

#ifdef USE_SIGTRAP_SIGINFO
	  if (fbsd_handle_debug_trap (this, wptid, pl))
	    return wptid;
#endif

	  /* Note that PL_FLAG_SCE is set for any event reported while
	     a thread is executing a system call in the kernel.  In
	     particular, signals that interrupt a sleep in a system
	     call will report this flag as part of their event.  Stops
	     explicitly for system call entry and exit always use
	     SIGTRAP, so only treat SIGTRAP events as system call
	     entry/exit events.  */
	  if (pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX)
	      && ourstatus->sig () == GDB_SIGNAL_TRAP)
	    {
#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
	      if (catch_syscall_enabled ())
		{
		  if (catching_syscall_number (pl.pl_syscall_code))
		    {
		      if (pl.pl_flags & PL_FLAG_SCE)
			ourstatus->set_syscall_entry (pl.pl_syscall_code);
		      else
			ourstatus->set_syscall_return (pl.pl_syscall_code);

		      return wptid;
		    }
		}
#endif
	      /* If the core isn't interested in this event, just
		 continue the process explicitly and wait for another
		 event.  Note that PT_SYSCALL is "sticky" on FreeBSD
		 and once system call stops are enabled on a process
		 it stops for all system call entries and exits.  */
	      if (ptrace (PT_CONTINUE, pid, (caddr_t) 1, 0) == -1)
		perror_with_name (("ptrace (PT_CONTINUE)"));
	      continue;
	    }

	  /* If this is a pending SIGSTOP event from an earlier call
	     to stop_process, discard the event and wait for another
	     event.  */
	  if (ourstatus->sig () == GDB_SIGNAL_STOP && fbsd_inf->pending_sigstop)
	    {
	      fbsd_nat_debug_printf ("ignoring SIGSTOP for pid %u", pid);
	      fbsd_inf->pending_sigstop = false;
	      if (ptrace (PT_CONTINUE, pid, (caddr_t) 1, 0) == -1)
		perror_with_name (("ptrace (PT_CONTINUE)"));
	      continue;
	    }
	}
      else
	fbsd_nat_debug_printf ("event [%s], [%s]",
			       target_pid_to_str (wptid).c_str (),
			       ourstatus->to_string ().c_str ());
      return wptid;
    }
}

/* Stop a given process.  If the process is already stopped, record
   its pending event instead.  */

void
fbsd_nat_target::stop_process (inferior *inf)
{
  fbsd_inferior *fbsd_inf = get_fbsd_inferior (inf);
  gdb_assert (fbsd_inf != nullptr);

  fbsd_inf->resumed_lwps = null_ptid;
  if (fbsd_inf->running_lwps == 0)
    return;

  ptid_t ptid (inf->pid);
  target_waitstatus status;
  ptid_t wptid = wait_1 (ptid, &status, TARGET_WNOHANG);

  if (wptid != minus_one_ptid)
    {
      /* Save the current event as a pending event.  */
      add_pending_event (wptid, status);
      fbsd_inf->running_lwps = 0;
      return;
    }

  /* If a SIGSTOP is already pending, don't send a new one, but tell
     wait_1 to report a SIGSTOP.  */
  if (fbsd_inf->pending_sigstop)
    {
      fbsd_nat_debug_printf ("waiting for existing pending SIGSTOP for %u",
			     inf->pid);
      fbsd_inf->pending_sigstop = false;
    }
  else
    {
      /* Ignore errors from kill as process exit might race with kill.  */
      fbsd_nat_debug_printf ("killing %u with SIGSTOP", inf->pid);
      ::kill (inf->pid, SIGSTOP);
    }

  /* Wait for SIGSTOP (or some other event) to be reported.  */
  wptid = wait_1 (ptid, &status, 0);

  switch (status.kind ())
    {
    case TARGET_WAITKIND_EXITED:
    case TARGET_WAITKIND_SIGNALLED:
      /* If the process has exited, we aren't going to get an
	 event for the SIGSTOP.  Save the current event and
	 return.  */
      add_pending_event (wptid, status);
      break;
    case TARGET_WAITKIND_IGNORE:
      /* wait() failed with ECHILD meaning the process no longer
	 exists.  This means a bug happened elsewhere, but at least
	 the process is no longer running.  */
      break;
    case TARGET_WAITKIND_STOPPED:
      /* If this is the SIGSTOP event, discard it and return
	 leaving the process stopped.  */
      if (status.sig () == GDB_SIGNAL_STOP)
	break;

      /* FALLTHROUGH */
    default:
      /* Some other event has occurred.  Save the current
	 event.  */
      add_pending_event (wptid, status);

      /* Ignore the next SIGSTOP for this process.  */
      fbsd_nat_debug_printf ("ignoring next SIGSTOP for %u", inf->pid);
      fbsd_inf->pending_sigstop = true;
      break;
    }
  fbsd_inf->running_lwps = 0;
}

ptid_t
fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
		       target_wait_flags target_options)
{
  fbsd_nat_debug_printf ("[%s], [%s]", target_pid_to_str (ptid).c_str (),
			 target_options_to_string (target_options).c_str ());

  /* If there is a valid pending event, return it.  */
  gdb::optional<pending_event> event = take_pending_event (ptid);
  if (event.has_value ())
    {
      /* Stop any other inferiors currently running.  */
      for (inferior *inf : all_non_exited_inferiors (this))
	stop_process (inf);

      fbsd_nat_debug_printf ("returning pending event [%s], [%s]",
			     target_pid_to_str (event->ptid).c_str (),
			     event->status.to_string ().c_str ());
      gdb_assert (event->ptid.matches (ptid));
      *ourstatus = event->status;
      return event->ptid;
    }

  /* Ensure any subsequent events trigger a new event in the loop.  */
  if (is_async_p ())
    async_file_flush ();

  ptid_t wptid;
  while (1)
    {
      wptid = wait_1 (ptid, ourstatus, target_options);

      /* If no event was found, just return.  */
      if (ourstatus->kind () == TARGET_WAITKIND_IGNORE
	  || ourstatus->kind () == TARGET_WAITKIND_NO_RESUMED)
	break;

      inferior *winf = find_inferior_ptid (this, wptid);
      gdb_assert (winf != nullptr);
      fbsd_inferior *fbsd_inf = get_fbsd_inferior (winf);
      gdb_assert (fbsd_inf != nullptr);
      gdb_assert (fbsd_inf->resumed_lwps != null_ptid);
      gdb_assert (fbsd_inf->running_lwps > 0);

      /* If an event is reported for a thread or process while
	 stepping some other thread, suspend the thread reporting the
	 event and defer the event until it can be reported to the
	 core.  */
      if (!wptid.matches (fbsd_inf->resumed_lwps))
	{
	  add_pending_event (wptid, *ourstatus);
	  fbsd_nat_debug_printf ("deferring event [%s], [%s]",
				 target_pid_to_str (wptid).c_str (),
				 ourstatus->to_string ().c_str ());
	  if (ptrace (PT_SUSPEND, wptid.lwp (), NULL, 0) == -1)
	    perror_with_name (("ptrace (PT_SUSPEND)"));
	  if (ptrace (PT_CONTINUE, wptid.pid (), (caddr_t) 1, 0) == -1)
	    perror_with_name (("ptrace (PT_CONTINUE)"));
	  continue;
	}

      /* This process is no longer running.  */
      fbsd_inf->resumed_lwps = null_ptid;
      fbsd_inf->running_lwps = 0;

      /* Stop any other inferiors currently running.  */
      for (inferior *inf : all_non_exited_inferiors (this))
	stop_process (inf);

      break;
    }

  /* If we are in async mode and found an event, there may still be
     another event pending.  Trigger the event pipe so that that the
     event loop keeps polling until no event is returned.  */
  if (is_async_p ()
      && ((ourstatus->kind () != TARGET_WAITKIND_IGNORE
	  && ourstatus->kind () != TARGET_WAITKIND_NO_RESUMED)
	  || ptid != minus_one_ptid))
    async_file_mark ();

  fbsd_nat_debug_printf ("returning [%s], [%s]",
			 target_pid_to_str (wptid).c_str (),
			 ourstatus->to_string ().c_str ());
  return wptid;
}

#ifdef USE_SIGTRAP_SIGINFO
/* Implement the "stopped_by_sw_breakpoint" target_ops method.  */

bool
fbsd_nat_target::stopped_by_sw_breakpoint ()
{
  struct ptrace_lwpinfo pl;

  if (ptrace (PT_LWPINFO, get_ptrace_pid (inferior_ptid), (caddr_t) &pl,
	      sizeof pl) == -1)
    return false;

  return (pl.pl_flags == PL_FLAG_SI
	  && pl.pl_siginfo.si_signo == SIGTRAP
	  && pl.pl_siginfo.si_code == TRAP_BRKPT);
}

/* Implement the "supports_stopped_by_sw_breakpoint" target_ops
   method.  */

bool
fbsd_nat_target::supports_stopped_by_sw_breakpoint ()
{
  return true;
}
#endif

#ifdef PROC_ASLR_CTL
class maybe_disable_address_space_randomization
{
public:
  explicit maybe_disable_address_space_randomization (bool disable_randomization)
  {
    if (disable_randomization)
      {
	if (procctl (P_PID, getpid (), PROC_ASLR_STATUS, &m_aslr_ctl) == -1)
	  {
	    warning (_("Failed to fetch current address space randomization "
		       "status: %s"), safe_strerror (errno));
	    return;
	  }

	m_aslr_ctl &= ~PROC_ASLR_ACTIVE;
	if (m_aslr_ctl == PROC_ASLR_FORCE_DISABLE)
	  return;

	int ctl = PROC_ASLR_FORCE_DISABLE;
	if (procctl (P_PID, getpid (), PROC_ASLR_CTL, &ctl) == -1)
	  {
	    warning (_("Error disabling address space randomization: %s"),
		     safe_strerror (errno));
	    return;
	  }

	m_aslr_ctl_set = true;
      }
  }

  ~maybe_disable_address_space_randomization ()
  {
    if (m_aslr_ctl_set)
      {
	if (procctl (P_PID, getpid (), PROC_ASLR_CTL, &m_aslr_ctl) == -1)
	  warning (_("Error restoring address space randomization: %s"),
		   safe_strerror (errno));
      }
  }

  DISABLE_COPY_AND_ASSIGN (maybe_disable_address_space_randomization);

private:
  bool m_aslr_ctl_set = false;
  int m_aslr_ctl = 0;
};
#endif

void
fbsd_nat_target::create_inferior (const char *exec_file,
				  const std::string &allargs,
				  char **env, int from_tty)
{
#ifdef PROC_ASLR_CTL
  maybe_disable_address_space_randomization restore_aslr_ctl
    (disable_randomization);
#endif

  fbsd_inferior *fbsd_inf = new fbsd_inferior;
  current_inferior ()->priv.reset (fbsd_inf);
  fbsd_inf->resumed_lwps = minus_one_ptid;
  fbsd_inf->num_lwps = 1;
  fbsd_inf->running_lwps = 1;
  inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty);
}

void
fbsd_nat_target::attach (const char *args, int from_tty)
{
  fbsd_inferior *fbsd_inf = new fbsd_inferior;
  current_inferior ()->priv.reset (fbsd_inf);
  fbsd_inf->resumed_lwps = minus_one_ptid;
  fbsd_inf->num_lwps = 1;
  fbsd_inf->running_lwps = 1;
  inf_ptrace_target::attach (args, from_tty);
}

/* If this thread has a pending fork event, there is a child process
   GDB is attached to that the core of GDB doesn't know about.
   Detach from it.  */

void
fbsd_nat_target::detach_fork_children (thread_info *tp)
{
  /* Check in thread_info::pending_waitstatus.  */
  if (tp->has_pending_waitstatus ())
    {
      const target_waitstatus &ws = tp->pending_waitstatus ();

      if (ws.kind () == TARGET_WAITKIND_VFORKED
	  || ws.kind () == TARGET_WAITKIND_FORKED)
	{
	  pid_t pid = ws.child_ptid ().pid ();
	  fbsd_nat_debug_printf ("detaching from child %d", pid);
	  (void) ptrace (PT_DETACH, pid, (caddr_t) 1, 0);
	}
    }

  /* Check in thread_info::pending_follow.  */
  if (tp->pending_follow.kind () == TARGET_WAITKIND_VFORKED
      || tp->pending_follow.kind () == TARGET_WAITKIND_FORKED)
    {
      pid_t pid = tp->pending_follow.child_ptid ().pid ();
      fbsd_nat_debug_printf ("detaching from child %d", pid);
      (void) ptrace (PT_DETACH, pid, (caddr_t) 1, 0);
    }
}

/* Detach from any child processes associated with pending fork events
   for a stopped process.  Returns true if the process has terminated
   and false if it is still alive.  */

bool
fbsd_nat_target::detach_fork_children (inferior *inf)
{
  /* Detach any child processes associated with pending fork events in
     threads belonging to this process.  */
  for (thread_info *tp : inf->non_exited_threads ())
    detach_fork_children (tp);

  /* Unwind state associated with any pending events.  Reset
     fbsd_inf->resumed_lwps so that take_pending_event will harvest
     events.  */
  fbsd_inferior *fbsd_inf = get_fbsd_inferior (inf);
  ptid_t ptid = ptid_t (inf->pid);
  fbsd_inf->resumed_lwps = ptid;

  while (1)
    {
      gdb::optional<pending_event> event = take_pending_event (ptid);
      if (!event.has_value ())
	break;

      switch (event->status.kind ())
	{
	case TARGET_WAITKIND_EXITED:
	case TARGET_WAITKIND_SIGNALLED:
	  return true;
	case TARGET_WAITKIND_FORKED:
	case TARGET_WAITKIND_VFORKED:
	  {
	    pid_t pid = event->status.child_ptid ().pid ();
	    fbsd_nat_debug_printf ("detaching from child %d", pid);
	    (void) ptrace (PT_DETACH, pid, (caddr_t) 1, 0);
	  }
	  break;
	}
    }
  return false;
}

/* Scan all of the threads for a stopped process invoking the supplied
   callback on the ptrace_lwpinfo object for threads other than the
   thread which reported the current stop.  The callback can return
   true to terminate the iteration early.  This function returns true
   if the callback returned true, otherwise it returns false.  */

typedef bool (ptrace_event_ftype) (const struct ptrace_lwpinfo &pl);

static bool
iterate_other_ptrace_events (pid_t pid,
			     gdb::function_view<ptrace_event_ftype> callback)
{
  /* Fetch the LWP ID of the thread that just reported the last stop
     and ignore that LWP in the following loop.  */
  ptrace_lwpinfo pl;
  if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof (pl)) != 0)
    perror_with_name (("ptrace (PT_LWPINFO)"));
  lwpid_t lwpid = pl.pl_lwpid;

  int nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0);
  if (nlwps == -1)
    perror_with_name (("ptrace (PT_GETLWPLIST)"));
  if (nlwps == 1)
    return false;

  gdb::unique_xmalloc_ptr<lwpid_t[]> lwps (XCNEWVEC (lwpid_t, nlwps));

  nlwps = ptrace (PT_GETLWPLIST, pid, (caddr_t) lwps.get (), nlwps);
  if (nlwps == -1)
    perror_with_name (("ptrace (PT_GETLWPLIST)"));

  for (int i = 0; i < nlwps; i++)
    {
      if (lwps[i] == lwpid)
	continue;

      if (ptrace (PT_LWPINFO, lwps[i], (caddr_t) &pl, sizeof (pl)) != 0)
	perror_with_name (("ptrace (PT_LWPINFO)"));

      if (callback (pl))
	return true;
    }
  return false;
}

/* True if there are any stopped threads with an interesting event.  */

static bool
pending_ptrace_events (inferior *inf)
{
  auto lambda = [] (const struct ptrace_lwpinfo &pl)
  {
#if defined(PT_LWP_EVENTS) && __FreeBSD_kernel_version < 1400090
    if (pl.pl_flags == PL_FLAG_BORN)
      return true;
#endif
#ifdef TDP_RFPPWAIT
    if (pl.pl_flags & PL_FLAG_FORKED)
      return true;
#endif
    if (pl.pl_event == PL_EVENT_SIGNAL)
      {
	if ((pl.pl_flags & PL_FLAG_SI) == 0)
	  {
	    /* Not sure which signal, assume it matters.  */
	    return true;
	  }
	if (pl.pl_siginfo.si_signo == SIGTRAP)
	  return true;
      }
    return false;
  };
  return iterate_other_ptrace_events (inf->pid,
				      gdb::make_function_view (lambda));
}

void
fbsd_nat_target::detach (inferior *inf, int from_tty)
{
  fbsd_nat_debug_start_end ("pid %d", inf->pid);

  stop_process (inf);

  remove_breakpoints_inf (inf);

  if (detach_fork_children (inf)) {
    /* No need to detach now.  */
    target_announce_detach (from_tty);

    detach_success (inf);
    return;
  }

  /* If there are any pending events (SIGSTOP from stop_process or a
     breakpoint hit that needs a PC fixup), drain events until the
     process can be safely detached.  */
  fbsd_inferior *fbsd_inf = get_fbsd_inferior (inf);
  ptid_t ptid = ptid_t (inf->pid);
  if (fbsd_inf->pending_sigstop || pending_ptrace_events (inf))
    {
      bool pending_sigstop = fbsd_inf->pending_sigstop;
      int sig = 0;

      if (pending_sigstop)
	fbsd_nat_debug_printf ("waiting for SIGSTOP");

      /* Force wait_1 to report the SIGSTOP instead of swallowing it.  */
      fbsd_inf->pending_sigstop = false;

      /* Report event for all threads from wait_1.  */
      fbsd_inf->resumed_lwps = ptid;

      do
	{
	  if (ptrace (PT_CONTINUE, inf->pid, (caddr_t) 1, sig) != 0)
	    perror_with_name (("ptrace(PT_CONTINUE)"));

	  target_waitstatus ws;
	  ptid_t wptid = wait_1 (ptid, &ws, 0);

	  switch (ws.kind ())
	    {
	    case TARGET_WAITKIND_EXITED:
	    case TARGET_WAITKIND_SIGNALLED:
	      /* No need to detach now.  */
	      target_announce_detach (from_tty);

	      detach_success (inf);
	      return;
	    case TARGET_WAITKIND_FORKED:
	    case TARGET_WAITKIND_VFORKED:
	      {
		pid_t pid = ws.child_ptid ().pid ();
		fbsd_nat_debug_printf ("detaching from child %d", pid);
		(void) ptrace (PT_DETACH, pid, (caddr_t) 1, 0);
		sig = 0;
	      }
	      break;
	    case TARGET_WAITKIND_STOPPED:
	      sig = gdb_signal_to_host (ws.sig ());
	      switch (sig)
		{
		case SIGSTOP:
		  if (pending_sigstop)
		    {
		      sig = 0;
		      pending_sigstop = false;
		    }
		  break;
		case SIGTRAP:
#ifndef USE_SIGTRAP_SIGINFO
		  {
		    /* Update PC from software breakpoint hit.  */
		    struct regcache *regcache = get_thread_regcache (this, wptid);
		    struct gdbarch *gdbarch = regcache->arch ();
		    int decr_pc = gdbarch_decr_pc_after_break (gdbarch);

		    if (decr_pc != 0)
		      {
			CORE_ADDR pc;

			pc = regcache_read_pc (regcache);
			if (breakpoint_inserted_here_p (regcache->aspace (),
							pc - decr_pc))
			  {
			    fbsd_nat_debug_printf ("adjusted PC for LWP %ld",
						   wptid.lwp ());
			    regcache_write_pc (regcache, pc - decr_pc);
			  }
		      }
		  }
#else
		  /* pacify gcc  */
		  (void) wptid;
#endif
		  sig = 0;
		  break;
		}
	    }
	}
      while (pending_sigstop || pending_ptrace_events (inf));
    }

  target_announce_detach (from_tty);

  if (ptrace (PT_DETACH, inf->pid, (caddr_t) 1, 0) == -1)
	perror_with_name (("ptrace (PT_DETACH)"));

  detach_success (inf);
}

/* Implement the "kill" target method.  */

void
fbsd_nat_target::kill ()
{
  pid_t pid = inferior_ptid.pid ();
  if (pid == 0)
    return;

  inferior *inf = current_inferior ();
  stop_process (inf);

  if (detach_fork_children (inf)) {
    /* No need to kill now.  */
    target_mourn_inferior (inferior_ptid);

    return;
  }

#ifdef TDP_RFPPWAIT
  /* If there are any threads that have forked a new child but not yet
     reported it because other threads reported events first, detach
     from the children before killing the parent.  */
  auto lambda = [] (const struct ptrace_lwpinfo &pl)
  {
    if (pl.pl_flags & PL_FLAG_FORKED)
      {
	pid_t child = pl.pl_child_pid;

	/* If the child hasn't reported its stop yet, wait for it to
	   stop.  */
	fbsd_wait_for_fork_child (child);

	/* Detach from the child.  */
	(void) ptrace (PT_DETACH, child, (caddr_t) 1, 0);
      }
    return false;
  };
  iterate_other_ptrace_events (pid, gdb::make_function_view (lambda));
#endif

  if (ptrace (PT_KILL, pid, NULL, 0) == -1)
	perror_with_name (("ptrace (PT_KILL)"));

  int status;
  waitpid (pid, &status, 0);

  target_mourn_inferior (inferior_ptid);
}

void
fbsd_nat_target::mourn_inferior ()
{
  gdb_assert (!have_pending_event (ptid_t (current_inferior ()->pid)));
  inf_ptrace_target::mourn_inferior ();
}

void
fbsd_nat_target::follow_exec (inferior *follow_inf, ptid_t ptid,
			      const char *execd_pathname)
{
  inferior *orig_inf = current_inferior ();

  inf_ptrace_target::follow_exec (follow_inf, ptid, execd_pathname);

  if (orig_inf != follow_inf)
    {
      /* Migrate the fbsd_inferior to the new inferior. */
      follow_inf->priv.reset (orig_inf->priv.release ());
    }
}

#ifdef TDP_RFPPWAIT
/* Target hook for follow_fork.  On entry and at return inferior_ptid is
   the ptid of the followed inferior.  */

void
fbsd_nat_target::follow_fork (inferior *child_inf, ptid_t child_ptid,
			      target_waitkind fork_kind, bool follow_child,
			      bool detach_fork)
{
  inf_ptrace_target::follow_fork (child_inf, child_ptid, fork_kind,
				  follow_child, detach_fork);

  if (child_inf != nullptr)
    {
      fbsd_inferior *fbsd_inf = new fbsd_inferior;
      child_inf->priv.reset (fbsd_inf);
      fbsd_inf->num_lwps = 1;
    }

  if (!follow_child && detach_fork)
    {
      pid_t child_pid = child_ptid.pid ();

      /* Breakpoints have already been detached from the child by
	 infrun.c.  */

      if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3) 1, 0) == -1)
	perror_with_name (("ptrace (PT_DETACH)"));

#ifndef PTRACE_VFORK
      if (fork_kind () == TARGET_WAITKIND_VFORKED)
	{
	  /* We can't insert breakpoints until the child process has
	     finished with the shared memory region.  The parent
	     process doesn't wait for the child process to exit or
	     exec until after it has been resumed from the ptrace stop
	     to report the fork.  Once it has been resumed it doesn't
	     stop again before returning to userland, so there is no
	     reliable way to wait on the parent.

	     We can't stay attached to the child to wait for an exec
	     or exit because it may invoke ptrace(PT_TRACE_ME)
	     (e.g. if the parent process is a debugger forking a new
	     child process).

	     In the end, the best we can do is to make sure it runs
	     for a little while.  Hopefully it will be out of range of
	     any breakpoints we reinsert.  Usually this is only the
	     single-step breakpoint at vfork's return point.  */

	  usleep (10000);

	  /* Schedule a fake VFORK_DONE event to report on the next
	     wait.  */
	  fbsd_add_vfork_done (inferior_ptid);
	}
#endif
    }
}

int
fbsd_nat_target::insert_fork_catchpoint (int pid)
{
  return 0;
}

int
fbsd_nat_target::remove_fork_catchpoint (int pid)
{
  return 0;
}

int
fbsd_nat_target::insert_vfork_catchpoint (int pid)
{
  return 0;
}

int
fbsd_nat_target::remove_vfork_catchpoint (int pid)
{
  return 0;
}
#endif

/* Implement the virtual inf_ptrace_target::post_startup_inferior method.  */

void
fbsd_nat_target::post_startup_inferior (ptid_t pid)
{
  fbsd_enable_proc_events (pid.pid ());
}

/* Implement the "post_attach" target_ops method.  */

void
fbsd_nat_target::post_attach (int pid)
{
  fbsd_enable_proc_events (pid);
  fbsd_add_threads (this, pid);
}

/* Traced processes always stop after exec.  */

int
fbsd_nat_target::insert_exec_catchpoint (int pid)
{
  return 0;
}

int
fbsd_nat_target::remove_exec_catchpoint (int pid)
{
  return 0;
}

#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
int
fbsd_nat_target::set_syscall_catchpoint (int pid, bool needed,
					 int any_count,
					 gdb::array_view<const int> syscall_counts)
{

  /* Ignore the arguments.  inf-ptrace.c will use PT_SYSCALL which
     will catch all system call entries and exits.  The system calls
     are filtered by GDB rather than the kernel.  */
  return 0;
}
#endif

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

bool
fbsd_nat_target::supports_disable_randomization ()
{
#ifdef PROC_ASLR_CTL
  return true;
#else
  return false;
#endif
}

/* See fbsd-nat.h.  */

bool
fbsd_nat_target::fetch_register_set (struct regcache *regcache, int regnum,
				     int fetch_op, const struct regset *regset,
				     int regbase, void *regs, size_t size)
{
  const struct regcache_map_entry *map
    = (const struct regcache_map_entry *) regset->regmap;
  pid_t pid = get_ptrace_pid (regcache->ptid ());

  if (regnum == -1
      || (regnum >= regbase && regcache_map_supplies (map, regnum - regbase,
						      regcache->arch (), size)))
    {
      if (ptrace (fetch_op, pid, (PTRACE_TYPE_ARG3) regs, 0) == -1)
	perror_with_name (_("Couldn't get registers"));

      regset->supply_regset (regset, regcache, regnum, regs, size);
      return true;
    }
  return false;
}

/* See fbsd-nat.h.  */

bool
fbsd_nat_target::store_register_set (struct regcache *regcache, int regnum,
				     int fetch_op, int store_op,
				     const struct regset *regset, int regbase,
				     void *regs, size_t size)
{
  const struct regcache_map_entry *map
    = (const struct regcache_map_entry *) regset->regmap;
  pid_t pid = get_ptrace_pid (regcache->ptid ());

  if (regnum == -1
      || (regnum >= regbase && regcache_map_supplies (map, regnum - regbase,
						      regcache->arch (), size)))
    {
      if (ptrace (fetch_op, pid, (PTRACE_TYPE_ARG3) regs, 0) == -1)
	perror_with_name (_("Couldn't get registers"));

      regset->collect_regset (regset, regcache, regnum, regs, size);

      if (ptrace (store_op, pid, (PTRACE_TYPE_ARG3) regs, 0) == -1)
	perror_with_name (_("Couldn't write registers"));
      return true;
    }
  return false;
}

/* See fbsd-nat.h.  */

size_t
fbsd_nat_target::have_regset (ptid_t ptid, int note)
{
  pid_t pid = get_ptrace_pid (ptid);
  struct iovec iov;

  iov.iov_base = nullptr;
  iov.iov_len = 0;
  if (ptrace (PT_GETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
    return 0;
  return iov.iov_len;
}

/* See fbsd-nat.h.  */

bool
fbsd_nat_target::fetch_regset (struct regcache *regcache, int regnum, int note,
			       const struct regset *regset, int regbase,
			       void *regs, size_t size)
{
  const struct regcache_map_entry *map
    = (const struct regcache_map_entry *) regset->regmap;
  pid_t pid = get_ptrace_pid (regcache->ptid ());

  if (regnum == -1
      || (regnum >= regbase && regcache_map_supplies (map, regnum - regbase,
						      regcache->arch (), size)))
    {
      struct iovec iov;

      iov.iov_base = regs;
      iov.iov_len = size;
      if (ptrace (PT_GETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
	perror_with_name (_("Couldn't get registers"));

      regset->supply_regset (regset, regcache, regnum, regs, size);
      return true;
    }
  return false;
}

bool
fbsd_nat_target::store_regset (struct regcache *regcache, int regnum, int note,
			       const struct regset *regset, int regbase,
			       void *regs, size_t size)
{
  const struct regcache_map_entry *map
    = (const struct regcache_map_entry *) regset->regmap;
  pid_t pid = get_ptrace_pid (regcache->ptid ());

  if (regnum == -1
      || (regnum >= regbase && regcache_map_supplies (map, regnum - regbase,
						      regcache->arch (), size)))
    {
      struct iovec iov;

      iov.iov_base = regs;
      iov.iov_len = size;
      if (ptrace (PT_GETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
	perror_with_name (_("Couldn't get registers"));

      regset->collect_regset (regset, regcache, regnum, regs, size);

      if (ptrace (PT_SETREGSET, pid, (PTRACE_TYPE_ARG3) &iov, note) == -1)
	perror_with_name (_("Couldn't write registers"));
      return true;
    }
  return false;
}

/* See fbsd-nat.h.  */

bool
fbsd_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo)
{
  struct ptrace_lwpinfo pl;
  pid_t pid = get_ptrace_pid (ptid);

  if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof pl) == -1)
    return false;
  if (!(pl.pl_flags & PL_FLAG_SI))
    return false;;
  *siginfo = pl.pl_siginfo;
  return (true);
}

void _initialize_fbsd_nat ();
void
_initialize_fbsd_nat ()
{
  add_setshow_boolean_cmd ("fbsd-lwp", class_maintenance,
			   &debug_fbsd_lwp, _("\
Set debugging of FreeBSD lwp module."), _("\
Show debugging of FreeBSD lwp module."), _("\
Enables printf debugging output."),
			   NULL,
			   &show_fbsd_lwp_debug,
			   &setdebuglist, &showdebuglist);
  add_setshow_boolean_cmd ("fbsd-nat", class_maintenance,
			   &debug_fbsd_nat, _("\
Set debugging of FreeBSD native target."), _("\
Show debugging of FreeBSD native target."), _("\
Enables printf debugging output."),
			   NULL,
			   &show_fbsd_nat_debug,
			   &setdebuglist, &showdebuglist);

  /* Install a SIGCHLD handler.  */
  signal (SIGCHLD, sigchld_handler);
}
