/* Copyright (C) 2020-2021 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 "server.h"
#include "target.h"
#include "netbsd-low.h"
#include "nat/netbsd-nat.h"

#include <sys/param.h>
#include <sys/types.h>

#include <sys/ptrace.h>
#include <sys/sysctl.h>

#include <limits.h>
#include <unistd.h>
#include <signal.h>

#include <elf.h>

#include <type_traits>

#include "gdbsupport/eintr.h"
#include "gdbsupport/gdb_wait.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/common-inferior.h"
#include "nat/fork-inferior.h"
#include "hostio.h"

int using_threads = 1;

/* Callback used by fork_inferior to start tracing the inferior.  */

static void
netbsd_ptrace_fun ()
{
  /* Switch child to its own process group so that signals won't
     directly affect GDBserver. */
  if (setpgid (0, 0) < 0)
    trace_start_error_with_name (("setpgid"));

  if (ptrace (PT_TRACE_ME, 0, nullptr, 0) < 0)
    trace_start_error_with_name (("ptrace"));

  /* If GDBserver is connected to gdb via stdio, redirect the inferior's
     stdout to stderr so that inferior i/o doesn't corrupt the connection.
     Also, redirect stdin to /dev/null.  */
  if (remote_connection_is_stdio ())
    {
      if (close (0) < 0)
	trace_start_error_with_name (("close"));
      if (open ("/dev/null", O_RDONLY) < 0)
	trace_start_error_with_name (("open"));
      if (dup2 (2, 1) < 0)
	trace_start_error_with_name (("dup2"));
      if (write (2, "stdin/stdout redirected\n",
		 sizeof ("stdin/stdout redirected\n") - 1) < 0)
	{
	  /* Errors ignored.  */
	}
    }
}

/* Implement the create_inferior method of the target_ops vector.  */

int
netbsd_process_target::create_inferior (const char *program,
					const std::vector<char *> &program_args)
{
  std::string str_program_args = construct_inferior_arguments (program_args);

  pid_t pid = fork_inferior (program, str_program_args.c_str (),
			     get_environ ()->envp (), netbsd_ptrace_fun,
			     nullptr, nullptr, nullptr, nullptr);

  add_process (pid, 0);

  post_fork_inferior (pid, program);

  return pid;
}

/* Implement the post_create_inferior target_ops method.  */

void
netbsd_process_target::post_create_inferior ()
{
  pid_t pid = current_process ()->pid;
  netbsd_nat::enable_proc_events (pid);

  low_arch_setup ();
}

/* Implement the attach target_ops method.  */

int
netbsd_process_target::attach (unsigned long pid)
{
  /* Unimplemented.  */
  return -1;
}

/* Returns true if GDB is interested in any child syscalls.  */

static bool
gdb_catching_syscalls_p (pid_t pid)
{
  struct process_info *proc = find_process_pid (pid);
  return !proc->syscalls_to_catch.empty ();
}

/* Implement the resume target_ops method.  */

void
netbsd_process_target::resume (struct thread_resume *resume_info, size_t n)
{
  ptid_t resume_ptid = resume_info[0].thread;
  const int signal = resume_info[0].sig;
  const bool step = resume_info[0].kind == resume_step;

  if (resume_ptid == minus_one_ptid)
    resume_ptid = ptid_of (current_thread);

  const pid_t pid = resume_ptid.pid ();
  const lwpid_t lwp = resume_ptid.lwp ();
  regcache_invalidate_pid (pid);

  auto fn
    = [&] (ptid_t ptid)
      {
	if (step)
	  {
	    if (ptid.lwp () == lwp || n != 1)
	      {
		if (ptrace (PT_SETSTEP, pid, NULL, ptid.lwp ()) == -1)
		  perror_with_name (("ptrace"));
		if (ptrace (PT_RESUME, pid, NULL, ptid.lwp ()) == -1)
		  perror_with_name (("ptrace"));
	      }
	    else
	      {
		if (ptrace (PT_CLEARSTEP, pid, NULL, ptid.lwp ()) == -1)
		  perror_with_name (("ptrace"));
		if (ptrace (PT_SUSPEND, pid, NULL, ptid.lwp ()) == -1)
		  perror_with_name (("ptrace"));
	      }
	  }
	else
	  {
	    if (ptrace (PT_CLEARSTEP, pid, NULL, ptid.lwp ()) == -1)
	      perror_with_name (("ptrace"));
	    if (ptrace (PT_RESUME, pid, NULL, ptid.lwp ()) == -1)
	      perror_with_name (("ptrace"));
	  }
      };

  netbsd_nat::for_each_thread (pid, fn);

  int request = gdb_catching_syscalls_p (pid) ? PT_CONTINUE : PT_SYSCALL;

  errno = 0;
  ptrace (request, pid, (void *)1, signal);
  if (errno)
    perror_with_name (("ptrace"));
}

