/* Native-dependent code for FreeBSD.

   Copyright (C) 2002-2025 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 "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 "cli/cli-cmds.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"
#include "gdbsupport/eintr.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.  */

std::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 (current_inferior ()->arch (), 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, true, 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 && c_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 = gdb::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.  */
  std::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)
    {
      std::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;
  gdb::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);
}

INIT_GDB_FILE (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);
}
