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