/* Returns true if GDB is interested in the reported SYSNO syscall.  */

static bool
netbsd_catch_this_syscall (int sysno)
{
  struct process_info *proc = current_process ();

  if (proc->syscalls_to_catch.empty ())
    return false;

  if (proc->syscalls_to_catch[0] == ANY_SYSCALL)
    return true;

  for (int iter : proc->syscalls_to_catch)
    if (iter == sysno)
      return true;

  return false;
}

/* Helper function for child_wait and the derivatives of child_wait.
   HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
   translation of that in OURSTATUS.  */

static void
netbsd_store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
{
  if (WIFEXITED (hoststatus))
    ourstatus->set_exited (WEXITSTATUS (hoststatus));
  else if (!WIFSTOPPED (hoststatus))
    ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (hoststatus)));
  else
    ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (hoststatus)));
}

/* Implement a safe wrapper around waitpid().  */

static pid_t
netbsd_waitpid (ptid_t ptid, struct target_waitstatus *ourstatus,
		target_wait_flags target_options)
{
  int status;
  int options = (target_options & TARGET_WNOHANG) ? WNOHANG : 0;

  pid_t pid
    = gdb::handle_eintr (-1, ::waitpid, ptid.pid (), &status, options);

  if (pid == -1)
    perror_with_name (_("Child process unexpectedly missing"));

  netbsd_store_waitstatus (ourstatus, status);
  return pid;
}


/* Implement the wait target_ops method.

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

static ptid_t
netbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus,
	     target_wait_flags target_options)
{
  pid_t pid = netbsd_waitpid (ptid, ourstatus, target_options);
  ptid_t wptid = ptid_t (pid);

  if (pid == 0)
    {
      gdb_assert (target_options & TARGET_WNOHANG);
      ourstatus->set_ignore ();
      return null_ptid;
    }

  gdb_assert (pid != -1);

  /* If the child stopped, keep investigating its status.  */
  if (ourstatus->kind () != TARGET_WAITKIND_STOPPED)
    return wptid;

  /* Extract the event and thread that received a signal.  */
  ptrace_siginfo_t psi;
  if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
    perror_with_name (("ptrace"));

  /* Pick child's siginfo_t.  */
  siginfo_t *si = &psi.psi_siginfo;

  lwpid_t lwp = psi.psi_lwpid;

  int signo = si->si_signo;
  const int code = si->si_code;

  /* Construct PTID with a specified thread that received the event.
     If a signal was targeted to the whole process, lwp is 0.  */
  wptid = ptid_t (pid, lwp, 0);

  /* Bail out on non-debugger oriented signals.  */
  if (signo != SIGTRAP)
    return wptid;

  /* Stop examining non-debugger oriented SIGTRAP codes.  */
  if (code <= SI_USER || code == SI_NOINFO)
    return wptid;

  /* Process state for threading events.  */
  ptrace_state_t pst = {};
  if (code == TRAP_LWP)
    if (ptrace (PT_GET_PROCESS_STATE, pid, &pst, sizeof (pst)) == -1)
      perror_with_name (("ptrace"));

  if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_EXIT)
    {
      /* If GDB attaches to a multi-threaded process, exiting
	 threads might be skipped during post_attach that
	 have not yet reported their PTRACE_LWP_EXIT event.
	 Ignore exited events for an unknown LWP.  */
      thread_info *thr = find_thread_ptid (wptid);
      if (thr == nullptr)
	  ourstatus->set_spurious ();
      else
	{
	  /* NetBSD does not store an LWP exit status.  */
	  ourstatus->set_thread_exited (0);

	  remove_thread (thr);
	}
      return wptid;
    }

  if (find_thread_ptid (ptid_t (pid)))
    current_thread = find_thread_ptid (wptid);

  if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE)
    {
      /* If GDB attaches to a multi-threaded process, newborn
	 threads might be added by nbsd_add_threads that have
	 not yet reported their PTRACE_LWP_CREATE event.  Ignore
	 born events for an already-known LWP.  */
      if (find_thread_ptid (wptid))
	ourstatus->set_spurious ();
      else
	{
	  add_thread (wptid, NULL);
	  ourstatus->set_thread_created ();
	}
      return wptid;
    }

  if (code == TRAP_EXEC)
    {
      ourstatus->set_execd
	(make_unique_xstrdup (netbsd_nat::pid_to_exec_file (pid)));
      return wptid;
    }

  if (code == TRAP_TRACE)
      return wptid;

  if (code == TRAP_SCE || code == TRAP_SCX)
    {
      int sysnum = si->si_sysnum;

      if (!netbsd_catch_this_syscall(sysnum))
	{
	  /* If the core isn't interested in this event, ignore it.  */
	  ourstatus->set_spurious ();
	  return wptid;
	}

      if (code == TRAP_SCE)
	ourstatus->set_syscall_entry (sysnum);
      else
	ourstatus->set_syscall_return (sysnum);

      return wptid;
    }

  if (code == TRAP_BRKPT)
    {
#ifdef PTRACE_BREAKPOINT_ADJ
      CORE_ADDR pc;
      struct reg r;
      ptrace (PT_GETREGS, pid, &r, psi.psi_lwpid);
      pc = PTRACE_REG_PC (&r);
      PTRACE_REG_SET_PC (&r, pc - PTRACE_BREAKPOINT_ADJ);
      ptrace (PT_SETREGS, pid, &r, psi.psi_lwpid);
#endif
      return wptid;
    }

  /* Unclassified SIGTRAP event.  */
  ourstatus->set_spurious ();
  return wptid;
}

