/* Copyright (C) 2020-2024 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 "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)))
    switch_to_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 (int pid, CORE_ADDR offset,
				  unsigned char *myaddr, unsigned int len)
{
  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);
}
