/* 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 ())
    {
      int request;

      /* 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 *inf = find_inferior_ptid (this, wptid);
      gdb_assert (inf != nullptr);
      fbsd_inferior *fbsd_inf = get_fbsd_inferior (inf);
      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);
			  }
		      }
		  }
#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);
}