/* Implement the wait target_ops method.  */

ptid_t
netbsd_process_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
			     target_wait_flags target_options)
{
  while (true)
    {
      ptid_t wptid = netbsd_wait (ptid, ourstatus, target_options);

      /* Register thread in the gdbcore if a thread was not reported earlier.
	 This is required after ::create_inferior, when the gdbcore does not
	 know about the first internal thread.
	 This may also happen on attach, when an event is registered on a thread
	 that was not fully initialized during the attach stage.  */
      if (wptid.lwp () != 0 && !find_thread_ptid (wptid)
	  && ourstatus->kind () != TARGET_WAITKIND_THREAD_EXITED)
	add_thread (wptid, nullptr);

      switch (ourstatus->kind ())
	{
	case TARGET_WAITKIND_EXITED:
	case TARGET_WAITKIND_STOPPED:
	case TARGET_WAITKIND_SIGNALLED:
	case TARGET_WAITKIND_FORKED:
	case TARGET_WAITKIND_VFORKED:
	case TARGET_WAITKIND_EXECD:
	case TARGET_WAITKIND_VFORK_DONE:
	case TARGET_WAITKIND_SYSCALL_ENTRY:
	case TARGET_WAITKIND_SYSCALL_RETURN:
	  /* Pass the result to the generic code.  */
	  return wptid;
	case TARGET_WAITKIND_THREAD_CREATED:
	case TARGET_WAITKIND_THREAD_EXITED:
	  /* The core needlessly stops on these events.  */
	  /* FALLTHROUGH */
	case TARGET_WAITKIND_SPURIOUS:
	  /* Spurious events are unhandled by the gdbserver core.  */
	  if (ptrace (PT_CONTINUE, current_process ()->pid, (void *) 1, 0)
	      == -1)
	    perror_with_name (("ptrace"));
	  break;
	default:
	  error (("Unknown stopped status"));
	}
    }
}

/* Implement the kill target_ops method.  */

int
netbsd_process_target::kill (process_info *process)
{
  pid_t pid = process->pid;
  if (ptrace (PT_KILL, pid, nullptr, 0) == -1)
    return -1;

  int status;
  if (gdb::handle_eintr (-1, ::waitpid, pid, &status, 0) == -1)
    return -1;
  mourn (process);
  return 0;
}

/* Implement the detach target_ops method.  */

int
netbsd_process_target::detach (process_info *process)
{
  pid_t pid = process->pid;

  ptrace (PT_DETACH, pid, (void *) 1, 0);
  mourn (process);
  return 0;
}

/* Implement the mourn target_ops method.  */

void
netbsd_process_target::mourn (struct process_info *proc)
{
  for_each_thread (proc->pid, remove_thread);

  remove_process (proc);
}

/* Implement the join target_ops method.  */

void
netbsd_process_target::join (int pid)
{
  /* The PT_DETACH is sufficient to detach from the process.
     So no need to do anything extra.  */
}

/* Implement the thread_alive target_ops method.  */

bool
netbsd_process_target::thread_alive (ptid_t ptid)
{
  return netbsd_nat::thread_alive (ptid);
}

/* Implement the fetch_registers target_ops method.  */

