]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/netbsd-nat.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gdb / netbsd-nat.c
CommitLineData
84c5b489
MK
1/* Native-dependent code for NetBSD.
2
d01e8234 3 Copyright (C) 2006-2025 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 19
84c5b489 20
1b71cfcf 21#include "netbsd-nat.h"
cf4ac4be 22#include "nat/netbsd-nat.h"
05f00e22 23#include "gdbthread.h"
1b71cfcf 24#include "netbsd-tdep.h"
05f00e22 25#include "inferior.h"
54b8cbd0 26#include "gdbarch.h"
de69cec0 27#include "gdbsupport/buildargv.h"
a9791f14 28#include "gdbsupport/eintr.h"
84c5b489 29
a2ecbe9f
KR
30#include <sys/types.h>
31#include <sys/ptrace.h>
32#include <sys/sysctl.h>
f94b2e03 33#include <sys/wait.h>
a2ecbe9f 34
766062f6 35/* Return the name of a file that can be opened to get the symbols for
84c5b489
MK
36 the child process identified by PID. */
37
0e90c441 38const char *
f6ac5f3d 39nbsd_nat_target::pid_to_exec_file (int pid)
84c5b489 40{
0e90c441 41 return netbsd_nat::pid_to_exec_file (pid);
84c5b489 42}
05f00e22 43
b4848d2a
KR
44/* Return the current directory for the process identified by PID. */
45
46static std::string
47nbsd_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
06ca5dd4
KR
58/* Return the kinfo_proc2 structure for the process identified by PID. */
59
60static bool
61nbsd_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
49d1d1f5
KR
71/* Return the command line for the process identified by PID. */
72
73static gdb::unique_xmalloc_ptr<char[]>
74nbsd_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;
cf4ac4be 79 if (::sysctl (mib, ARRAY_SIZE (mib), NULL, &size, NULL, 0) == -1 || size == 0)
49d1d1f5
KR
80 return nullptr;
81
82 gdb::unique_xmalloc_ptr<char[]> args (XNEWVAR (char, size));
83
cf4ac4be 84 if (::sysctl (mib, ARRAY_SIZE (mib), args.get (), &size, NULL, 0) == -1
49d1d1f5
KR
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
05f00e22
KR
98/* Return true if PTID is still active in the inferior. */
99
100bool
101nbsd_nat_target::thread_alive (ptid_t ptid)
102{
cf4ac4be 103 return netbsd_nat::thread_alive (ptid);
05f00e22
KR
104}
105
106/* Return the name assigned to a thread by an application. Returns
107 the string in a static buffer. */
108
109const char *
110nbsd_nat_target::thread_name (struct thread_info *thr)
111{
112 ptid_t ptid = thr->ptid;
cf4ac4be 113 return netbsd_nat::thread_name (ptid);
05f00e22
KR
114}
115
116/* Implement the "post_attach" target_ops method. */
117
118static void
119nbsd_add_threads (nbsd_nat_target *target, pid_t pid)
120{
121 auto fn
cf4ac4be 122 = [&target] (ptid_t ptid)
05f00e22 123 {
05f00e22
KR
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 }
05f00e22
KR
131 };
132
cf4ac4be 133 netbsd_nat::for_each_thread (pid, fn);
117539e6
KR
134}
135
200fd287 136/* Implement the virtual inf_ptrace_target::post_startup_inferior method. */
117539e6
KR
137
138void
139nbsd_nat_target::post_startup_inferior (ptid_t ptid)
140{
cf4ac4be 141 netbsd_nat::enable_proc_events (ptid.pid ());
117539e6
KR
142}
143
05f00e22
KR
144/* Implement the "post_attach" target_ops method. */
145
146void
147nbsd_nat_target::post_attach (int pid)
148{
cf4ac4be 149 netbsd_nat::enable_proc_events (pid);
05f00e22
KR
150 nbsd_add_threads (this, pid);
151}
152
153/* Implement the "update_thread_list" target_ops method. */
154
155void
156nbsd_nat_target::update_thread_list ()
157{
117539e6 158 delete_exited_threads ();
05f00e22
KR
159}
160
161/* Convert PTID to a string. */
162
163std::string
164nbsd_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}
54b8cbd0
KR
177
178/* Retrieve all the memory regions in the specified process. */
179
180static gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]>
181nbsd_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
215int
216nbsd_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)
deb70aa0 225 perror_with_name (_("Couldn't fetch VM map entries"));
54b8cbd0
KR
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 {
6cb06a8c
TT
251 gdb_printf ("Save segment, %ld bytes at %s (%c%c%c)\n",
252 (long) size,
99d9c3b9 253 paddress (current_inferior ()->arch (), kve->kve_start),
6cb06a8c
TT
254 kve->kve_protection & KVME_PROT_READ ? 'r' : '-',
255 kve->kve_protection & KVME_PROT_WRITE ? 'w' : '-',
256 kve->kve_protection & KVME_PROT_EXEC ? 'x' : '-');
54b8cbd0
KR
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,
e01493b7 263 kve->kve_protection & KVME_PROT_EXEC, 1, false, data);
54b8cbd0
KR
264 }
265 return 0;
266}
267
268/* Implement the "info_proc" target_ops method. */
269
270bool
271nbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
272{
273 pid_t pid;
49d1d1f5 274 bool do_cmdline = false;
b4848d2a 275 bool do_cwd = false;
51c133d5 276 bool do_exe = false;
54b8cbd0 277 bool do_mappings = false;
06ca5dd4 278 bool do_status = false;
54b8cbd0
KR
279
280 switch (what)
281 {
1085dfd4
KR
282 case IP_MINIMAL:
283 do_cmdline = true;
284 do_cwd = true;
285 do_exe = true;
286 break;
06ca5dd4
KR
287 case IP_STAT:
288 case IP_STATUS:
289 do_status = true;
290 break;
54b8cbd0
KR
291 case IP_MAPPINGS:
292 do_mappings = true;
293 break;
49d1d1f5
KR
294 case IP_CMDLINE:
295 do_cmdline = true;
296 break;
51c133d5
KR
297 case IP_EXE:
298 do_exe = true;
299 break;
b4848d2a
KR
300 case IP_CWD:
301 do_cwd = true;
302 break;
1085dfd4
KR
303 case IP_ALL:
304 do_cmdline = true;
305 do_cwd = true;
306 do_exe = true;
307 do_mappings = true;
06ca5dd4 308 do_status = true;
1085dfd4 309 break;
54b8cbd0
KR
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)
dda83cd7 319 error (_("No current process: you must name one."));
54b8cbd0
KR
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
6cb06a8c 326 gdb_printf (_("process %d\n"), pid);
54b8cbd0 327
49d1d1f5
KR
328 if (do_cmdline)
329 {
330 gdb::unique_xmalloc_ptr<char[]> cmdline = nbsd_pid_to_cmdline (pid);
331 if (cmdline != nullptr)
6cb06a8c 332 gdb_printf ("cmdline = '%s'\n", cmdline.get ());
49d1d1f5
KR
333 else
334 warning (_("unable to fetch command line"));
335 }
b4848d2a
KR
336 if (do_cwd)
337 {
338 std::string cwd = nbsd_pid_to_cwd (pid);
339 if (cwd != "")
6cb06a8c 340 gdb_printf ("cwd = '%s'\n", cwd.c_str ());
b4848d2a
KR
341 else
342 warning (_("unable to fetch current working directory"));
343 }
51c133d5
KR
344 if (do_exe)
345 {
346 const char *exe = pid_to_exec_file (pid);
347 if (exe != nullptr)
6cb06a8c 348 gdb_printf ("exe = '%s'\n", exe);
51c133d5
KR
349 else
350 warning (_("unable to fetch executable path name"));
351 }
54b8cbd0
KR
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 }
06ca5dd4
KR
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
6cb06a8c
TT
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:");
06ca5dd4 417 for (int i = 0; i < kp.p_ngroups; i++)
6cb06a8c
TT
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);
06ca5dd4 433 int pgtok = getpagesize () / 1024;
6cb06a8c
TT
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:");
06ca5dd4 444 for (size_t i = 0; i < ARRAY_SIZE (kp.p_siglist.__bits); i++)
6cb06a8c
TT
445 gdb_printf (" %08" PRIx32, kp.p_siglist.__bits[i]);
446 gdb_printf ("\n");
447 gdb_printf ("Ignored Signals:");
06ca5dd4 448 for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigignore.__bits); i++)
6cb06a8c
TT
449 gdb_printf (" %08" PRIx32, kp.p_sigignore.__bits[i]);
450 gdb_printf ("\n");
451 gdb_printf ("Caught Signals:");
06ca5dd4 452 for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigcatch.__bits); i++)
6cb06a8c
TT
453 gdb_printf (" %08" PRIx32, kp.p_sigcatch.__bits[i]);
454 gdb_printf ("\n");
06ca5dd4
KR
455 }
456 }
54b8cbd0
KR
457
458 return true;
459}
f94b2e03
KR
460
461/* Resume execution of a specified PTID, that points to a process or a thread
462 within a process. If one thread is specified, all other threads are
463 suspended. If STEP is nonzero, single-step it. If SIGNAL is nonzero,
464 give it that signal. */
465
466static void
467nbsd_resume(nbsd_nat_target *target, ptid_t ptid, int step,
468 enum gdb_signal signal)
469{
470 int request;
471
472 gdb_assert (minus_one_ptid != ptid);
473
474 if (ptid.lwp_p ())
475 {
476 /* If ptid is a specific LWP, suspend all other LWPs in the process. */
477 inferior *inf = find_inferior_ptid (target, ptid);
478
479 for (thread_info *tp : inf->non_exited_threads ())
dda83cd7
SM
480 {
481 if (tp->ptid.lwp () == ptid.lwp ())
482 request = PT_RESUME;
483 else
484 request = PT_SUSPEND;
485
486 if (ptrace (request, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
487 perror_with_name (("ptrace"));
488 }
f94b2e03
KR
489 }
490 else
491 {
492 /* If ptid is a wildcard, resume all matching threads (they won't run
dda83cd7 493 until the process is continued however). */
f94b2e03 494 for (thread_info *tp : all_non_exited_threads (target, ptid))
dda83cd7
SM
495 if (ptrace (PT_RESUME, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
496 perror_with_name (("ptrace"));
f94b2e03
KR
497 }
498
499 if (step)
500 {
501 for (thread_info *tp : all_non_exited_threads (target, ptid))
502 if (ptrace (PT_SETSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
503 perror_with_name (("ptrace"));
504 }
505 else
506 {
507 for (thread_info *tp : all_non_exited_threads (target, ptid))
508 if (ptrace (PT_CLEARSTEP, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1)
509 perror_with_name (("ptrace"));
510 }
511
f087eb27 512 if (catch_syscall_enabled ())
f94b2e03
KR
513 request = PT_SYSCALL;
514 else
515 request = PT_CONTINUE;
516
517 /* An address of (void *)1 tells ptrace to continue from
518 where it was. If GDB wanted it to start some other way, we have
519 already written a new program counter value to the child. */
520 if (ptrace (request, ptid.pid (), (void *)1, gdb_signal_to_host (signal)) == -1)
521 perror_with_name (("ptrace"));
522}
523
524/* Resume execution of thread PTID, or all threads of all inferiors
525 if PTID is -1. If STEP is nonzero, single-step it. If SIGNAL is nonzero,
526 give it that signal. */
527
528void
529nbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
530{
531 if (minus_one_ptid != ptid)
532 nbsd_resume (this, ptid, step, signal);
533 else
534 {
535 for (inferior *inf : all_non_exited_inferiors (this))
536 nbsd_resume (this, ptid_t (inf->pid, 0, 0), step, signal);
537 }
538}
539
540/* Implement a safe wrapper around waitpid(). */
541
542static pid_t
b60cea74
TT
543nbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus,
544 target_wait_flags options)
f94b2e03
KR
545{
546 pid_t pid;
547 int status;
548
549 set_sigint_trap ();
550
a9791f14
TV
551 /* The common code passes WNOHANG that leads to crashes, overwrite it. */
552 pid = gdb::waitpid (ptid.pid (), &status, 0);
f94b2e03
KR
553
554 clear_sigint_trap ();
555
556 if (pid == -1)
557 perror_with_name (_("Child process unexpectedly missing"));
558
7509b829 559 *ourstatus = host_status_to_waitstatus (status);
f94b2e03
KR
560 return pid;
561}
562
563/* Wait for the child specified by PTID to do something. Return the
564 process ID of the child, or MINUS_ONE_PTID in case of error; store
565 the status in *OURSTATUS. */
566
567ptid_t
568nbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
b60cea74 569 target_wait_flags target_options)
f94b2e03
KR
570{
571 pid_t pid = nbsd_wait (ptid, ourstatus, target_options);
572 ptid_t wptid = ptid_t (pid);
573
574 /* If the child stopped, keep investigating its status. */
183be222 575 if (ourstatus->kind () != TARGET_WAITKIND_STOPPED)
f94b2e03
KR
576 return wptid;
577
578 /* Extract the event and thread that received a signal. */
579 ptrace_siginfo_t psi;
580 if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
581 perror_with_name (("ptrace"));
582
583 /* Pick child's siginfo_t. */
584 siginfo_t *si = &psi.psi_siginfo;
585
586 int lwp = psi.psi_lwpid;
587
588 int signo = si->si_signo;
589 const int code = si->si_code;
590
591 /* Construct PTID with a specified thread that received the event.
592 If a signal was targeted to the whole process, lwp is 0. */
593 wptid = ptid_t (pid, lwp, 0);
594
595 /* Bail out on non-debugger oriented signals.. */
596 if (signo != SIGTRAP)
597 return wptid;
598
599 /* Stop examining non-debugger oriented SIGTRAP codes. */
600 if (code <= SI_USER || code == SI_NOINFO)
601 return wptid;
602
117539e6
KR
603 /* Process state for threading events */
604 ptrace_state_t pst = {};
605 if (code == TRAP_LWP)
606 {
607 if (ptrace (PT_GET_PROCESS_STATE, pid, &pst, sizeof (pst)) == -1)
608 perror_with_name (("ptrace"));
609 }
610
611 if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_EXIT)
612 {
613 /* If GDB attaches to a multi-threaded process, exiting
614 threads might be skipped during post_attach that
615 have not yet reported their PTRACE_LWP_EXIT event.
616 Ignore exited events for an unknown LWP. */
9213a6d7 617 thread_info *thr = this->find_thread (wptid);
117539e6 618 if (thr == nullptr)
183be222 619 ourstatus->set_spurious ();
117539e6
KR
620 else
621 {
117539e6 622 /* NetBSD does not store an LWP exit status. */
183be222 623 ourstatus->set_thread_exited (0);
117539e6 624
117539e6
KR
625 delete_thread (thr);
626 }
627
628 /* The GDB core expects that the rest of the threads are running. */
629 if (ptrace (PT_CONTINUE, pid, (void *) 1, 0) == -1)
630 perror_with_name (("ptrace"));
631
632 return wptid;
633 }
634
f94b2e03
KR
635 if (in_thread_list (this, ptid_t (pid)))
636 thread_change_ptid (this, ptid_t (pid), wptid);
637
117539e6
KR
638 if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE)
639 {
640 /* If GDB attaches to a multi-threaded process, newborn
641 threads might be added by nbsd_add_threads that have
642 not yet reported their PTRACE_LWP_CREATE event. Ignore
643 born events for an already-known LWP. */
644 if (in_thread_list (this, wptid))
183be222 645 ourstatus->set_spurious ();
117539e6
KR
646 else
647 {
648 add_thread (this, wptid);
183be222 649 ourstatus->set_thread_created ();
117539e6
KR
650 }
651 return wptid;
652 }
653
f94b2e03
KR
654 if (code == TRAP_EXEC)
655 {
183be222 656 ourstatus->set_execd (make_unique_xstrdup (pid_to_exec_file (pid)));
f94b2e03
KR
657 return wptid;
658 }
659
660 if (code == TRAP_TRACE)
661 {
662 /* Unhandled at this level. */
663 return wptid;
664 }
665
666 if (code == TRAP_SCE || code == TRAP_SCX)
667 {
668 int sysnum = si->si_sysnum;
669
670 if (!catch_syscall_enabled () || !catching_syscall_number (sysnum))
671 {
672 /* If the core isn't interested in this event, ignore it. */
183be222 673 ourstatus->set_spurious ();
f94b2e03
KR
674 return wptid;
675 }
676
183be222
SM
677 if (code == TRAP_SCE)
678 ourstatus->set_syscall_entry (sysnum);
679 else
680 ourstatus->set_syscall_return (sysnum);
f94b2e03
KR
681 return wptid;
682 }
683
684 if (code == TRAP_BRKPT)
685 {
686 /* Unhandled at this level. */
687 return wptid;
688 }
689
690 /* Unclassified SIGTRAP event. */
183be222 691 ourstatus->set_spurious ();
f94b2e03
KR
692 return wptid;
693}
694
695/* Implement the "insert_exec_catchpoint" target_ops method. */
696
697int
698nbsd_nat_target::insert_exec_catchpoint (int pid)
699{
700 /* Nothing to do. */
701 return 0;
702}
703
704/* Implement the "remove_exec_catchpoint" target_ops method. */
705
706int
707nbsd_nat_target::remove_exec_catchpoint (int pid)
708{
709 /* Nothing to do. */
710 return 0;
711}
712
713/* Implement the "set_syscall_catchpoint" target_ops method. */
714
715int
716nbsd_nat_target::set_syscall_catchpoint (int pid, bool needed,
dda83cd7
SM
717 int any_count,
718 gdb::array_view<const int> syscall_counts)
f94b2e03
KR
719{
720 /* Ignore the arguments. inf-ptrace.c will use PT_SYSCALL which
721 will catch all system call entries and exits. The system calls
722 are filtered by GDB rather than the kernel. */
723 return 0;
724}
1de14d77
KR
725
726/* Implement the "supports_multi_process" target_ops method. */
727
728bool
729nbsd_nat_target::supports_multi_process ()
730{
731 return true;
732}
4d46f402
KR
733
734/* Implement the "xfer_partial" target_ops method. */
735
736enum target_xfer_status
737nbsd_nat_target::xfer_partial (enum target_object object,
738 const char *annex, gdb_byte *readbuf,
739 const gdb_byte *writebuf,
740 ULONGEST offset, ULONGEST len,
741 ULONGEST *xfered_len)
742{
743 pid_t pid = inferior_ptid.pid ();
744
745 switch (object)
746 {
747 case TARGET_OBJECT_SIGNAL_INFO:
748 {
cf4ac4be
KR
749 len = netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset,
750 len);
4d46f402 751
cf4ac4be 752 if (len == -1)
4d46f402
KR
753 return TARGET_XFER_E_IO;
754
4d46f402
KR
755 *xfered_len = len;
756 return TARGET_XFER_OK;
757 }
91e5e8db
KR
758 case TARGET_OBJECT_MEMORY:
759 {
760 size_t xfered;
761 int res;
762 if (writebuf != nullptr)
763 res = netbsd_nat::write_memory (pid, writebuf, offset, len, &xfered);
764 else
765 res = netbsd_nat::read_memory (pid, readbuf, offset, len, &xfered);
766 if (res != 0)
767 {
768 if (res == EACCES)
6cb06a8c
TT
769 gdb_printf (gdb_stderr, "Cannot %s process at %s (%s). "
770 "Is PaX MPROTECT active? See security(7), "
771 "sysctl(7), paxctl(8)\n",
772 (writebuf ? "write to" : "read from"),
773 pulongest (offset), safe_strerror (errno));
91e5e8db
KR
774 return TARGET_XFER_E_IO;
775 }
776 if (xfered == 0)
777 return TARGET_XFER_EOF;
778 *xfered_len = (ULONGEST) xfered;
779 return TARGET_XFER_OK;
780 }
4d46f402
KR
781 default:
782 return inf_ptrace_target::xfer_partial (object, annex,
783 readbuf, writebuf, offset,
784 len, xfered_len);
785 }
786}
a6e6223e
KR
787
788/* Implement the "supports_dumpcore" target_ops method. */
789
790bool
791nbsd_nat_target::supports_dumpcore ()
792{
793 return true;
794}
795
796/* Implement the "dumpcore" target_ops method. */
797
798void
799nbsd_nat_target::dumpcore (const char *filename)
800{
801 pid_t pid = inferior_ptid.pid ();
802
803 if (ptrace (PT_DUMPCORE, pid, const_cast<char *>(filename),
804 strlen (filename)) == -1)
805 perror_with_name (("ptrace"));
806}