/* Copyright (C) 2020-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 "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::string &program_args)
{
  pid_t pid = fork_inferior (program, 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 = current_thread->id;

  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::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);

	  thr->process ()->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
	{
	  find_process_pid (wptid.pid ())->add_thread (wptid, nullptr);
	  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)
	find_process_pid (wptid.pid ())->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::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)
{
  proc->for_each_thread ([proc] (thread_info *thread)
    {
      proc->remove_thread (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 = current_thread->id;

  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 = current_thread->id;

  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 = get_first_thread ()->id;

  ::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::open (file, O_RDONLY);
  if (fd < 0)
    perror_with_name (("open"));

  Elf64_Ehdr header;
  ssize_t ret = gdb::read (fd, &header, sizeof (header));
  if (ret == -1)
    perror_with_name (("read"));
  gdb::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);
}