void
netbsd_process_target::fetch_registers (struct regcache *regcache, int regno)
{
  const netbsd_regset_info *regset = get_regs_info ();
  ptid_t inferior_ptid = ptid_of (current_thread);

  while (regset->size >= 0)
    {
      std::vector<char> buf;
      buf.resize (regset->size);
      int res = ptrace (regset->get_request, inferior_ptid.pid (), buf.data (),
			inferior_ptid.lwp ());
      if (res == -1)
	perror_with_name (("ptrace"));
      regset->store_function (regcache, buf.data ());
      regset++;
    }
}

/* Implement the store_registers target_ops method.  */

void
netbsd_process_target::store_registers (struct regcache *regcache, int regno)
{
  const netbsd_regset_info *regset = get_regs_info ();
  ptid_t inferior_ptid = ptid_of (current_thread);

  while (regset->size >= 0)
    {
      std::vector<char> buf;
      buf.resize (regset->size);
      int res = ptrace (regset->get_request, inferior_ptid.pid (), buf.data (),
			inferior_ptid.lwp ());
      if (res == -1)
	perror_with_name (("ptrace"));

      /* Then overlay our cached registers on that.  */
      regset->fill_function (regcache, buf.data ());
      /* Only now do we write the register set.  */
      res = ptrace (regset->set_request, inferior_ptid.pid (), buf. data (),
		    inferior_ptid.lwp ());
      if (res == -1)
	perror_with_name (("ptrace"));
      regset++;
    }
}

/* Implement the read_memory target_ops method.  */

int
netbsd_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr,
				    int size)
{
  pid_t pid = current_process ()->pid;
  return netbsd_nat::read_memory (pid, myaddr, memaddr, size, nullptr);
}

/* Implement the write_memory target_ops method.  */

int
netbsd_process_target::write_memory (CORE_ADDR memaddr,
				     const unsigned char *myaddr, int size)
{
  pid_t pid = current_process ()->pid;
  return netbsd_nat::write_memory (pid, myaddr, memaddr, size, nullptr);
}

/* Implement the request_interrupt target_ops method.  */

void
netbsd_process_target::request_interrupt ()
{
  ptid_t inferior_ptid = ptid_of (get_first_thread ());

  ::kill (inferior_ptid.pid (), SIGINT);
}

/* Read the AUX Vector for the specified PID, wrapping the ptrace(2) call
   with the PIOD_READ_AUXV operation and using the PT_IO standard input
   and output arguments.  */

static size_t
netbsd_read_auxv(pid_t pid, void *offs, void *addr, size_t len)
{
  struct ptrace_io_desc pio;

  pio.piod_op = PIOD_READ_AUXV;
  pio.piod_offs = offs;
  pio.piod_addr = addr;
  pio.piod_len = len;

  if (ptrace (PT_IO, pid, &pio, 0) == -1)
    perror_with_name (("ptrace"));

  return pio.piod_len;
}

/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
   to debugger memory starting at MYADDR.  */

int
netbsd_process_target::read_auxv (CORE_ADDR offset,
				  unsigned char *myaddr, unsigned int len)
{
  pid_t pid = pid_of (current_thread);

  return netbsd_read_auxv (pid, (void *) (intptr_t) offset, myaddr, len);
}

bool
netbsd_process_target::supports_z_point_type (char z_type)
{
  switch (z_type)
    {
    case Z_PACKET_SW_BP:
      return true;
    case Z_PACKET_HW_BP:
    case Z_PACKET_WRITE_WP:
    case Z_PACKET_READ_WP:
    case Z_PACKET_ACCESS_WP:
    default:
      return false; /* Not supported.  */
    }
}

/* Insert {break/watch}point at address ADDR.  SIZE is not used.  */

int
netbsd_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
		     int size, struct raw_breakpoint *bp)
{
  switch (type)
    {
    case raw_bkpt_type_sw:
      return insert_memory_breakpoint (bp);
    case raw_bkpt_type_hw:
    case raw_bkpt_type_write_wp:
    case raw_bkpt_type_read_wp:
    case raw_bkpt_type_access_wp:
    default:
      return 1; /* Not supported.  */
    }
}

/* Remove {break/watch}point at address ADDR.  SIZE is not used.  */

int
netbsd_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
				     int size, struct raw_breakpoint *bp)
{
  switch (type)
    {
    case raw_bkpt_type_sw:
      return remove_memory_breakpoint (bp);
    case raw_bkpt_type_hw:
    case raw_bkpt_type_write_wp:
    case raw_bkpt_type_read_wp:
    case raw_bkpt_type_access_wp:
    default:
      return 1; /* Not supported.  */
    }
}

