xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/netbsd-nat.c (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
1 /* Native-dependent code for NetBSD.
2 
3    Copyright (C) 2006-2023 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "defs.h"
21 
22 #include "netbsd-nat.h"
23 #include "nat/netbsd-nat.h"
24 #include "gdbthread.h"
25 #include "netbsd-tdep.h"
26 #include "inferior.h"
27 #include "gdbarch.h"
28 #include "gdbsupport/buildargv.h"
29 
30 #include <sys/types.h>
31 #include <sys/ptrace.h>
32 #include <sys/sysctl.h>
33 #include <sys/wait.h>
34 
35 /* Return the name of a file that can be opened to get the symbols for
36    the child process identified by PID.  */
37 
38 const char *
39 nbsd_nat_target::pid_to_exec_file (int pid)
40 {
41   return netbsd_nat::pid_to_exec_file (pid);
42 }
43 
44 /* Return the current directory for the process identified by PID.  */
45 
46 static std::string
47 nbsd_pid_to_cwd (int pid)
48 {
49   char buf[PATH_MAX];
50   size_t buflen;
51   int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_CWD};
52   buflen = sizeof (buf);
53   if (sysctl (mib, ARRAY_SIZE (mib), buf, &buflen, NULL, 0))
54     return "";
55   return buf;
56 }
57 
58 /* Return the kinfo_proc2 structure for the process identified by PID.  */
59 
60 static bool
61 nbsd_pid_to_kinfo_proc2 (pid_t pid, struct kinfo_proc2 *kp)
62 {
63   gdb_assert (kp != nullptr);
64 
65   size_t size = sizeof (*kp);
66   int mib[6] = {CTL_KERN, KERN_PROC2, KERN_PROC_PID, pid,
67 		static_cast<int> (size), 1};
68   return !sysctl (mib, ARRAY_SIZE (mib), kp, &size, NULL, 0);
69 }
70 
71 /* Return the command line for the process identified by PID.  */
72 
73 static gdb::unique_xmalloc_ptr<char[]>
74 nbsd_pid_to_cmdline (int pid)
75 {
76   int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV};
77 
78   size_t size = 0;
79   if (::sysctl (mib, ARRAY_SIZE (mib), NULL, &size, NULL, 0) == -1 || size == 0)
80     return nullptr;
81 
82   gdb::unique_xmalloc_ptr<char[]> args (XNEWVAR (char, size));
83 
84   if (::sysctl (mib, ARRAY_SIZE (mib), args.get (), &size, NULL, 0) == -1
85       || size == 0)
86     return nullptr;
87 
88   /* Arguments are returned as a flattened string with NUL separators.
89      Join the arguments with spaces to form a single string.  */
90   for (size_t i = 0; i < size - 1; i++)
91     if (args[i] == '\0')
92       args[i] = ' ';
93   args[size - 1] = '\0';
94 
95   return args;
96 }
97 
98 /* Return true if PTID is still active in the inferior.  */
99 
100 bool
101 nbsd_nat_target::thread_alive (ptid_t ptid)
102 {
103   return netbsd_nat::thread_alive (ptid);
104 }
105 
106 /* Return the name assigned to a thread by an application.  Returns
107    the string in a static buffer.  */
108 
109 const char *
110 nbsd_nat_target::thread_name (struct thread_info *thr)
111 {
112   ptid_t ptid = thr->ptid;
113   return netbsd_nat::thread_name (ptid);
114 }
115 
116 /* Implement the "post_attach" target_ops method.  */
117 
118 static void
119 nbsd_add_threads (nbsd_nat_target *target, pid_t pid)
120 {
121   auto fn
122     = [&target] (ptid_t ptid)
123       {
124 	if (!in_thread_list (target, ptid))
125 	  {
126 	    if (inferior_ptid.lwp () == 0)
127 	      thread_change_ptid (target, inferior_ptid, ptid);
128 	    else
129 	      add_thread (target, ptid);
130 	  }
131       };
132 
133   netbsd_nat::for_each_thread (pid, fn);
134 }
135 
136 /* Implement the virtual inf_ptrace_target::post_startup_inferior method.  */
137 
138 void
139 nbsd_nat_target::post_startup_inferior (ptid_t ptid)
140 {
141   netbsd_nat::enable_proc_events (ptid.pid ());
142 }
143 
144 /* Implement the "post_attach" target_ops method.  */
145 
146 void
147 nbsd_nat_target::post_attach (int pid)
148 {
149   netbsd_nat::enable_proc_events (pid);
150   nbsd_add_threads (this, pid);
151 }
152 
153 /* Implement the "update_thread_list" target_ops method.  */
154 
155 void
156 nbsd_nat_target::update_thread_list ()
157 {
158   delete_exited_threads ();
159 }
160 
161 /* Convert PTID to a string.  */
162 
163 std::string
164 nbsd_nat_target::pid_to_str (ptid_t ptid)
165 {
166   int lwp = ptid.lwp ();
167 
168   if (lwp != 0)
169     {
170       pid_t pid = ptid.pid ();
171 
172       return string_printf ("LWP %d of process %d", lwp, pid);
173     }
174 
175   return normal_pid_to_str (ptid);
176 }
177 
178 /* Retrieve all the memory regions in the specified process.  */
179 
180 static gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]>
181 nbsd_kinfo_get_vmmap (pid_t pid, size_t *size)
182 {
183   int mib[5] = {CTL_VM, VM_PROC, VM_PROC_MAP, pid,
184 		sizeof (struct kinfo_vmentry)};
185 
186   size_t length = 0;
187   if (sysctl (mib, ARRAY_SIZE (mib), NULL, &length, NULL, 0))
188     {
189       *size = 0;
190       return NULL;
191     }
192 
193   /* Prereserve more space.  The length argument is volatile and can change
194      between the sysctl(3) calls as this function can be called against a
195      running process.  */
196   length = length * 5 / 3;
197 
198   gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> kiv
199     (XNEWVAR (kinfo_vmentry, length));
200 
201   if (sysctl (mib, ARRAY_SIZE (mib), kiv.get (), &length, NULL, 0))
202     {
203       *size = 0;
204       return NULL;
205     }
206 
207   *size = length / sizeof (struct kinfo_vmentry);
208   return kiv;
209 }
210 
211 /* Iterate over all the memory regions in the current inferior,
212    calling FUNC for each memory region.  OBFD is passed as the last
213    argument to FUNC.  */
214 
215 int
216 nbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
217 				      void *data)
218 {
219   pid_t pid = inferior_ptid.pid ();
220 
221   size_t nitems;
222   gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> vmentl
223     = nbsd_kinfo_get_vmmap (pid, &nitems);
224   if (vmentl == NULL)
225     perror_with_name (_("Couldn't fetch VM map entries"));
226 
227   for (size_t i = 0; i < nitems; i++)
228     {
229       struct kinfo_vmentry *kve = &vmentl[i];
230 
231       /* Skip unreadable segments and those where MAP_NOCORE has been set.  */
232       if (!(kve->kve_protection & KVME_PROT_READ)
233 	  || kve->kve_flags & KVME_FLAG_NOCOREDUMP)
234 	continue;
235 
236       /* Skip segments with an invalid type.  */
237       switch (kve->kve_type)
238 	{
239 	case KVME_TYPE_VNODE:
240 	case KVME_TYPE_ANON:
241 	case KVME_TYPE_SUBMAP:
242 	case KVME_TYPE_OBJECT:
243 	  break;
244 	default:
245 	  continue;
246 	}
247 
248       size_t size = kve->kve_end - kve->kve_start;
249       if (info_verbose)
250 	{
251 	  gdb_printf ("Save segment, %ld bytes at %s (%c%c%c)\n",
252 		      (long) size,
253 		      paddress (target_gdbarch (), kve->kve_start),
254 		      kve->kve_protection & KVME_PROT_READ ? 'r' : '-',
255 		      kve->kve_protection & KVME_PROT_WRITE ? 'w' : '-',
256 		      kve->kve_protection & KVME_PROT_EXEC ? 'x' : '-');
257 	}
258 
259       /* Invoke the callback function to create the corefile segment.
260 	 Pass MODIFIED as true, we do not know the real modification state.  */
261       func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ,
262 	    kve->kve_protection & KVME_PROT_WRITE,
263 	    kve->kve_protection & KVME_PROT_EXEC, 1, false, data);
264     }
265   return 0;
266 }
267 
268 /* Implement the "info_proc" target_ops method.  */
269 
270 bool
271 nbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
272 {
273   pid_t pid;
274   bool do_cmdline = false;
275   bool do_cwd = false;
276   bool do_exe = false;
277   bool do_mappings = false;
278   bool do_status = false;
279 
280   switch (what)
281     {
282     case IP_MINIMAL:
283       do_cmdline = true;
284       do_cwd = true;
285       do_exe = true;
286       break;
287     case IP_STAT:
288     case IP_STATUS:
289       do_status = true;
290       break;
291     case IP_MAPPINGS:
292       do_mappings = true;
293       break;
294     case IP_CMDLINE:
295       do_cmdline = true;
296       break;
297     case IP_EXE:
298       do_exe = true;
299       break;
300     case IP_CWD:
301       do_cwd = true;
302       break;
303     case IP_ALL:
304       do_cmdline = true;
305       do_cwd = true;
306       do_exe = true;
307       do_mappings = true;
308       do_status = true;
309       break;
310     default:
311       error (_("Not supported on this target."));
312     }
313 
314   gdb_argv built_argv (args);
315   if (built_argv.count () == 0)
316     {
317       pid = inferior_ptid.pid ();
318       if (pid == 0)
319 	error (_("No current process: you must name one."));
320     }
321   else if (built_argv.count () == 1 && isdigit (built_argv[0][0]))
322     pid = strtol (built_argv[0], NULL, 10);
323   else
324     error (_("Invalid arguments."));
325 
326   gdb_printf (_("process %d\n"), pid);
327 
328   if (do_cmdline)
329     {
330       gdb::unique_xmalloc_ptr<char[]> cmdline = nbsd_pid_to_cmdline (pid);
331       if (cmdline != nullptr)
332 	gdb_printf ("cmdline = '%s'\n", cmdline.get ());
333       else
334 	warning (_("unable to fetch command line"));
335     }
336   if (do_cwd)
337     {
338       std::string cwd = nbsd_pid_to_cwd (pid);
339       if (cwd != "")
340 	gdb_printf ("cwd = '%s'\n", cwd.c_str ());
341       else
342 	warning (_("unable to fetch current working directory"));
343     }
344   if (do_exe)
345     {
346       const char *exe = pid_to_exec_file (pid);
347       if (exe != nullptr)
348 	gdb_printf ("exe = '%s'\n", exe);
349       else
350 	warning (_("unable to fetch executable path name"));
351     }
352   if (do_mappings)
353     {
354       size_t nvment;
355       gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> vmentl
356 	= nbsd_kinfo_get_vmmap (pid, &nvment);
357 
358       if (vmentl != nullptr)
359 	{
360 	  int addr_bit = TARGET_CHAR_BIT * sizeof (void *);
361 	  nbsd_info_proc_mappings_header (addr_bit);
362 
363 	  struct kinfo_vmentry *kve = vmentl.get ();
364 	  for (int i = 0; i < nvment; i++, kve++)
365 	    nbsd_info_proc_mappings_entry (addr_bit, kve->kve_start,
366 					   kve->kve_end, kve->kve_offset,
367 					   kve->kve_flags, kve->kve_protection,
368 					   kve->kve_path);
369 	}
370       else
371 	warning (_("unable to fetch virtual memory map"));
372     }
373   if (do_status)
374     {
375       struct kinfo_proc2 kp;
376       if (!nbsd_pid_to_kinfo_proc2 (pid, &kp))
377 	warning (_("Failed to fetch process information"));
378       else
379 	{
380 	  auto process_status
381 	    = [] (int8_t stat)
382 	      {
383 		switch (stat)
384 		  {
385 		  case SIDL:
386 		    return "IDL";
387 		  case SACTIVE:
388 		    return "ACTIVE";
389 		  case SDYING:
390 		    return "DYING";
391 		  case SSTOP:
392 		    return "STOP";
393 		  case SZOMB:
394 		    return "ZOMB";
395 		  case SDEAD:
396 		    return "DEAD";
397 		  default:
398 		    return "? (unknown)";
399 		  }
400 	      };
401 
402 	  gdb_printf ("Name: %s\n", kp.p_comm);
403 	  gdb_printf ("State: %s\n", process_status(kp.p_realstat));
404 	  gdb_printf ("Parent process: %" PRId32 "\n", kp.p_ppid);
405 	  gdb_printf ("Process group: %" PRId32 "\n", kp.p__pgid);
406 	  gdb_printf ("Session id: %" PRId32 "\n", kp.p_sid);
407 	  gdb_printf ("TTY: %" PRId32 "\n", kp.p_tdev);
408 	  gdb_printf ("TTY owner process group: %" PRId32 "\n", kp.p_tpgid);
409 	  gdb_printf ("User IDs (real, effective, saved): "
410 		      "%" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
411 		      kp.p_ruid, kp.p_uid, kp.p_svuid);
412 	  gdb_printf ("Group IDs (real, effective, saved): "
413 		      "%" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
414 		      kp.p_rgid, kp.p_gid, kp.p_svgid);
415 
416 	  gdb_printf ("Groups:");
417 	  for (int i = 0; i < kp.p_ngroups; i++)
418 	    gdb_printf (" %" PRIu32, kp.p_groups[i]);
419 	  gdb_printf ("\n");
420 	  gdb_printf ("Minor faults (no memory page): %" PRIu64 "\n",
421 		      kp.p_uru_minflt);
422 	  gdb_printf ("Major faults (memory page faults): %" PRIu64 "\n",
423 		      kp.p_uru_majflt);
424 	  gdb_printf ("utime: %" PRIu32 ".%06" PRIu32 "\n",
425 		      kp.p_uutime_sec, kp.p_uutime_usec);
426 	  gdb_printf ("stime: %" PRIu32 ".%06" PRIu32 "\n",
427 		      kp.p_ustime_sec, kp.p_ustime_usec);
428 	  gdb_printf ("utime+stime, children: %" PRIu32 ".%06" PRIu32 "\n",
429 		      kp.p_uctime_sec, kp.p_uctime_usec);
430 	  gdb_printf ("'nice' value: %" PRIu8 "\n", kp.p_nice);
431 	  gdb_printf ("Start time: %" PRIu32 ".%06" PRIu32 "\n",
432 		      kp.p_ustart_sec, kp.p_ustart_usec);
433 	  int pgtok = getpagesize () / 1024;
434 	  gdb_printf ("Data size: %" PRIuMAX " kB\n",
435 		      (uintmax_t) kp.p_vm_dsize * pgtok);
436 	  gdb_printf ("Stack size: %" PRIuMAX " kB\n",
437 		      (uintmax_t) kp.p_vm_ssize * pgtok);
438 	  gdb_printf ("Text size: %" PRIuMAX " kB\n",
439 		      (uintmax_t) kp.p_vm_tsize * pgtok);
440 	  gdb_printf ("Resident set size: %" PRIuMAX " kB\n",
441 		      (uintmax_t) kp.p_vm_rssize * pgtok);
442 	  gdb_printf ("Maximum RSS: %" PRIu64 " kB\n", kp.p_uru_maxrss);
443 	  gdb_printf ("Pending Signals:");
444 	  for (size_t i = 0; i < ARRAY_SIZE (kp.p_siglist.__bits); i++)
445 	    gdb_printf (" %08" PRIx32, kp.p_siglist.__bits[i]);
446 	  gdb_printf ("\n");
447 	  gdb_printf ("Ignored Signals:");
448 	  for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigignore.__bits); i++)
449 	    gdb_printf (" %08" PRIx32, kp.p_sigignore.__bits[i]);
450 	  gdb_printf ("\n");
451 	  gdb_printf ("Caught Signals:");
452 	  for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigcatch.__bits); i++)
453 	    gdb_printf (" %08" PRIx32, kp.p_sigcatch.__bits[i]);
454 	  gdb_printf ("\n");
455 	}
456     }
457 
458   return true;
459 }
460 
461 #ifdef PT_STEP
462 /* Resume execution of a specified PTID, that points to a process or a thread
463    within a process.  If one thread is specified, all other threads are
464    suspended.  If STEP is nonzero, single-step it.  If SIGNAL is nonzero,
465    give it that signal.  */
466 
467 static void
468 nbsd_resume(nbsd_nat_target *target, ptid_t ptid, int step,
469 	    enum gdb_signal signal)
470 {
471   int request;
472 
473   gdb_assert (minus_one_ptid != ptid);
474 
475   if (ptid.lwp_p ())
476     {
477       /* If ptid is a specific LWP, suspend all other LWPs in the process.  */
478       inferior *inf = find_inferior_ptid (target, ptid);
479 
480       for (thread_info *tp : inf->non_exited_threads ())
481 	{
482 	  if (tp->ptid.lwp () == ptid.lwp ())
483 	    request = PT_RESUME;
484 	  else
485 	    request = PT_SUSPEND;
486 
487 	  if (ptrace (request, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
488 	    perror_with_name (("ptrace"));
489 	}
490     }
491   else
492     {
493       /* If ptid is a wildcard, resume all matching threads (they won't run
494 	 until the process is continued however).  */
495       for (thread_info *tp : all_non_exited_threads (target, ptid))
496 	if (ptrace (PT_RESUME, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
497 	  perror_with_name (("ptrace"));
498     }
499 
500   if (step)
501     {
502       for (thread_info *tp : all_non_exited_threads (target, ptid))
503 	if (ptrace (PT_SETSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
504 	  perror_with_name (("ptrace"));
505     }
506   else
507     {
508       for (thread_info *tp : all_non_exited_threads (target, ptid))
509 	if (ptrace (PT_CLEARSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
510 	  perror_with_name (("ptrace"));
511     }
512 
513   if (catch_syscall_enabled () > 0)
514     request = PT_SYSCALL;
515   else
516     request = PT_CONTINUE;
517 
518   /* An address of (void *)1 tells ptrace to continue from
519      where it was.  If GDB wanted it to start some other way, we have
520      already written a new program counter value to the child.  */
521   if (ptrace (request, ptid.pid (), (void *)1, gdb_signal_to_host (signal)) == -1)
522     perror_with_name (("ptrace"));
523 }
524 #endif
525 
526 /* Resume execution of thread PTID, or all threads of all inferiors
527    if PTID is -1.  If STEP is nonzero, single-step it.  If SIGNAL is nonzero,
528    give it that signal.  */
529 
530 void
531 nbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
532 {
533 #ifdef PT_STEP
534   if (minus_one_ptid != ptid)
535     nbsd_resume (this, ptid, step, signal);
536   else
537     {
538       for (inferior *inf : all_non_exited_inferiors (this))
539 	nbsd_resume (this, ptid_t (inf->pid, 0, 0), step, signal);
540     }
541 #else
542     gdb_assert(step == 0);
543     if (ptid.pid () == -1)
544       ptid = inferior_ptid;
545     inf_ptrace_target::resume (ptid, step, signal);
546 #endif
547 }
548 
549 /* Implement a safe wrapper around waitpid().  */
550 
551 static pid_t
552 nbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus,
553 	   target_wait_flags options)
554 {
555   pid_t pid;
556   int status;
557 
558   set_sigint_trap ();
559 
560   do
561     {
562       /* The common code passes WNOHANG that leads to crashes, overwrite it.  */
563       pid = waitpid (ptid.pid (), &status, 0);
564     }
565   while (pid == -1 && errno == EINTR);
566 
567   clear_sigint_trap ();
568 
569   if (pid == -1)
570     perror_with_name (_("Child process unexpectedly missing"));
571 
572   *ourstatus = host_status_to_waitstatus (status);
573   return pid;
574 }
575 
576 /* Wait for the child specified by PTID to do something.  Return the
577    process ID of the child, or MINUS_ONE_PTID in case of error; store
578    the status in *OURSTATUS.  */
579 
580 ptid_t
581 nbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
582 		       target_wait_flags target_options)
583 {
584   pid_t pid = nbsd_wait (ptid, ourstatus, target_options);
585   ptid_t wptid = ptid_t (pid);
586 
587   /* If the child stopped, keep investigating its status.  */
588   if (ourstatus->kind () != TARGET_WAITKIND_STOPPED)
589     return wptid;
590 
591   /* Extract the event and thread that received a signal.  */
592   ptrace_siginfo_t psi;
593   if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
594     perror_with_name (("ptrace"));
595 
596   /* Pick child's siginfo_t.  */
597   siginfo_t *si = &psi.psi_siginfo;
598 
599   int lwp = psi.psi_lwpid;
600 
601   int signo = si->si_signo;
602   const int code = si->si_code;
603 
604   /* Construct PTID with a specified thread that received the event.
605      If a signal was targeted to the whole process, lwp is 0.  */
606   wptid = ptid_t (pid, lwp, 0);
607 
608   /* Bail out on non-debugger oriented signals..  */
609   if (signo != SIGTRAP)
610     return wptid;
611 
612   /* Stop examining non-debugger oriented SIGTRAP codes.  */
613   if (code <= SI_USER || code == SI_NOINFO)
614     return wptid;
615 
616   /* Process state for threading events */
617   ptrace_state_t pst = {};
618   if (code == TRAP_LWP)
619     {
620       if (ptrace (PT_GET_PROCESS_STATE, pid, &pst, sizeof (pst)) == -1)
621 	perror_with_name (("ptrace"));
622     }
623 
624   if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_EXIT)
625     {
626       /* If GDB attaches to a multi-threaded process, exiting
627 	 threads might be skipped during post_attach that
628 	 have not yet reported their PTRACE_LWP_EXIT event.
629 	 Ignore exited events for an unknown LWP.  */
630       thread_info *thr = find_thread_ptid (this, wptid);
631       if (thr == nullptr)
632 	  ourstatus->set_spurious ();
633       else
634 	{
635 	  /* NetBSD does not store an LWP exit status.  */
636 	  ourstatus->set_thread_exited (0);
637 
638 	  if (print_thread_events)
639 	    gdb_printf (_("[%s exited]\n"),
640 			target_pid_to_str (wptid).c_str ());
641 	  delete_thread (thr);
642 	}
643 
644       /* The GDB core expects that the rest of the threads are running.  */
645       if (ptrace (PT_CONTINUE, pid, (void *) 1, 0) == -1)
646 	perror_with_name (("ptrace"));
647 
648       return wptid;
649     }
650 
651   if (in_thread_list (this, ptid_t (pid)))
652       thread_change_ptid (this, ptid_t (pid), wptid);
653 
654   if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE)
655     {
656       /* If GDB attaches to a multi-threaded process, newborn
657 	 threads might be added by nbsd_add_threads that have
658 	 not yet reported their PTRACE_LWP_CREATE event.  Ignore
659 	 born events for an already-known LWP.  */
660       if (in_thread_list (this, wptid))
661 	  ourstatus->set_spurious ();
662       else
663 	{
664 	  add_thread (this, wptid);
665 	  ourstatus->set_thread_created ();
666 	}
667       return wptid;
668     }
669 
670   if (code == TRAP_EXEC)
671     {
672       ourstatus->set_execd (make_unique_xstrdup (pid_to_exec_file (pid)));
673       return wptid;
674     }
675 
676   if (code == TRAP_TRACE)
677     {
678       /* Unhandled at this level.  */
679       return wptid;
680     }
681 
682   if (code == TRAP_SCE || code == TRAP_SCX)
683     {
684       int sysnum = si->si_sysnum;
685 
686       if (!catch_syscall_enabled () || !catching_syscall_number (sysnum))
687 	{
688 	  /* If the core isn't interested in this event, ignore it.  */
689 	  ourstatus->set_spurious ();
690 	  return wptid;
691 	}
692 
693       if (code == TRAP_SCE)
694 	ourstatus->set_syscall_entry (sysnum);
695       else
696 	ourstatus->set_syscall_return (sysnum);
697       return wptid;
698     }
699 
700   if (code == TRAP_BRKPT)
701     {
702       /* Unhandled at this level.  */
703       return wptid;
704     }
705 
706   /* Unclassified SIGTRAP event.  */
707   ourstatus->set_spurious ();
708   return wptid;
709 }
710 
711 /* Implement the "insert_exec_catchpoint" target_ops method.  */
712 
713 int
714 nbsd_nat_target::insert_exec_catchpoint (int pid)
715 {
716   /* Nothing to do.  */
717   return 0;
718 }
719 
720 /* Implement the "remove_exec_catchpoint" target_ops method.  */
721 
722 int
723 nbsd_nat_target::remove_exec_catchpoint (int pid)
724 {
725   /* Nothing to do.  */
726   return 0;
727 }
728 
729 /* Implement the "set_syscall_catchpoint" target_ops method.  */
730 
731 int
732 nbsd_nat_target::set_syscall_catchpoint (int pid, bool needed,
733 					 int any_count,
734 					 gdb::array_view<const int> syscall_counts)
735 {
736   /* Ignore the arguments.  inf-ptrace.c will use PT_SYSCALL which
737      will catch all system call entries and exits.  The system calls
738      are filtered by GDB rather than the kernel.  */
739   return 0;
740 }
741 
742 /* Implement the "supports_multi_process" target_ops method. */
743 
744 bool
745 nbsd_nat_target::supports_multi_process ()
746 {
747   return true;
748 }
749 
750 /* Implement the "xfer_partial" target_ops method.  */
751 
752 enum target_xfer_status
753 nbsd_nat_target::xfer_partial (enum target_object object,
754 			       const char *annex, gdb_byte *readbuf,
755 			       const gdb_byte *writebuf,
756 			       ULONGEST offset, ULONGEST len,
757 			       ULONGEST *xfered_len)
758 {
759   pid_t pid = inferior_ptid.pid ();
760 
761   switch (object)
762     {
763     case TARGET_OBJECT_SIGNAL_INFO:
764       {
765 	len = netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset,
766 					len);
767 
768 	if (len == -1)
769 	  return TARGET_XFER_E_IO;
770 
771 	*xfered_len = len;
772 	return TARGET_XFER_OK;
773       }
774     case TARGET_OBJECT_MEMORY:
775       {
776 	size_t xfered;
777 	int res;
778 	if (writebuf != nullptr)
779 	  res = netbsd_nat::write_memory (pid, writebuf, offset, len, &xfered);
780 	else
781 	  res = netbsd_nat::read_memory (pid, readbuf, offset, len, &xfered);
782 	if (res != 0)
783 	  {
784 	    if (res == EACCES)
785 	      gdb_printf (gdb_stderr, "Cannot %s process at %s (%s). "
786 			  "Is PaX MPROTECT active? See security(7), "
787 			  "sysctl(7), paxctl(8)\n",
788 			  (writebuf ? "write to" : "read from"),
789 			  pulongest (offset), safe_strerror (errno));
790 	    return TARGET_XFER_E_IO;
791 	  }
792 	if (xfered == 0)
793 	  return TARGET_XFER_EOF;
794 	*xfered_len = (ULONGEST) xfered;
795 	return TARGET_XFER_OK;
796       }
797     default:
798       return inf_ptrace_target::xfer_partial (object, annex,
799 					      readbuf, writebuf, offset,
800 					      len, xfered_len);
801     }
802 }
803 
804 /* Implement the "supports_dumpcore" target_ops method.  */
805 
806 bool
807 nbsd_nat_target::supports_dumpcore ()
808 {
809   return true;
810 }
811 
812 /* Implement the "dumpcore" target_ops method.  */
813 
814 void
815 nbsd_nat_target::dumpcore (const char *filename)
816 {
817   pid_t pid = inferior_ptid.pid ();
818 
819   if (ptrace (PT_DUMPCORE, pid, const_cast<char *>(filename),
820 	      strlen (filename)) == -1)
821     perror_with_name (("ptrace"));
822 }
823