Home | History | Annotate | Line # | Download | only in gdbserver
netbsd-low.cc revision 1.1.1.2
      1  1.1.1.2  christos /* Copyright (C) 2020-2023 Free Software Foundation, Inc.
      2      1.1  christos 
      3      1.1  christos    This file is part of GDB.
      4      1.1  christos 
      5      1.1  christos    This program is free software; you can redistribute it and/or modify
      6      1.1  christos    it under the terms of the GNU General Public License as published by
      7      1.1  christos    the Free Software Foundation; either version 3 of the License, or
      8      1.1  christos    (at your option) any later version.
      9      1.1  christos 
     10      1.1  christos    This program is distributed in the hope that it will be useful,
     11      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13      1.1  christos    GNU General Public License for more details.
     14      1.1  christos 
     15      1.1  christos    You should have received a copy of the GNU General Public License
     16      1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     17      1.1  christos 
     18      1.1  christos #include "server.h"
     19      1.1  christos #include "target.h"
     20      1.1  christos #include "netbsd-low.h"
     21      1.1  christos #include "nat/netbsd-nat.h"
     22      1.1  christos 
     23      1.1  christos #include <sys/param.h>
     24      1.1  christos #include <sys/types.h>
     25      1.1  christos 
     26      1.1  christos #include <sys/ptrace.h>
     27      1.1  christos #include <sys/sysctl.h>
     28      1.1  christos 
     29      1.1  christos #include <limits.h>
     30      1.1  christos #include <unistd.h>
     31      1.1  christos #include <signal.h>
     32      1.1  christos 
     33      1.1  christos #include <elf.h>
     34      1.1  christos 
     35      1.1  christos #include <type_traits>
     36      1.1  christos 
     37      1.1  christos #include "gdbsupport/eintr.h"
     38      1.1  christos #include "gdbsupport/gdb_wait.h"
     39      1.1  christos #include "gdbsupport/filestuff.h"
     40      1.1  christos #include "gdbsupport/common-inferior.h"
     41      1.1  christos #include "nat/fork-inferior.h"
     42      1.1  christos #include "hostio.h"
     43      1.1  christos 
     44      1.1  christos int using_threads = 1;
     45      1.1  christos 
     46      1.1  christos /* Callback used by fork_inferior to start tracing the inferior.  */
     47      1.1  christos 
     48      1.1  christos static void
     49      1.1  christos netbsd_ptrace_fun ()
     50      1.1  christos {
     51      1.1  christos   /* Switch child to its own process group so that signals won't
     52      1.1  christos      directly affect GDBserver. */
     53      1.1  christos   if (setpgid (0, 0) < 0)
     54      1.1  christos     trace_start_error_with_name (("setpgid"));
     55      1.1  christos 
     56      1.1  christos   if (ptrace (PT_TRACE_ME, 0, nullptr, 0) < 0)
     57      1.1  christos     trace_start_error_with_name (("ptrace"));
     58      1.1  christos 
     59      1.1  christos   /* If GDBserver is connected to gdb via stdio, redirect the inferior's
     60      1.1  christos      stdout to stderr so that inferior i/o doesn't corrupt the connection.
     61      1.1  christos      Also, redirect stdin to /dev/null.  */
     62      1.1  christos   if (remote_connection_is_stdio ())
     63      1.1  christos     {
     64      1.1  christos       if (close (0) < 0)
     65      1.1  christos 	trace_start_error_with_name (("close"));
     66      1.1  christos       if (open ("/dev/null", O_RDONLY) < 0)
     67      1.1  christos 	trace_start_error_with_name (("open"));
     68      1.1  christos       if (dup2 (2, 1) < 0)
     69      1.1  christos 	trace_start_error_with_name (("dup2"));
     70      1.1  christos       if (write (2, "stdin/stdout redirected\n",
     71      1.1  christos 		 sizeof ("stdin/stdout redirected\n") - 1) < 0)
     72      1.1  christos 	{
     73      1.1  christos 	  /* Errors ignored.  */
     74      1.1  christos 	}
     75      1.1  christos     }
     76      1.1  christos }
     77      1.1  christos 
     78      1.1  christos /* Implement the create_inferior method of the target_ops vector.  */
     79      1.1  christos 
     80      1.1  christos int
     81      1.1  christos netbsd_process_target::create_inferior (const char *program,
     82      1.1  christos 					const std::vector<char *> &program_args)
     83      1.1  christos {
     84      1.1  christos   std::string str_program_args = construct_inferior_arguments (program_args);
     85      1.1  christos 
     86      1.1  christos   pid_t pid = fork_inferior (program, str_program_args.c_str (),
     87      1.1  christos 			     get_environ ()->envp (), netbsd_ptrace_fun,
     88      1.1  christos 			     nullptr, nullptr, nullptr, nullptr);
     89      1.1  christos 
     90  1.1.1.2  christos   add_process (pid, 0);
     91      1.1  christos 
     92      1.1  christos   post_fork_inferior (pid, program);
     93      1.1  christos 
     94      1.1  christos   return pid;
     95      1.1  christos }
     96      1.1  christos 
     97      1.1  christos /* Implement the post_create_inferior target_ops method.  */
     98      1.1  christos 
     99      1.1  christos void
    100      1.1  christos netbsd_process_target::post_create_inferior ()
    101      1.1  christos {
    102      1.1  christos   pid_t pid = current_process ()->pid;
    103      1.1  christos   netbsd_nat::enable_proc_events (pid);
    104  1.1.1.2  christos 
    105  1.1.1.2  christos   low_arch_setup ();
    106      1.1  christos }
    107      1.1  christos 
    108      1.1  christos /* Implement the attach target_ops method.  */
    109      1.1  christos 
    110      1.1  christos int
    111      1.1  christos netbsd_process_target::attach (unsigned long pid)
    112      1.1  christos {
    113      1.1  christos   /* Unimplemented.  */
    114      1.1  christos   return -1;
    115      1.1  christos }
    116      1.1  christos 
    117      1.1  christos /* Returns true if GDB is interested in any child syscalls.  */
    118      1.1  christos 
    119      1.1  christos static bool
    120      1.1  christos gdb_catching_syscalls_p (pid_t pid)
    121      1.1  christos {
    122      1.1  christos   struct process_info *proc = find_process_pid (pid);
    123      1.1  christos   return !proc->syscalls_to_catch.empty ();
    124      1.1  christos }
    125      1.1  christos 
    126      1.1  christos /* Implement the resume target_ops method.  */
    127      1.1  christos 
    128      1.1  christos void
    129      1.1  christos netbsd_process_target::resume (struct thread_resume *resume_info, size_t n)
    130      1.1  christos {
    131      1.1  christos   ptid_t resume_ptid = resume_info[0].thread;
    132      1.1  christos   const int signal = resume_info[0].sig;
    133      1.1  christos   const bool step = resume_info[0].kind == resume_step;
    134      1.1  christos 
    135      1.1  christos   if (resume_ptid == minus_one_ptid)
    136      1.1  christos     resume_ptid = ptid_of (current_thread);
    137      1.1  christos 
    138      1.1  christos   const pid_t pid = resume_ptid.pid ();
    139      1.1  christos   const lwpid_t lwp = resume_ptid.lwp ();
    140      1.1  christos   regcache_invalidate_pid (pid);
    141      1.1  christos 
    142      1.1  christos   auto fn
    143      1.1  christos     = [&] (ptid_t ptid)
    144      1.1  christos       {
    145      1.1  christos 	if (step)
    146      1.1  christos 	  {
    147      1.1  christos 	    if (ptid.lwp () == lwp || n != 1)
    148      1.1  christos 	      {
    149      1.1  christos 		if (ptrace (PT_SETSTEP, pid, NULL, ptid.lwp ()) == -1)
    150      1.1  christos 		  perror_with_name (("ptrace"));
    151      1.1  christos 		if (ptrace (PT_RESUME, pid, NULL, ptid.lwp ()) == -1)
    152      1.1  christos 		  perror_with_name (("ptrace"));
    153      1.1  christos 	      }
    154      1.1  christos 	    else
    155      1.1  christos 	      {
    156      1.1  christos 		if (ptrace (PT_CLEARSTEP, pid, NULL, ptid.lwp ()) == -1)
    157      1.1  christos 		  perror_with_name (("ptrace"));
    158      1.1  christos 		if (ptrace (PT_SUSPEND, pid, NULL, ptid.lwp ()) == -1)
    159      1.1  christos 		  perror_with_name (("ptrace"));
    160      1.1  christos 	      }
    161      1.1  christos 	  }
    162      1.1  christos 	else
    163      1.1  christos 	  {
    164      1.1  christos 	    if (ptrace (PT_CLEARSTEP, pid, NULL, ptid.lwp ()) == -1)
    165      1.1  christos 	      perror_with_name (("ptrace"));
    166      1.1  christos 	    if (ptrace (PT_RESUME, pid, NULL, ptid.lwp ()) == -1)
    167      1.1  christos 	      perror_with_name (("ptrace"));
    168      1.1  christos 	  }
    169      1.1  christos       };
    170      1.1  christos 
    171      1.1  christos   netbsd_nat::for_each_thread (pid, fn);
    172      1.1  christos 
    173      1.1  christos   int request = gdb_catching_syscalls_p (pid) ? PT_CONTINUE : PT_SYSCALL;
    174      1.1  christos 
    175      1.1  christos   errno = 0;
    176      1.1  christos   ptrace (request, pid, (void *)1, signal);
    177      1.1  christos   if (errno)
    178      1.1  christos     perror_with_name (("ptrace"));
    179      1.1  christos }
    180      1.1  christos 
    181      1.1  christos /* Returns true if GDB is interested in the reported SYSNO syscall.  */
    182      1.1  christos 
    183      1.1  christos static bool
    184      1.1  christos netbsd_catch_this_syscall (int sysno)
    185      1.1  christos {
    186      1.1  christos   struct process_info *proc = current_process ();
    187      1.1  christos 
    188      1.1  christos   if (proc->syscalls_to_catch.empty ())
    189      1.1  christos     return false;
    190      1.1  christos 
    191      1.1  christos   if (proc->syscalls_to_catch[0] == ANY_SYSCALL)
    192      1.1  christos     return true;
    193      1.1  christos 
    194      1.1  christos   for (int iter : proc->syscalls_to_catch)
    195      1.1  christos     if (iter == sysno)
    196      1.1  christos       return true;
    197      1.1  christos 
    198      1.1  christos   return false;
    199      1.1  christos }
    200      1.1  christos 
    201      1.1  christos /* Helper function for child_wait and the derivatives of child_wait.
    202      1.1  christos    HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
    203      1.1  christos    translation of that in OURSTATUS.  */
    204      1.1  christos 
    205      1.1  christos static void
    206      1.1  christos netbsd_store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
    207      1.1  christos {
    208      1.1  christos   if (WIFEXITED (hoststatus))
    209  1.1.1.2  christos     ourstatus->set_exited (WEXITSTATUS (hoststatus));
    210      1.1  christos   else if (!WIFSTOPPED (hoststatus))
    211  1.1.1.2  christos     ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (hoststatus)));
    212      1.1  christos   else
    213  1.1.1.2  christos     ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (hoststatus)));
    214      1.1  christos }
    215      1.1  christos 
    216      1.1  christos /* Implement a safe wrapper around waitpid().  */
    217      1.1  christos 
    218      1.1  christos static pid_t
    219  1.1.1.2  christos netbsd_waitpid (ptid_t ptid, struct target_waitstatus *ourstatus,
    220  1.1.1.2  christos 		target_wait_flags target_options)
    221      1.1  christos {
    222      1.1  christos   int status;
    223  1.1.1.2  christos   int options = (target_options & TARGET_WNOHANG) ? WNOHANG : 0;
    224      1.1  christos 
    225      1.1  christos   pid_t pid
    226  1.1.1.2  christos     = gdb::handle_eintr (-1, ::waitpid, ptid.pid (), &status, options);
    227      1.1  christos 
    228      1.1  christos   if (pid == -1)
    229      1.1  christos     perror_with_name (_("Child process unexpectedly missing"));
    230      1.1  christos 
    231      1.1  christos   netbsd_store_waitstatus (ourstatus, status);
    232      1.1  christos   return pid;
    233      1.1  christos }
    234      1.1  christos 
    235      1.1  christos 
    236      1.1  christos /* Implement the wait target_ops method.
    237      1.1  christos 
    238      1.1  christos    Wait for the child specified by PTID to do something.  Return the
    239      1.1  christos    process ID of the child, or MINUS_ONE_PTID in case of error; store
    240      1.1  christos    the status in *OURSTATUS.  */
    241      1.1  christos 
    242      1.1  christos static ptid_t
    243      1.1  christos netbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus,
    244  1.1.1.2  christos 	     target_wait_flags target_options)
    245      1.1  christos {
    246      1.1  christos   pid_t pid = netbsd_waitpid (ptid, ourstatus, target_options);
    247      1.1  christos   ptid_t wptid = ptid_t (pid);
    248      1.1  christos 
    249      1.1  christos   if (pid == 0)
    250      1.1  christos     {
    251      1.1  christos       gdb_assert (target_options & TARGET_WNOHANG);
    252  1.1.1.2  christos       ourstatus->set_ignore ();
    253      1.1  christos       return null_ptid;
    254      1.1  christos     }
    255      1.1  christos 
    256      1.1  christos   gdb_assert (pid != -1);
    257      1.1  christos 
    258      1.1  christos   /* If the child stopped, keep investigating its status.  */
    259  1.1.1.2  christos   if (ourstatus->kind () != TARGET_WAITKIND_STOPPED)
    260      1.1  christos     return wptid;
    261      1.1  christos 
    262      1.1  christos   /* Extract the event and thread that received a signal.  */
    263      1.1  christos   ptrace_siginfo_t psi;
    264      1.1  christos   if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
    265      1.1  christos     perror_with_name (("ptrace"));
    266      1.1  christos 
    267      1.1  christos   /* Pick child's siginfo_t.  */
    268      1.1  christos   siginfo_t *si = &psi.psi_siginfo;
    269      1.1  christos 
    270      1.1  christos   lwpid_t lwp = psi.psi_lwpid;
    271      1.1  christos 
    272      1.1  christos   int signo = si->si_signo;
    273      1.1  christos   const int code = si->si_code;
    274      1.1  christos 
    275      1.1  christos   /* Construct PTID with a specified thread that received the event.
    276      1.1  christos      If a signal was targeted to the whole process, lwp is 0.  */
    277      1.1  christos   wptid = ptid_t (pid, lwp, 0);
    278      1.1  christos 
    279      1.1  christos   /* Bail out on non-debugger oriented signals.  */
    280      1.1  christos   if (signo != SIGTRAP)
    281      1.1  christos     return wptid;
    282      1.1  christos 
    283      1.1  christos   /* Stop examining non-debugger oriented SIGTRAP codes.  */
    284      1.1  christos   if (code <= SI_USER || code == SI_NOINFO)
    285      1.1  christos     return wptid;
    286      1.1  christos 
    287      1.1  christos   /* Process state for threading events.  */
    288      1.1  christos   ptrace_state_t pst = {};
    289      1.1  christos   if (code == TRAP_LWP)
    290      1.1  christos     if (ptrace (PT_GET_PROCESS_STATE, pid, &pst, sizeof (pst)) == -1)
    291      1.1  christos       perror_with_name (("ptrace"));
    292      1.1  christos 
    293      1.1  christos   if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_EXIT)
    294      1.1  christos     {
    295      1.1  christos       /* If GDB attaches to a multi-threaded process, exiting
    296      1.1  christos 	 threads might be skipped during post_attach that
    297      1.1  christos 	 have not yet reported their PTRACE_LWP_EXIT event.
    298      1.1  christos 	 Ignore exited events for an unknown LWP.  */
    299      1.1  christos       thread_info *thr = find_thread_ptid (wptid);
    300      1.1  christos       if (thr == nullptr)
    301  1.1.1.2  christos 	  ourstatus->set_spurious ();
    302      1.1  christos       else
    303      1.1  christos 	{
    304      1.1  christos 	  /* NetBSD does not store an LWP exit status.  */
    305  1.1.1.2  christos 	  ourstatus->set_thread_exited (0);
    306      1.1  christos 
    307      1.1  christos 	  remove_thread (thr);
    308      1.1  christos 	}
    309      1.1  christos       return wptid;
    310      1.1  christos     }
    311      1.1  christos 
    312      1.1  christos   if (find_thread_ptid (ptid_t (pid)))
    313  1.1.1.2  christos     switch_to_thread (find_thread_ptid (wptid));
    314      1.1  christos 
    315      1.1  christos   if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE)
    316      1.1  christos     {
    317      1.1  christos       /* If GDB attaches to a multi-threaded process, newborn
    318      1.1  christos 	 threads might be added by nbsd_add_threads that have
    319      1.1  christos 	 not yet reported their PTRACE_LWP_CREATE event.  Ignore
    320      1.1  christos 	 born events for an already-known LWP.  */
    321      1.1  christos       if (find_thread_ptid (wptid))
    322  1.1.1.2  christos 	ourstatus->set_spurious ();
    323      1.1  christos       else
    324      1.1  christos 	{
    325      1.1  christos 	  add_thread (wptid, NULL);
    326  1.1.1.2  christos 	  ourstatus->set_thread_created ();
    327      1.1  christos 	}
    328      1.1  christos       return wptid;
    329      1.1  christos     }
    330      1.1  christos 
    331      1.1  christos   if (code == TRAP_EXEC)
    332      1.1  christos     {
    333  1.1.1.2  christos       ourstatus->set_execd
    334  1.1.1.2  christos 	(make_unique_xstrdup (netbsd_nat::pid_to_exec_file (pid)));
    335      1.1  christos       return wptid;
    336      1.1  christos     }
    337      1.1  christos 
    338      1.1  christos   if (code == TRAP_TRACE)
    339      1.1  christos       return wptid;
    340      1.1  christos 
    341      1.1  christos   if (code == TRAP_SCE || code == TRAP_SCX)
    342      1.1  christos     {
    343      1.1  christos       int sysnum = si->si_sysnum;
    344      1.1  christos 
    345      1.1  christos       if (!netbsd_catch_this_syscall(sysnum))
    346      1.1  christos 	{
    347      1.1  christos 	  /* If the core isn't interested in this event, ignore it.  */
    348  1.1.1.2  christos 	  ourstatus->set_spurious ();
    349      1.1  christos 	  return wptid;
    350      1.1  christos 	}
    351      1.1  christos 
    352  1.1.1.2  christos       if (code == TRAP_SCE)
    353  1.1.1.2  christos 	ourstatus->set_syscall_entry (sysnum);
    354  1.1.1.2  christos       else
    355  1.1.1.2  christos 	ourstatus->set_syscall_return (sysnum);
    356  1.1.1.2  christos 
    357      1.1  christos       return wptid;
    358      1.1  christos     }
    359      1.1  christos 
    360      1.1  christos   if (code == TRAP_BRKPT)
    361      1.1  christos     {
    362      1.1  christos #ifdef PTRACE_BREAKPOINT_ADJ
    363      1.1  christos       CORE_ADDR pc;
    364      1.1  christos       struct reg r;
    365      1.1  christos       ptrace (PT_GETREGS, pid, &r, psi.psi_lwpid);
    366      1.1  christos       pc = PTRACE_REG_PC (&r);
    367      1.1  christos       PTRACE_REG_SET_PC (&r, pc - PTRACE_BREAKPOINT_ADJ);
    368      1.1  christos       ptrace (PT_SETREGS, pid, &r, psi.psi_lwpid);
    369      1.1  christos #endif
    370      1.1  christos       return wptid;
    371      1.1  christos     }
    372      1.1  christos 
    373      1.1  christos   /* Unclassified SIGTRAP event.  */
    374  1.1.1.2  christos   ourstatus->set_spurious ();
    375      1.1  christos   return wptid;
    376      1.1  christos }
    377      1.1  christos 
    378      1.1  christos /* Implement the wait target_ops method.  */
    379      1.1  christos 
    380      1.1  christos ptid_t
    381      1.1  christos netbsd_process_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
    382  1.1.1.2  christos 			     target_wait_flags target_options)
    383      1.1  christos {
    384      1.1  christos   while (true)
    385      1.1  christos     {
    386      1.1  christos       ptid_t wptid = netbsd_wait (ptid, ourstatus, target_options);
    387      1.1  christos 
    388      1.1  christos       /* Register thread in the gdbcore if a thread was not reported earlier.
    389      1.1  christos 	 This is required after ::create_inferior, when the gdbcore does not
    390      1.1  christos 	 know about the first internal thread.
    391      1.1  christos 	 This may also happen on attach, when an event is registered on a thread
    392      1.1  christos 	 that was not fully initialized during the attach stage.  */
    393      1.1  christos       if (wptid.lwp () != 0 && !find_thread_ptid (wptid)
    394  1.1.1.2  christos 	  && ourstatus->kind () != TARGET_WAITKIND_THREAD_EXITED)
    395      1.1  christos 	add_thread (wptid, nullptr);
    396      1.1  christos 
    397  1.1.1.2  christos       switch (ourstatus->kind ())
    398      1.1  christos 	{
    399      1.1  christos 	case TARGET_WAITKIND_EXITED:
    400      1.1  christos 	case TARGET_WAITKIND_STOPPED:
    401      1.1  christos 	case TARGET_WAITKIND_SIGNALLED:
    402      1.1  christos 	case TARGET_WAITKIND_FORKED:
    403      1.1  christos 	case TARGET_WAITKIND_VFORKED:
    404      1.1  christos 	case TARGET_WAITKIND_EXECD:
    405      1.1  christos 	case TARGET_WAITKIND_VFORK_DONE:
    406      1.1  christos 	case TARGET_WAITKIND_SYSCALL_ENTRY:
    407      1.1  christos 	case TARGET_WAITKIND_SYSCALL_RETURN:
    408      1.1  christos 	  /* Pass the result to the generic code.  */
    409      1.1  christos 	  return wptid;
    410      1.1  christos 	case TARGET_WAITKIND_THREAD_CREATED:
    411      1.1  christos 	case TARGET_WAITKIND_THREAD_EXITED:
    412      1.1  christos 	  /* The core needlessly stops on these events.  */
    413      1.1  christos 	  /* FALLTHROUGH */
    414      1.1  christos 	case TARGET_WAITKIND_SPURIOUS:
    415      1.1  christos 	  /* Spurious events are unhandled by the gdbserver core.  */
    416      1.1  christos 	  if (ptrace (PT_CONTINUE, current_process ()->pid, (void *) 1, 0)
    417      1.1  christos 	      == -1)
    418      1.1  christos 	    perror_with_name (("ptrace"));
    419      1.1  christos 	  break;
    420      1.1  christos 	default:
    421      1.1  christos 	  error (("Unknown stopped status"));
    422      1.1  christos 	}
    423      1.1  christos     }
    424      1.1  christos }
    425      1.1  christos 
    426      1.1  christos /* Implement the kill target_ops method.  */
    427      1.1  christos 
    428      1.1  christos int
    429      1.1  christos netbsd_process_target::kill (process_info *process)
    430      1.1  christos {
    431      1.1  christos   pid_t pid = process->pid;
    432      1.1  christos   if (ptrace (PT_KILL, pid, nullptr, 0) == -1)
    433      1.1  christos     return -1;
    434      1.1  christos 
    435      1.1  christos   int status;
    436  1.1.1.2  christos   if (gdb::handle_eintr (-1, ::waitpid, pid, &status, 0) == -1)
    437      1.1  christos     return -1;
    438      1.1  christos   mourn (process);
    439      1.1  christos   return 0;
    440      1.1  christos }
    441      1.1  christos 
    442      1.1  christos /* Implement the detach target_ops method.  */
    443      1.1  christos 
    444      1.1  christos int
    445      1.1  christos netbsd_process_target::detach (process_info *process)
    446      1.1  christos {
    447      1.1  christos   pid_t pid = process->pid;
    448      1.1  christos 
    449      1.1  christos   ptrace (PT_DETACH, pid, (void *) 1, 0);
    450      1.1  christos   mourn (process);
    451      1.1  christos   return 0;
    452      1.1  christos }
    453      1.1  christos 
    454      1.1  christos /* Implement the mourn target_ops method.  */
    455      1.1  christos 
    456      1.1  christos void
    457      1.1  christos netbsd_process_target::mourn (struct process_info *proc)
    458      1.1  christos {
    459      1.1  christos   for_each_thread (proc->pid, remove_thread);
    460      1.1  christos 
    461      1.1  christos   remove_process (proc);
    462      1.1  christos }
    463      1.1  christos 
    464      1.1  christos /* Implement the join target_ops method.  */
    465      1.1  christos 
    466      1.1  christos void
    467      1.1  christos netbsd_process_target::join (int pid)
    468      1.1  christos {
    469      1.1  christos   /* The PT_DETACH is sufficient to detach from the process.
    470      1.1  christos      So no need to do anything extra.  */
    471      1.1  christos }
    472      1.1  christos 
    473      1.1  christos /* Implement the thread_alive target_ops method.  */
    474      1.1  christos 
    475      1.1  christos bool
    476      1.1  christos netbsd_process_target::thread_alive (ptid_t ptid)
    477      1.1  christos {
    478      1.1  christos   return netbsd_nat::thread_alive (ptid);
    479      1.1  christos }
    480      1.1  christos 
    481      1.1  christos /* Implement the fetch_registers target_ops method.  */
    482      1.1  christos 
    483      1.1  christos void
    484      1.1  christos netbsd_process_target::fetch_registers (struct regcache *regcache, int regno)
    485      1.1  christos {
    486  1.1.1.2  christos   const netbsd_regset_info *regset = get_regs_info ();
    487      1.1  christos   ptid_t inferior_ptid = ptid_of (current_thread);
    488      1.1  christos 
    489      1.1  christos   while (regset->size >= 0)
    490      1.1  christos     {
    491      1.1  christos       std::vector<char> buf;
    492      1.1  christos       buf.resize (regset->size);
    493      1.1  christos       int res = ptrace (regset->get_request, inferior_ptid.pid (), buf.data (),
    494      1.1  christos 			inferior_ptid.lwp ());
    495      1.1  christos       if (res == -1)
    496      1.1  christos 	perror_with_name (("ptrace"));
    497      1.1  christos       regset->store_function (regcache, buf.data ());
    498      1.1  christos       regset++;
    499      1.1  christos     }
    500      1.1  christos }
    501      1.1  christos 
    502      1.1  christos /* Implement the store_registers target_ops method.  */
    503      1.1  christos 
    504      1.1  christos void
    505      1.1  christos netbsd_process_target::store_registers (struct regcache *regcache, int regno)
    506      1.1  christos {
    507  1.1.1.2  christos   const netbsd_regset_info *regset = get_regs_info ();
    508      1.1  christos   ptid_t inferior_ptid = ptid_of (current_thread);
    509      1.1  christos 
    510      1.1  christos   while (regset->size >= 0)
    511      1.1  christos     {
    512      1.1  christos       std::vector<char> buf;
    513      1.1  christos       buf.resize (regset->size);
    514      1.1  christos       int res = ptrace (regset->get_request, inferior_ptid.pid (), buf.data (),
    515      1.1  christos 			inferior_ptid.lwp ());
    516      1.1  christos       if (res == -1)
    517      1.1  christos 	perror_with_name (("ptrace"));
    518      1.1  christos 
    519      1.1  christos       /* Then overlay our cached registers on that.  */
    520      1.1  christos       regset->fill_function (regcache, buf.data ());
    521      1.1  christos       /* Only now do we write the register set.  */
    522      1.1  christos       res = ptrace (regset->set_request, inferior_ptid.pid (), buf. data (),
    523      1.1  christos 		    inferior_ptid.lwp ());
    524      1.1  christos       if (res == -1)
    525      1.1  christos 	perror_with_name (("ptrace"));
    526      1.1  christos       regset++;
    527      1.1  christos     }
    528      1.1  christos }
    529      1.1  christos 
    530      1.1  christos /* Implement the read_memory target_ops method.  */
    531      1.1  christos 
    532      1.1  christos int
    533      1.1  christos netbsd_process_target::read_memory (CORE_ADDR memaddr, unsigned char *myaddr,
    534      1.1  christos 				    int size)
    535      1.1  christos {
    536      1.1  christos   pid_t pid = current_process ()->pid;
    537  1.1.1.2  christos   return netbsd_nat::read_memory (pid, myaddr, memaddr, size, nullptr);
    538      1.1  christos }
    539      1.1  christos 
    540      1.1  christos /* Implement the write_memory target_ops method.  */
    541      1.1  christos 
    542      1.1  christos int
    543      1.1  christos netbsd_process_target::write_memory (CORE_ADDR memaddr,
    544      1.1  christos 				     const unsigned char *myaddr, int size)
    545      1.1  christos {
    546      1.1  christos   pid_t pid = current_process ()->pid;
    547  1.1.1.2  christos   return netbsd_nat::write_memory (pid, myaddr, memaddr, size, nullptr);
    548      1.1  christos }
    549      1.1  christos 
    550      1.1  christos /* Implement the request_interrupt target_ops method.  */
    551      1.1  christos 
    552      1.1  christos void
    553      1.1  christos netbsd_process_target::request_interrupt ()
    554      1.1  christos {
    555      1.1  christos   ptid_t inferior_ptid = ptid_of (get_first_thread ());
    556      1.1  christos 
    557  1.1.1.2  christos   ::kill (inferior_ptid.pid (), SIGINT);
    558      1.1  christos }
    559      1.1  christos 
    560      1.1  christos /* Read the AUX Vector for the specified PID, wrapping the ptrace(2) call
    561      1.1  christos    with the PIOD_READ_AUXV operation and using the PT_IO standard input
    562      1.1  christos    and output arguments.  */
    563      1.1  christos 
    564      1.1  christos static size_t
    565      1.1  christos netbsd_read_auxv(pid_t pid, void *offs, void *addr, size_t len)
    566      1.1  christos {
    567      1.1  christos   struct ptrace_io_desc pio;
    568      1.1  christos 
    569      1.1  christos   pio.piod_op = PIOD_READ_AUXV;
    570      1.1  christos   pio.piod_offs = offs;
    571      1.1  christos   pio.piod_addr = addr;
    572      1.1  christos   pio.piod_len = len;
    573      1.1  christos 
    574      1.1  christos   if (ptrace (PT_IO, pid, &pio, 0) == -1)
    575      1.1  christos     perror_with_name (("ptrace"));
    576      1.1  christos 
    577      1.1  christos   return pio.piod_len;
    578      1.1  christos }
    579      1.1  christos 
    580      1.1  christos /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
    581      1.1  christos    to debugger memory starting at MYADDR.  */
    582      1.1  christos 
    583      1.1  christos int
    584      1.1  christos netbsd_process_target::read_auxv (CORE_ADDR offset,
    585      1.1  christos 				  unsigned char *myaddr, unsigned int len)
    586      1.1  christos {
    587      1.1  christos   pid_t pid = pid_of (current_thread);
    588      1.1  christos 
    589      1.1  christos   return netbsd_read_auxv (pid, (void *) (intptr_t) offset, myaddr, len);
    590      1.1  christos }
    591      1.1  christos 
    592      1.1  christos bool
    593      1.1  christos netbsd_process_target::supports_z_point_type (char z_type)
    594      1.1  christos {
    595      1.1  christos   switch (z_type)
    596      1.1  christos     {
    597      1.1  christos     case Z_PACKET_SW_BP:
    598      1.1  christos       return true;
    599      1.1  christos     case Z_PACKET_HW_BP:
    600      1.1  christos     case Z_PACKET_WRITE_WP:
    601      1.1  christos     case Z_PACKET_READ_WP:
    602      1.1  christos     case Z_PACKET_ACCESS_WP:
    603      1.1  christos     default:
    604      1.1  christos       return false; /* Not supported.  */
    605      1.1  christos     }
    606      1.1  christos }
    607      1.1  christos 
    608      1.1  christos /* Insert {break/watch}point at address ADDR.  SIZE is not used.  */
    609      1.1  christos 
    610      1.1  christos int
    611      1.1  christos netbsd_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
    612      1.1  christos 		     int size, struct raw_breakpoint *bp)
    613      1.1  christos {
    614      1.1  christos   switch (type)
    615      1.1  christos     {
    616      1.1  christos     case raw_bkpt_type_sw:
    617      1.1  christos       return insert_memory_breakpoint (bp);
    618      1.1  christos     case raw_bkpt_type_hw:
    619      1.1  christos     case raw_bkpt_type_write_wp:
    620      1.1  christos     case raw_bkpt_type_read_wp:
    621      1.1  christos     case raw_bkpt_type_access_wp:
    622      1.1  christos     default:
    623      1.1  christos       return 1; /* Not supported.  */
    624      1.1  christos     }
    625      1.1  christos }
    626      1.1  christos 
    627      1.1  christos /* Remove {break/watch}point at address ADDR.  SIZE is not used.  */
    628      1.1  christos 
    629      1.1  christos int
    630      1.1  christos netbsd_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
    631      1.1  christos 				     int size, struct raw_breakpoint *bp)
    632      1.1  christos {
    633      1.1  christos   switch (type)
    634      1.1  christos     {
    635      1.1  christos     case raw_bkpt_type_sw:
    636      1.1  christos       return remove_memory_breakpoint (bp);
    637      1.1  christos     case raw_bkpt_type_hw:
    638      1.1  christos     case raw_bkpt_type_write_wp:
    639      1.1  christos     case raw_bkpt_type_read_wp:
    640      1.1  christos     case raw_bkpt_type_access_wp:
    641      1.1  christos     default:
    642      1.1  christos       return 1; /* Not supported.  */
    643      1.1  christos     }
    644      1.1  christos }
    645      1.1  christos 
    646      1.1  christos /* Implement the stopped_by_sw_breakpoint target_ops method.  */
    647      1.1  christos 
    648      1.1  christos bool
    649      1.1  christos netbsd_process_target::stopped_by_sw_breakpoint ()
    650      1.1  christos {
    651      1.1  christos   ptrace_siginfo_t psi;
    652      1.1  christos   pid_t pid = current_process ()->pid;
    653      1.1  christos 
    654      1.1  christos   if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
    655      1.1  christos     perror_with_name (("ptrace"));
    656      1.1  christos 
    657      1.1  christos   return psi.psi_siginfo.si_signo == SIGTRAP &&
    658      1.1  christos 	 psi.psi_siginfo.si_code == TRAP_BRKPT;
    659      1.1  christos }
    660      1.1  christos 
    661      1.1  christos /* Implement the supports_stopped_by_sw_breakpoint target_ops method.  */
    662      1.1  christos 
    663      1.1  christos bool
    664      1.1  christos netbsd_process_target::supports_stopped_by_sw_breakpoint ()
    665      1.1  christos {
    666      1.1  christos   return true;
    667      1.1  christos }
    668      1.1  christos 
    669      1.1  christos /* Implement the supports_qxfer_siginfo target_ops method.  */
    670      1.1  christos 
    671      1.1  christos bool
    672      1.1  christos netbsd_process_target::supports_qxfer_siginfo ()
    673      1.1  christos {
    674      1.1  christos   return true;
    675      1.1  christos }
    676      1.1  christos 
    677      1.1  christos /* Implement the qxfer_siginfo target_ops method.  */
    678      1.1  christos 
    679      1.1  christos int
    680      1.1  christos netbsd_process_target::qxfer_siginfo (const char *annex, unsigned char *readbuf,
    681      1.1  christos 				      unsigned const char *writebuf,
    682      1.1  christos 				      CORE_ADDR offset, int len)
    683      1.1  christos {
    684      1.1  christos   if (current_thread == nullptr)
    685      1.1  christos     return -1;
    686      1.1  christos 
    687      1.1  christos   pid_t pid = current_process ()->pid;
    688      1.1  christos 
    689      1.1  christos   return netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset, len);
    690      1.1  christos }
    691      1.1  christos 
    692      1.1  christos /* Implement the supports_non_stop target_ops method.  */
    693      1.1  christos 
    694      1.1  christos bool
    695      1.1  christos netbsd_process_target::supports_non_stop ()
    696      1.1  christos {
    697      1.1  christos   return false;
    698      1.1  christos }
    699      1.1  christos 
    700      1.1  christos /* Implement the supports_multi_process target_ops method.  */
    701      1.1  christos 
    702      1.1  christos bool
    703      1.1  christos netbsd_process_target::supports_multi_process ()
    704      1.1  christos {
    705      1.1  christos   return true;
    706      1.1  christos }
    707      1.1  christos 
    708      1.1  christos /* Check if fork events are supported.  */
    709      1.1  christos 
    710      1.1  christos bool
    711      1.1  christos netbsd_process_target::supports_fork_events ()
    712      1.1  christos {
    713      1.1  christos   return false;
    714      1.1  christos }
    715      1.1  christos 
    716      1.1  christos /* Check if vfork events are supported.  */
    717      1.1  christos 
    718      1.1  christos bool
    719      1.1  christos netbsd_process_target::supports_vfork_events ()
    720      1.1  christos {
    721      1.1  christos   return false;
    722      1.1  christos }
    723      1.1  christos 
    724      1.1  christos /* Check if exec events are supported.  */
    725      1.1  christos 
    726      1.1  christos bool
    727      1.1  christos netbsd_process_target::supports_exec_events ()
    728      1.1  christos {
    729      1.1  christos   return true;
    730      1.1  christos }
    731      1.1  christos 
    732      1.1  christos /* Implement the supports_disable_randomization target_ops method.  */
    733      1.1  christos 
    734      1.1  christos bool
    735      1.1  christos netbsd_process_target::supports_disable_randomization ()
    736      1.1  christos {
    737      1.1  christos   return false;
    738      1.1  christos }
    739      1.1  christos 
    740      1.1  christos /* Extract &phdr and num_phdr in the inferior.  Return 0 on success.  */
    741      1.1  christos 
    742      1.1  christos template <typename T>
    743      1.1  christos int get_phdr_phnum_from_proc_auxv (const pid_t pid,
    744      1.1  christos 				   CORE_ADDR *phdr_memaddr, int *num_phdr)
    745      1.1  christos {
    746      1.1  christos   typedef typename std::conditional<sizeof(T) == sizeof(int64_t),
    747      1.1  christos 				    Aux64Info, Aux32Info>::type auxv_type;
    748      1.1  christos   const size_t auxv_size = sizeof (auxv_type);
    749      1.1  christos   const size_t auxv_buf_size = 128 * sizeof (auxv_type);
    750      1.1  christos 
    751      1.1  christos   std::vector<char> auxv_buf;
    752      1.1  christos   auxv_buf.resize (auxv_buf_size);
    753      1.1  christos 
    754      1.1  christos   netbsd_read_auxv (pid, nullptr, auxv_buf.data (), auxv_buf_size);
    755      1.1  christos 
    756      1.1  christos   *phdr_memaddr = 0;
    757      1.1  christos   *num_phdr = 0;
    758      1.1  christos 
    759      1.1  christos   for (char *buf = auxv_buf.data ();
    760      1.1  christos        buf < (auxv_buf.data () + auxv_buf_size);
    761      1.1  christos        buf += auxv_size)
    762      1.1  christos     {
    763      1.1  christos       auxv_type *const aux = (auxv_type *) buf;
    764      1.1  christos 
    765      1.1  christos       switch (aux->a_type)
    766      1.1  christos 	{
    767      1.1  christos 	case AT_PHDR:
    768      1.1  christos 	  *phdr_memaddr = aux->a_v;
    769      1.1  christos 	  break;
    770      1.1  christos 	case AT_PHNUM:
    771      1.1  christos 	  *num_phdr = aux->a_v;
    772      1.1  christos 	  break;
    773      1.1  christos 	}
    774      1.1  christos 
    775      1.1  christos       if (*phdr_memaddr != 0 && *num_phdr != 0)
    776      1.1  christos 	break;
    777      1.1  christos     }
    778      1.1  christos 
    779      1.1  christos   if (*phdr_memaddr == 0 || *num_phdr == 0)
    780      1.1  christos     {
    781      1.1  christos       warning ("Unexpected missing AT_PHDR and/or AT_PHNUM: "
    782      1.1  christos 	       "phdr_memaddr = %s, phdr_num = %d",
    783      1.1  christos 	       core_addr_to_string (*phdr_memaddr), *num_phdr);
    784      1.1  christos       return 2;
    785      1.1  christos     }
    786      1.1  christos 
    787      1.1  christos   return 0;
    788      1.1  christos }
    789      1.1  christos 
    790      1.1  christos /* Return &_DYNAMIC (via PT_DYNAMIC) in the inferior, or 0 if not present.  */
    791      1.1  christos 
    792      1.1  christos template <typename T>
    793      1.1  christos static CORE_ADDR
    794  1.1.1.2  christos get_dynamic (const pid_t pid)
    795      1.1  christos {
    796      1.1  christos   typedef typename std::conditional<sizeof(T) == sizeof(int64_t),
    797      1.1  christos 				    Elf64_Phdr, Elf32_Phdr>::type phdr_type;
    798      1.1  christos   const int phdr_size = sizeof (phdr_type);
    799      1.1  christos 
    800      1.1  christos   CORE_ADDR phdr_memaddr;
    801      1.1  christos   int num_phdr;
    802      1.1  christos   if (get_phdr_phnum_from_proc_auxv<T> (pid, &phdr_memaddr, &num_phdr))
    803      1.1  christos     return 0;
    804      1.1  christos 
    805      1.1  christos   std::vector<unsigned char> phdr_buf;
    806      1.1  christos   phdr_buf.resize (num_phdr * phdr_size);
    807      1.1  christos 
    808  1.1.1.2  christos   if (netbsd_nat::read_memory (pid, phdr_buf.data (), phdr_memaddr,
    809  1.1.1.2  christos 			       phdr_buf.size (), nullptr))
    810      1.1  christos     return 0;
    811      1.1  christos 
    812      1.1  christos   /* Compute relocation: it is expected to be 0 for "regular" executables,
    813      1.1  christos      non-zero for PIE ones.  */
    814      1.1  christos   CORE_ADDR relocation = -1;
    815      1.1  christos   for (int i = 0; relocation == -1 && i < num_phdr; i++)
    816      1.1  christos     {
    817  1.1.1.2  christos       phdr_type *const p = (phdr_type *) (phdr_buf.data () + i * phdr_size);
    818      1.1  christos 
    819      1.1  christos       if (p->p_type == PT_PHDR)
    820      1.1  christos 	relocation = phdr_memaddr - p->p_vaddr;
    821      1.1  christos     }
    822      1.1  christos 
    823      1.1  christos   if (relocation == -1)
    824      1.1  christos     {
    825      1.1  christos       /* PT_PHDR is optional, but necessary for PIE in general.  Fortunately
    826      1.1  christos 	 any real world executables, including PIE executables, have always
    827      1.1  christos 	 PT_PHDR present.  PT_PHDR is not present in some shared libraries or
    828      1.1  christos 	 in fpc (Free Pascal 2.4) binaries but neither of those have a need for
    829      1.1  christos 	 or present DT_DEBUG anyway (fpc binaries are statically linked).
    830      1.1  christos 
    831      1.1  christos 	 Therefore if there exists DT_DEBUG there is always also PT_PHDR.
    832      1.1  christos 
    833      1.1  christos 	 GDB could find RELOCATION also from AT_ENTRY - e_entry.  */
    834      1.1  christos 
    835      1.1  christos       return 0;
    836      1.1  christos     }
    837      1.1  christos 
    838      1.1  christos   for (int i = 0; i < num_phdr; i++)
    839      1.1  christos     {
    840      1.1  christos       phdr_type *const p = (phdr_type *) (phdr_buf.data () + i * phdr_size);
    841      1.1  christos 
    842      1.1  christos       if (p->p_type == PT_DYNAMIC)
    843      1.1  christos 	return p->p_vaddr + relocation;
    844      1.1  christos     }
    845      1.1  christos 
    846      1.1  christos   return 0;
    847      1.1  christos }
    848      1.1  christos 
    849      1.1  christos /* Return &_r_debug in the inferior, or -1 if not present.  Return value
    850      1.1  christos    can be 0 if the inferior does not yet have the library list initialized.
    851      1.1  christos    We look for DT_MIPS_RLD_MAP first.  MIPS executables use this instead of
    852      1.1  christos    DT_DEBUG, although they sometimes contain an unused DT_DEBUG entry too.  */
    853      1.1  christos 
    854      1.1  christos template <typename T>
    855      1.1  christos static CORE_ADDR
    856  1.1.1.2  christos get_r_debug (const pid_t pid)
    857      1.1  christos {
    858      1.1  christos   typedef typename std::conditional<sizeof(T) == sizeof(int64_t),
    859      1.1  christos 				    Elf64_Dyn, Elf32_Dyn>::type dyn_type;
    860      1.1  christos   const int dyn_size = sizeof (dyn_type);
    861      1.1  christos   unsigned char buf[sizeof (dyn_type)];  /* The larger of the two.  */
    862      1.1  christos   CORE_ADDR map = -1;
    863      1.1  christos 
    864  1.1.1.2  christos   CORE_ADDR dynamic_memaddr = get_dynamic<T> (pid);
    865      1.1  christos   if (dynamic_memaddr == 0)
    866      1.1  christos     return map;
    867      1.1  christos 
    868  1.1.1.2  christos   while (netbsd_nat::read_memory (pid, buf, dynamic_memaddr, dyn_size, nullptr)
    869  1.1.1.2  christos 	 == 0)
    870      1.1  christos     {
    871      1.1  christos       dyn_type *const dyn = (dyn_type *) buf;
    872      1.1  christos #if defined DT_MIPS_RLD_MAP
    873      1.1  christos       union
    874      1.1  christos       {
    875      1.1  christos 	T map;
    876      1.1  christos 	unsigned char buf[sizeof (T)];
    877      1.1  christos       }
    878      1.1  christos       rld_map;
    879      1.1  christos 
    880      1.1  christos       if (dyn->d_tag == DT_MIPS_RLD_MAP)
    881      1.1  christos 	{
    882  1.1.1.2  christos 	  if (netbsd_nat::read_memory (pid, rld_map.buf, dyn->d_un.d_val,
    883  1.1.1.2  christos 				       sizeof (rld_map.buf), nullptr) == 0)
    884      1.1  christos 	    return rld_map.map;
    885      1.1  christos 	  else
    886      1.1  christos 	    break;
    887      1.1  christos 	}
    888      1.1  christos #endif  /* DT_MIPS_RLD_MAP */
    889      1.1  christos 
    890      1.1  christos       if (dyn->d_tag == DT_DEBUG && map == -1)
    891      1.1  christos 	map = dyn->d_un.d_val;
    892      1.1  christos 
    893      1.1  christos       if (dyn->d_tag == DT_NULL)
    894      1.1  christos 	break;
    895      1.1  christos 
    896      1.1  christos       dynamic_memaddr += dyn_size;
    897      1.1  christos     }
    898      1.1  christos 
    899      1.1  christos   return map;
    900      1.1  christos }
    901      1.1  christos 
    902      1.1  christos /* Read one pointer from MEMADDR in the inferior.  */
    903      1.1  christos 
    904      1.1  christos static int
    905  1.1.1.2  christos read_one_ptr (const pid_t pid, CORE_ADDR memaddr, CORE_ADDR *ptr, int ptr_size)
    906      1.1  christos {
    907      1.1  christos   /* Go through a union so this works on either big or little endian
    908      1.1  christos      hosts, when the inferior's pointer size is smaller than the size
    909      1.1  christos      of CORE_ADDR.  It is assumed the inferior's endianness is the
    910      1.1  christos      same of the superior's.  */
    911      1.1  christos 
    912      1.1  christos   union
    913      1.1  christos   {
    914      1.1  christos     CORE_ADDR core_addr;
    915      1.1  christos     unsigned int ui;
    916      1.1  christos     unsigned char uc;
    917      1.1  christos   } addr;
    918      1.1  christos 
    919  1.1.1.2  christos   int ret = netbsd_nat::read_memory (pid, &addr.uc, memaddr, ptr_size, nullptr);
    920      1.1  christos   if (ret == 0)
    921      1.1  christos     {
    922      1.1  christos       if (ptr_size == sizeof (CORE_ADDR))
    923      1.1  christos 	*ptr = addr.core_addr;
    924      1.1  christos       else if (ptr_size == sizeof (unsigned int))
    925      1.1  christos 	*ptr = addr.ui;
    926      1.1  christos       else
    927      1.1  christos 	gdb_assert_not_reached ("unhandled pointer size");
    928      1.1  christos     }
    929      1.1  christos   return ret;
    930      1.1  christos }
    931      1.1  christos 
    932      1.1  christos /* Construct qXfer:libraries-svr4:read reply.  */
    933      1.1  christos 
    934      1.1  christos template <typename T>
    935      1.1  christos int
    936  1.1.1.2  christos netbsd_qxfer_libraries_svr4 (const pid_t pid, const char *annex,
    937      1.1  christos 			     unsigned char *readbuf,
    938      1.1  christos 			     unsigned const char *writebuf,
    939      1.1  christos 			     CORE_ADDR offset, int len)
    940      1.1  christos {
    941      1.1  christos   struct link_map_offsets
    942      1.1  christos   {
    943      1.1  christos     /* Offset and size of r_debug.r_version.  */
    944      1.1  christos     int r_version_offset;
    945      1.1  christos 
    946      1.1  christos     /* Offset and size of r_debug.r_map.  */
    947      1.1  christos     int r_map_offset;
    948      1.1  christos 
    949      1.1  christos     /* Offset to l_addr field in struct link_map.  */
    950      1.1  christos     int l_addr_offset;
    951      1.1  christos 
    952      1.1  christos     /* Offset to l_name field in struct link_map.  */
    953      1.1  christos     int l_name_offset;
    954      1.1  christos 
    955      1.1  christos     /* Offset to l_ld field in struct link_map.  */
    956      1.1  christos     int l_ld_offset;
    957      1.1  christos 
    958      1.1  christos     /* Offset to l_next field in struct link_map.  */
    959      1.1  christos     int l_next_offset;
    960      1.1  christos 
    961      1.1  christos     /* Offset to l_prev field in struct link_map.  */
    962      1.1  christos     int l_prev_offset;
    963      1.1  christos   };
    964      1.1  christos 
    965      1.1  christos   static const struct link_map_offsets lmo_32bit_offsets =
    966      1.1  christos     {
    967      1.1  christos       0,     /* r_version offset. */
    968      1.1  christos       4,     /* r_debug.r_map offset.  */
    969      1.1  christos       0,     /* l_addr offset in link_map.  */
    970      1.1  christos       4,     /* l_name offset in link_map.  */
    971      1.1  christos       8,     /* l_ld offset in link_map.  */
    972      1.1  christos       12,    /* l_next offset in link_map.  */
    973      1.1  christos       16     /* l_prev offset in link_map.  */
    974      1.1  christos     };
    975      1.1  christos 
    976      1.1  christos   static const struct link_map_offsets lmo_64bit_offsets =
    977      1.1  christos     {
    978      1.1  christos       0,     /* r_version offset. */
    979      1.1  christos       8,     /* r_debug.r_map offset.  */
    980      1.1  christos       0,     /* l_addr offset in link_map.  */
    981      1.1  christos       8,     /* l_name offset in link_map.  */
    982      1.1  christos       16,    /* l_ld offset in link_map.  */
    983      1.1  christos       24,    /* l_next offset in link_map.  */
    984      1.1  christos       32     /* l_prev offset in link_map.  */
    985      1.1  christos     };
    986      1.1  christos 
    987      1.1  christos   CORE_ADDR lm_addr = 0, lm_prev = 0;
    988      1.1  christos   CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
    989      1.1  christos   int header_done = 0;
    990      1.1  christos 
    991      1.1  christos   const struct link_map_offsets *lmo
    992      1.1  christos     = ((sizeof (T) == sizeof (int64_t))
    993      1.1  christos        ? &lmo_64bit_offsets : &lmo_32bit_offsets);
    994      1.1  christos   int ptr_size = sizeof (T);
    995      1.1  christos 
    996      1.1  christos   while (annex[0] != '\0')
    997      1.1  christos     {
    998      1.1  christos       const char *sep = strchr (annex, '=');
    999      1.1  christos       if (sep == nullptr)
   1000      1.1  christos 	break;
   1001      1.1  christos 
   1002      1.1  christos       int name_len = sep - annex;
   1003      1.1  christos       CORE_ADDR *addrp;
   1004      1.1  christos       if (name_len == 5 && startswith (annex, "start"))
   1005      1.1  christos 	addrp = &lm_addr;
   1006      1.1  christos       else if (name_len == 4 && startswith (annex, "prev"))
   1007      1.1  christos 	addrp = &lm_prev;
   1008      1.1  christos       else
   1009      1.1  christos 	{
   1010      1.1  christos 	  annex = strchr (sep, ';');
   1011      1.1  christos 	  if (annex == nullptr)
   1012      1.1  christos 	    break;
   1013      1.1  christos 	  annex++;
   1014      1.1  christos 	  continue;
   1015      1.1  christos 	}
   1016      1.1  christos 
   1017      1.1  christos       annex = decode_address_to_semicolon (addrp, sep + 1);
   1018      1.1  christos     }
   1019      1.1  christos 
   1020      1.1  christos   if (lm_addr == 0)
   1021      1.1  christos     {
   1022  1.1.1.2  christos       CORE_ADDR r_debug = get_r_debug<T> (pid);
   1023      1.1  christos 
   1024      1.1  christos       /* We failed to find DT_DEBUG.  Such situation will not change
   1025      1.1  christos 	 for this inferior - do not retry it.  Report it to GDB as
   1026      1.1  christos 	 E01, see for the reasons at the GDB solib-svr4.c side.  */
   1027      1.1  christos       if (r_debug == (CORE_ADDR) -1)
   1028      1.1  christos 	return -1;
   1029      1.1  christos 
   1030      1.1  christos       if (r_debug != 0)
   1031      1.1  christos 	{
   1032      1.1  christos 	  CORE_ADDR map_offset = r_debug + lmo->r_map_offset;
   1033  1.1.1.2  christos 	  if (read_one_ptr (pid, map_offset, &lm_addr, ptr_size) != 0)
   1034      1.1  christos 	    warning ("unable to read r_map from %s",
   1035      1.1  christos 		     core_addr_to_string (map_offset));
   1036      1.1  christos 	}
   1037      1.1  christos     }
   1038      1.1  christos 
   1039      1.1  christos   std::string document = "<library-list-svr4 version=\"1.0\"";
   1040      1.1  christos 
   1041      1.1  christos   while (lm_addr
   1042  1.1.1.2  christos 	 && read_one_ptr (pid, lm_addr + lmo->l_name_offset,
   1043      1.1  christos 			  &l_name, ptr_size) == 0
   1044  1.1.1.2  christos 	 && read_one_ptr (pid, lm_addr + lmo->l_addr_offset,
   1045      1.1  christos 			  &l_addr, ptr_size) == 0
   1046  1.1.1.2  christos 	 && read_one_ptr (pid, lm_addr + lmo->l_ld_offset,
   1047      1.1  christos 			  &l_ld, ptr_size) == 0
   1048  1.1.1.2  christos 	 && read_one_ptr (pid, lm_addr + lmo->l_prev_offset,
   1049      1.1  christos 			  &l_prev, ptr_size) == 0
   1050  1.1.1.2  christos 	 && read_one_ptr (pid, lm_addr + lmo->l_next_offset,
   1051      1.1  christos 			  &l_next, ptr_size) == 0)
   1052      1.1  christos     {
   1053      1.1  christos       if (lm_prev != l_prev)
   1054      1.1  christos 	{
   1055      1.1  christos 	  warning ("Corrupted shared library list: 0x%lx != 0x%lx",
   1056      1.1  christos 		   (long) lm_prev, (long) l_prev);
   1057      1.1  christos 	  break;
   1058      1.1  christos 	}
   1059      1.1  christos 
   1060      1.1  christos       /* Ignore the first entry even if it has valid name as the first entry
   1061      1.1  christos 	 corresponds to the main executable.  The first entry should not be
   1062      1.1  christos 	 skipped if the dynamic loader was loaded late by a static executable
   1063      1.1  christos 	 (see solib-svr4.c parameter ignore_first).  But in such case the main
   1064      1.1  christos 	 executable does not have PT_DYNAMIC present and this function already
   1065      1.1  christos 	 exited above due to failed get_r_debug.  */
   1066      1.1  christos       if (lm_prev == 0)
   1067      1.1  christos 	string_appendf (document, " main-lm=\"0x%lx\"",
   1068      1.1  christos 			(unsigned long) lm_addr);
   1069      1.1  christos       else
   1070      1.1  christos 	{
   1071      1.1  christos 	  unsigned char libname[PATH_MAX];
   1072      1.1  christos 
   1073      1.1  christos 	  /* Not checking for error because reading may stop before
   1074      1.1  christos 	     we've got PATH_MAX worth of characters.  */
   1075      1.1  christos 	  libname[0] = '\0';
   1076  1.1.1.2  christos 	  netbsd_nat::read_memory (pid, libname, l_name, sizeof (libname) - 1,
   1077  1.1.1.2  christos 				   nullptr);
   1078      1.1  christos 	  libname[sizeof (libname) - 1] = '\0';
   1079      1.1  christos 	  if (libname[0] != '\0')
   1080      1.1  christos 	    {
   1081      1.1  christos 	      if (!header_done)
   1082      1.1  christos 		{
   1083      1.1  christos 		  /* Terminate `<library-list-svr4'.  */
   1084      1.1  christos 		  document += '>';
   1085      1.1  christos 		  header_done = 1;
   1086      1.1  christos 		}
   1087      1.1  christos 
   1088      1.1  christos 	      string_appendf (document, "<library name=\"");
   1089  1.1.1.2  christos 	      xml_escape_text_append (document, (char *) libname);
   1090      1.1  christos 	      string_appendf (document, "\" lm=\"0x%lx\" "
   1091      1.1  christos 			      "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
   1092      1.1  christos 			      (unsigned long) lm_addr, (unsigned long) l_addr,
   1093      1.1  christos 			      (unsigned long) l_ld);
   1094      1.1  christos 	    }
   1095      1.1  christos 	}
   1096      1.1  christos 
   1097      1.1  christos       lm_prev = lm_addr;
   1098      1.1  christos       lm_addr = l_next;
   1099      1.1  christos     }
   1100      1.1  christos 
   1101      1.1  christos   if (!header_done)
   1102      1.1  christos     {
   1103      1.1  christos       /* Empty list; terminate `<library-list-svr4'.  */
   1104      1.1  christos       document += "/>";
   1105      1.1  christos     }
   1106      1.1  christos   else
   1107      1.1  christos     document += "</library-list-svr4>";
   1108      1.1  christos 
   1109      1.1  christos   int document_len = document.length ();
   1110      1.1  christos   if (offset < document_len)
   1111      1.1  christos     document_len -= offset;
   1112      1.1  christos   else
   1113      1.1  christos     document_len = 0;
   1114      1.1  christos   if (len > document_len)
   1115      1.1  christos     len = document_len;
   1116      1.1  christos 
   1117      1.1  christos   memcpy (readbuf, document.data () + offset, len);
   1118      1.1  christos 
   1119      1.1  christos   return len;
   1120      1.1  christos }
   1121      1.1  christos 
   1122      1.1  christos /* Return true if FILE is a 64-bit ELF file,
   1123      1.1  christos    false if the file is not a 64-bit ELF file,
   1124      1.1  christos    and error if the file is not accessible or doesn't exist.  */
   1125      1.1  christos 
   1126      1.1  christos static bool
   1127      1.1  christos elf_64_file_p (const char *file)
   1128      1.1  christos {
   1129  1.1.1.2  christos   int fd = gdb::handle_eintr (-1, ::open, file, O_RDONLY);
   1130      1.1  christos   if (fd < 0)
   1131      1.1  christos     perror_with_name (("open"));
   1132      1.1  christos 
   1133      1.1  christos   Elf64_Ehdr header;
   1134  1.1.1.2  christos   ssize_t ret = gdb::handle_eintr (-1, ::read, fd, &header, sizeof (header));
   1135      1.1  christos   if (ret == -1)
   1136      1.1  christos     perror_with_name (("read"));
   1137  1.1.1.2  christos   gdb::handle_eintr (-1, ::close, fd);
   1138      1.1  christos   if (ret != sizeof (header))
   1139      1.1  christos     error ("Cannot read ELF file header: %s", file);
   1140      1.1  christos 
   1141      1.1  christos   if (header.e_ident[EI_MAG0] != ELFMAG0
   1142      1.1  christos       || header.e_ident[EI_MAG1] != ELFMAG1
   1143      1.1  christos       || header.e_ident[EI_MAG2] != ELFMAG2
   1144      1.1  christos       || header.e_ident[EI_MAG3] != ELFMAG3)
   1145      1.1  christos     error ("Unrecognized ELF file header: %s", file);
   1146      1.1  christos 
   1147      1.1  christos   return header.e_ident[EI_CLASS] == ELFCLASS64;
   1148      1.1  christos }
   1149      1.1  christos 
   1150      1.1  christos /* Construct qXfer:libraries-svr4:read reply.  */
   1151      1.1  christos 
   1152      1.1  christos int
   1153      1.1  christos netbsd_process_target::qxfer_libraries_svr4 (const char *annex,
   1154      1.1  christos 					     unsigned char *readbuf,
   1155      1.1  christos 					     unsigned const char *writebuf,
   1156      1.1  christos 					     CORE_ADDR offset, int len)
   1157      1.1  christos {
   1158      1.1  christos   if (writebuf != nullptr)
   1159      1.1  christos     return -2;
   1160      1.1  christos   if (readbuf == nullptr)
   1161      1.1  christos     return -1;
   1162      1.1  christos 
   1163      1.1  christos   struct process_info *proc = current_process ();
   1164      1.1  christos   pid_t pid = proc->pid;
   1165      1.1  christos   bool is_elf64 = elf_64_file_p (netbsd_nat::pid_to_exec_file (pid));
   1166      1.1  christos 
   1167      1.1  christos   if (is_elf64)
   1168  1.1.1.2  christos     return netbsd_qxfer_libraries_svr4<int64_t> (pid, annex, readbuf,
   1169      1.1  christos 						 writebuf, offset, len);
   1170      1.1  christos   else
   1171  1.1.1.2  christos     return netbsd_qxfer_libraries_svr4<int32_t> (pid, annex, readbuf,
   1172      1.1  christos 						 writebuf, offset, len);
   1173      1.1  christos }
   1174      1.1  christos 
   1175      1.1  christos /* Implement the supports_qxfer_libraries_svr4 target_ops method.  */
   1176      1.1  christos 
   1177      1.1  christos bool
   1178      1.1  christos netbsd_process_target::supports_qxfer_libraries_svr4 ()
   1179      1.1  christos {
   1180      1.1  christos   return true;
   1181      1.1  christos }
   1182      1.1  christos 
   1183      1.1  christos /* Return the name of a file that can be opened to get the symbols for
   1184      1.1  christos    the child process identified by PID.  */
   1185      1.1  christos 
   1186  1.1.1.2  christos const char *
   1187      1.1  christos netbsd_process_target::pid_to_exec_file (pid_t pid)
   1188      1.1  christos {
   1189  1.1.1.2  christos   return netbsd_nat::pid_to_exec_file (pid);
   1190      1.1  christos }
   1191      1.1  christos 
   1192      1.1  christos /* Implementation of the target_ops method "supports_pid_to_exec_file".  */
   1193      1.1  christos 
   1194      1.1  christos bool
   1195      1.1  christos netbsd_process_target::supports_pid_to_exec_file ()
   1196      1.1  christos {
   1197      1.1  christos   return true;
   1198      1.1  christos }
   1199      1.1  christos 
   1200      1.1  christos /* Implementation of the target_ops method "supports_hardware_single_step".  */
   1201      1.1  christos bool
   1202      1.1  christos netbsd_process_target::supports_hardware_single_step ()
   1203      1.1  christos {
   1204      1.1  christos   return true;
   1205      1.1  christos }
   1206      1.1  christos 
   1207      1.1  christos /* Implementation of the target_ops method "sw_breakpoint_from_kind".  */
   1208      1.1  christos 
   1209      1.1  christos const gdb_byte *
   1210      1.1  christos netbsd_process_target::sw_breakpoint_from_kind (int kind, int *size)
   1211      1.1  christos {
   1212      1.1  christos   static gdb_byte brkpt[PTRACE_BREAKPOINT_SIZE] = {*PTRACE_BREAKPOINT};
   1213      1.1  christos 
   1214      1.1  christos   *size = PTRACE_BREAKPOINT_SIZE;
   1215      1.1  christos 
   1216      1.1  christos   return brkpt;
   1217      1.1  christos }
   1218      1.1  christos 
   1219      1.1  christos /* Implement the thread_name target_ops method.  */
   1220      1.1  christos 
   1221      1.1  christos const char *
   1222      1.1  christos netbsd_process_target::thread_name (ptid_t ptid)
   1223      1.1  christos {
   1224      1.1  christos   return netbsd_nat::thread_name (ptid);
   1225      1.1  christos }
   1226      1.1  christos 
   1227      1.1  christos /* Implement the supports_catch_syscall target_ops method.  */
   1228      1.1  christos 
   1229      1.1  christos bool
   1230      1.1  christos netbsd_process_target::supports_catch_syscall ()
   1231      1.1  christos {
   1232      1.1  christos   return true;
   1233      1.1  christos }
   1234      1.1  christos 
   1235      1.1  christos /* Implement the supports_read_auxv target_ops method.  */
   1236      1.1  christos 
   1237      1.1  christos bool
   1238      1.1  christos netbsd_process_target::supports_read_auxv ()
   1239      1.1  christos {
   1240      1.1  christos   return true;
   1241      1.1  christos }
   1242      1.1  christos 
   1243      1.1  christos void
   1244      1.1  christos initialize_low ()
   1245      1.1  christos {
   1246  1.1.1.2  christos   set_target_ops (the_netbsd_target);
   1247      1.1  christos }
   1248