/* Implement the stopped_by_sw_breakpoint target_ops method.  */

bool
netbsd_process_target::stopped_by_sw_breakpoint ()
{
  ptrace_siginfo_t psi;
  pid_t pid = current_process ()->pid;

  if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
    perror_with_name (("ptrace"));

  return psi.psi_siginfo.si_signo == SIGTRAP &&
	 psi.psi_siginfo.si_code == TRAP_BRKPT;
}

/* Implement the supports_stopped_by_sw_breakpoint target_ops method.  */

bool
netbsd_process_target::supports_stopped_by_sw_breakpoint ()
{
  return true;
}

/* Implement the supports_qxfer_siginfo target_ops method.  */

bool
netbsd_process_target::supports_qxfer_siginfo ()
{
  return true;
}

/* Implement the qxfer_siginfo target_ops method.  */

int
netbsd_process_target::qxfer_siginfo (const char *annex, unsigned char *readbuf,
				      unsigned const char *writebuf,
				      CORE_ADDR offset, int len)
{
  if (current_thread == nullptr)
    return -1;

  pid_t pid = current_process ()->pid;

  return netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset, len);
}

/* Implement the supports_non_stop target_ops method.  */

bool
netbsd_process_target::supports_non_stop ()
{
  return false;
}

/* Implement the supports_multi_process target_ops method.  */

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

/* Check if fork events are supported.  */

bool
netbsd_process_target::supports_fork_events ()
{
  return false;
}

/* Check if vfork events are supported.  */

bool
netbsd_process_target::supports_vfork_events ()
{
  return false;
}

/* Check if exec events are supported.  */

bool
netbsd_process_target::supports_exec_events ()
{
  return true;
}

/* Implement the supports_disable_randomization target_ops method.  */

bool
netbsd_process_target::supports_disable_randomization ()
{
  return false;
}

/* Extract &phdr and num_phdr in the inferior.  Return 0 on success.  */

template <typename T>
int get_phdr_phnum_from_proc_auxv (const pid_t pid,
				   CORE_ADDR *phdr_memaddr, int *num_phdr)
{
  typedef typename std::conditional<sizeof(T) == sizeof(int64_t),
				    Aux64Info, Aux32Info>::type auxv_type;
  const size_t auxv_size = sizeof (auxv_type);
  const size_t auxv_buf_size = 128 * sizeof (auxv_type);

  std::vector<char> auxv_buf;
  auxv_buf.resize (auxv_buf_size);

  netbsd_read_auxv (pid, nullptr, auxv_buf.data (), auxv_buf_size);

  *phdr_memaddr = 0;
  *num_phdr = 0;

  for (char *buf = auxv_buf.data ();
       buf < (auxv_buf.data () + auxv_buf_size);
       buf += auxv_size)
    {
      auxv_type *const aux = (auxv_type *) buf;

      switch (aux->a_type)
	{
	case AT_PHDR:
	  *phdr_memaddr = aux->a_v;
	  break;
	case AT_PHNUM:
	  *num_phdr = aux->a_v;
	  break;
	}

      if (*phdr_memaddr != 0 && *num_phdr != 0)
	break;
    }

  if (*phdr_memaddr == 0 || *num_phdr == 0)
    {
      warning ("Unexpected missing AT_PHDR and/or AT_PHNUM: "
	       "phdr_memaddr = %s, phdr_num = %d",
	       core_addr_to_string (*phdr_memaddr), *num_phdr);
      return 2;
    }

  return 0;
}

/* Return &_DYNAMIC (via PT_DYNAMIC) in the inferior, or 0 if not present.  */

template <typename T>
static CORE_ADDR
get_dynamic (const pid_t pid)
{
  typedef typename std::conditional<sizeof(T) == sizeof(int64_t),
				    Elf64_Phdr, Elf32_Phdr>::type phdr_type;
  const int phdr_size = sizeof (phdr_type);

  CORE_ADDR phdr_memaddr;
  int num_phdr;
  if (get_phdr_phnum_from_proc_auxv<T> (pid, &phdr_memaddr, &num_phdr))
    return 0;

  std::vector<unsigned char> phdr_buf;
  phdr_buf.resize (num_phdr * phdr_size);

  if (netbsd_nat::read_memory (pid, phdr_buf.data (), phdr_memaddr,
			       phdr_buf.size (), nullptr))
    return 0;

  /* Compute relocation: it is expected to be 0 for "regular" executables,
     non-zero for PIE ones.  */
  CORE_ADDR relocation = -1;
  for (int i = 0; relocation == -1 && i < num_phdr; i++)
    {
      phdr_type *const p = (phdr_type *) (phdr_buf.data () + i * phdr_size);

      if (p->p_type == PT_PHDR)
	relocation = phdr_memaddr - p->p_vaddr;
    }

  if (relocation == -1)
    {
      /* PT_PHDR is optional, but necessary for PIE in general.  Fortunately
	 any real world executables, including PIE executables, have always
	 PT_PHDR present.  PT_PHDR is not present in some shared libraries or
	 in fpc (Free Pascal 2.4) binaries but neither of those have a need for
	 or present DT_DEBUG anyway (fpc binaries are statically linked).

	 Therefore if there exists DT_DEBUG there is always also PT_PHDR.

	 GDB could find RELOCATION also from AT_ENTRY - e_entry.  */

      return 0;
    }

  for (int i = 0; i < num_phdr; i++)
    {
      phdr_type *const p = (phdr_type *) (phdr_buf.data () + i * phdr_size);

      if (p->p_type == PT_DYNAMIC)
	return p->p_vaddr + relocation;
    }

  return 0;
}

/* Return &_r_debug in the inferior, or -1 if not present.  Return value
   can be 0 if the inferior does not yet have the library list initialized.
   We look for DT_MIPS_RLD_MAP first.  MIPS executables use this instead of
   DT_DEBUG, although they sometimes contain an unused DT_DEBUG entry too.  */

template <typename T>
static CORE_ADDR
get_r_debug (const pid_t pid)
{
  typedef typename std::conditional<sizeof(T) == sizeof(int64_t),
				    Elf64_Dyn, Elf32_Dyn>::type dyn_type;
  const int dyn_size = sizeof (dyn_type);
  unsigned char buf[sizeof (dyn_type)];  /* The larger of the two.  */
  CORE_ADDR map = -1;

  CORE_ADDR dynamic_memaddr = get_dynamic<T> (pid);
  if (dynamic_memaddr == 0)
    return map;

  while (netbsd_nat::read_memory (pid, buf, dynamic_memaddr, dyn_size, nullptr)
	 == 0)
    {
      dyn_type *const dyn = (dyn_type *) buf;
#if defined DT_MIPS_RLD_MAP
      union
      {
	T map;
	unsigned char buf[sizeof (T)];
      }
      rld_map;

      if (dyn->d_tag == DT_MIPS_RLD_MAP)
	{
	  if (netbsd_nat::read_memory (pid, rld_map.buf, dyn->d_un.d_val,
				       sizeof (rld_map.buf), nullptr) == 0)
	    return rld_map.map;
	  else
	    break;
	}
#endif  /* DT_MIPS_RLD_MAP */

      if (dyn->d_tag == DT_DEBUG && map == -1)
	map = dyn->d_un.d_val;

      if (dyn->d_tag == DT_NULL)
	break;

      dynamic_memaddr += dyn_size;
    }

  return map;
}

/* Read one pointer from MEMADDR in the inferior.  */

static int
read_one_ptr (const pid_t pid, CORE_ADDR memaddr, CORE_ADDR *ptr, int ptr_size)
{
  /* Go through a union so this works on either big or little endian
     hosts, when the inferior's pointer size is smaller than the size
     of CORE_ADDR.  It is assumed the inferior's endianness is the
     same of the superior's.  */

  union
  {
    CORE_ADDR core_addr;
    unsigned int ui;
    unsigned char uc;
  } addr;

  int ret = netbsd_nat::read_memory (pid, &addr.uc, memaddr, ptr_size, nullptr);
  if (ret == 0)
    {
      if (ptr_size == sizeof (CORE_ADDR))
	*ptr = addr.core_addr;
      else if (ptr_size == sizeof (unsigned int))
	*ptr = addr.ui;
      else
	gdb_assert_not_reached ("unhandled pointer size");
    }
  return ret;
}

/* Construct qXfer:libraries-svr4:read reply.  */

template <typename T>
int
netbsd_qxfer_libraries_svr4 (const pid_t pid, const char *annex,
			     unsigned char *readbuf,
			     unsigned const char *writebuf,
			     CORE_ADDR offset, int len)
{
  struct link_map_offsets
  {
    /* Offset and size of r_debug.r_version.  */
    int r_version_offset;

    /* Offset and size of r_debug.r_map.  */
    int r_map_offset;

    /* Offset to l_addr field in struct link_map.  */
    int l_addr_offset;

    /* Offset to l_name field in struct link_map.  */
    int l_name_offset;

    /* Offset to l_ld field in struct link_map.  */
    int l_ld_offset;

    /* Offset to l_next field in struct link_map.  */
    int l_next_offset;

    /* Offset to l_prev field in struct link_map.  */
    int l_prev_offset;
  };

  static const struct link_map_offsets lmo_32bit_offsets =
    {
      0,     /* r_version offset. */
      4,     /* r_debug.r_map offset.  */
      0,     /* l_addr offset in link_map.  */
      4,     /* l_name offset in link_map.  */
      8,     /* l_ld offset in link_map.  */
      12,    /* l_next offset in link_map.  */
      16     /* l_prev offset in link_map.  */
    };

  static const struct link_map_offsets lmo_64bit_offsets =
    {
      0,     /* r_version offset. */
      8,     /* r_debug.r_map offset.  */
      0,     /* l_addr offset in link_map.  */
      8,     /* l_name offset in link_map.  */
      16,    /* l_ld offset in link_map.  */
      24,    /* l_next offset in link_map.  */
      32     /* l_prev offset in link_map.  */
    };

  CORE_ADDR lm_addr = 0, lm_prev = 0;
  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
  int header_done = 0;

  const struct link_map_offsets *lmo
    = ((sizeof (T) == sizeof (int64_t))
       ? &lmo_64bit_offsets : &lmo_32bit_offsets);
  int ptr_size = sizeof (T);

  while (annex[0] != '\0')
    {
      const char *sep = strchr (annex, '=');
      if (sep == nullptr)
	break;

      int name_len = sep - annex;
      CORE_ADDR *addrp;
      if (name_len == 5 && startswith (annex, "start"))
	addrp = &lm_addr;
      else if (name_len == 4 && startswith (annex, "prev"))
	addrp = &lm_prev;
      else
	{
	  annex = strchr (sep, ';');
	  if (annex == nullptr)
	    break;
	  annex++;
	  continue;
	}

      annex = decode_address_to_semicolon (addrp, sep + 1);
    }

  if (lm_addr == 0)
    {
      CORE_ADDR r_debug = get_r_debug<T> (pid);

      /* We failed to find DT_DEBUG.  Such situation will not change
	 for this inferior - do not retry it.  Report it to GDB as
	 E01, see for the reasons at the GDB solib-svr4.c side.  */
      if (r_debug == (CORE_ADDR) -1)
	return -1;

      if (r_debug != 0)
	{
	  CORE_ADDR map_offset = r_debug + lmo->r_map_offset;
	  if (read_one_ptr (pid, map_offset, &lm_addr, ptr_size) != 0)
	    warning ("unable to read r_map from %s",
		     core_addr_to_string (map_offset));
	}
    }

  std::string document = "<library-list-svr4 version=\"1.0\"";

  while (lm_addr
	 && read_one_ptr (pid, lm_addr + lmo->l_name_offset,
			  &l_name, ptr_size) == 0
	 && read_one_ptr (pid, lm_addr + lmo->l_addr_offset,
			  &l_addr, ptr_size) == 0
	 && read_one_ptr (pid, lm_addr + lmo->l_ld_offset,
			  &l_ld, ptr_size) == 0
	 && read_one_ptr (pid, lm_addr + lmo->l_prev_offset,
			  &l_prev, ptr_size) == 0
	 && read_one_ptr (pid, lm_addr + lmo->l_next_offset,
			  &l_next, ptr_size) == 0)
    {
      if (lm_prev != l_prev)
	{
	  warning ("Corrupted shared library list: 0x%lx != 0x%lx",
		   (long) lm_prev, (long) l_prev);
	  break;
	}

      /* Ignore the first entry even if it has valid name as the first entry
	 corresponds to the main executable.  The first entry should not be
	 skipped if the dynamic loader was loaded late by a static executable
	 (see solib-svr4.c parameter ignore_first).  But in such case the main
	 executable does not have PT_DYNAMIC present and this function already
	 exited above due to failed get_r_debug.  */
      if (lm_prev == 0)
	string_appendf (document, " main-lm=\"0x%lx\"",
			(unsigned long) lm_addr);
      else
	{
	  unsigned char libname[PATH_MAX];

	  /* Not checking for error because reading may stop before
	     we've got PATH_MAX worth of characters.  */
	  libname[0] = '\0';
	  netbsd_nat::read_memory (pid, libname, l_name, sizeof (libname) - 1,
				   nullptr);
	  libname[sizeof (libname) - 1] = '\0';
	  if (libname[0] != '\0')
	    {
	      if (!header_done)
		{
		  /* Terminate `<library-list-svr4'.  */
		  document += '>';
		  header_done = 1;
		}

	      string_appendf (document, "<library name=\"");
	      xml_escape_text_append (&document, (char *) libname);
	      string_appendf (document, "\" lm=\"0x%lx\" "
			      "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
			      (unsigned long) lm_addr, (unsigned long) l_addr,
			      (unsigned long) l_ld);
	    }
	}

      lm_prev = lm_addr;
      lm_addr = l_next;
    }

  if (!header_done)
    {
      /* Empty list; terminate `<library-list-svr4'.  */
      document += "/>";
    }
  else
    document += "</library-list-svr4>";

  int document_len = document.length ();
  if (offset < document_len)
    document_len -= offset;
  else
    document_len = 0;
  if (len > document_len)
    len = document_len;

  memcpy (readbuf, document.data () + offset, len);

  return len;
}

/* Return true if FILE is a 64-bit ELF file,
   false if the file is not a 64-bit ELF file,
   and error if the file is not accessible or doesn't exist.  */

static bool
elf_64_file_p (const char *file)
{
  int fd = gdb::handle_eintr (-1, ::open, file, O_RDONLY);
  if (fd < 0)
    perror_with_name (("open"));

  Elf64_Ehdr header;
  ssize_t ret = gdb::handle_eintr (-1, ::read, fd, &header, sizeof (header));
  if (ret == -1)
    perror_with_name (("read"));
  gdb::handle_eintr (-1, ::close, fd);
  if (ret != sizeof (header))
    error ("Cannot read ELF file header: %s", file);

  if (header.e_ident[EI_MAG0] != ELFMAG0
      || header.e_ident[EI_MAG1] != ELFMAG1
      || header.e_ident[EI_MAG2] != ELFMAG2
      || header.e_ident[EI_MAG3] != ELFMAG3)
    error ("Unrecognized ELF file header: %s", file);

  return header.e_ident[EI_CLASS] == ELFCLASS64;
}

/* Construct qXfer:libraries-svr4:read reply.  */

int
netbsd_process_target::qxfer_libraries_svr4 (const char *annex,
					     unsigned char *readbuf,
					     unsigned const char *writebuf,
					     CORE_ADDR offset, int len)
{
  if (writebuf != nullptr)
    return -2;
  if (readbuf == nullptr)
    return -1;

  struct process_info *proc = current_process ();
  pid_t pid = proc->pid;
  bool is_elf64 = elf_64_file_p (netbsd_nat::pid_to_exec_file (pid));

  if (is_elf64)
    return netbsd_qxfer_libraries_svr4<int64_t> (pid, annex, readbuf,
						 writebuf, offset, len);
  else
    return netbsd_qxfer_libraries_svr4<int32_t> (pid, annex, readbuf,
						 writebuf, offset, len);
}

/* Implement the supports_qxfer_libraries_svr4 target_ops method.  */

bool
netbsd_process_target::supports_qxfer_libraries_svr4 ()
{
  return true;
}

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

const char *
netbsd_process_target::pid_to_exec_file (pid_t pid)
{
  return netbsd_nat::pid_to_exec_file (pid);
}

/* Implementation of the target_ops method "supports_pid_to_exec_file".  */

bool
netbsd_process_target::supports_pid_to_exec_file ()
{
  return true;
}

/* Implementation of the target_ops method "supports_hardware_single_step".  */
bool
netbsd_process_target::supports_hardware_single_step ()
{
  return true;
}

/* Implementation of the target_ops method "sw_breakpoint_from_kind".  */

const gdb_byte *
netbsd_process_target::sw_breakpoint_from_kind (int kind, int *size)
{
  static gdb_byte brkpt[PTRACE_BREAKPOINT_SIZE] = {*PTRACE_BREAKPOINT};

  *size = PTRACE_BREAKPOINT_SIZE;

  return brkpt;
}

/* Implement the thread_name target_ops method.  */

const char *
netbsd_process_target::thread_name (ptid_t ptid)
{
  return netbsd_nat::thread_name (ptid);
}

/* Implement the supports_catch_syscall target_ops method.  */

bool
netbsd_process_target::supports_catch_syscall ()
{
  return true;
}

/* Implement the supports_read_auxv target_ops method.  */

bool
netbsd_process_target::supports_read_auxv ()
{
  return true;
}

void
initialize_low ()
{
  set_target_ops (the_netbsd_target);
}
