1 /* Native-dependent code for NetBSD. 2 3 Copyright (C) 2006-2024 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 21 #include "netbsd-nat.h" 22 #include "nat/netbsd-nat.h" 23 #include "gdbthread.h" 24 #include "netbsd-tdep.h" 25 #include "inferior.h" 26 #include "gdbarch.h" 27 #include "gdbsupport/buildargv.h" 28 29 #include <sys/types.h> 30 #include <sys/ptrace.h> 31 #include <sys/sysctl.h> 32 #include <sys/wait.h> 33 34 /* Return the name of a file that can be opened to get the symbols for 35 the child process identified by PID. */ 36 37 const char * 38 nbsd_nat_target::pid_to_exec_file (int pid) 39 { 40 return netbsd_nat::pid_to_exec_file (pid); 41 } 42 43 /* Return the current directory for the process identified by PID. */ 44 45 static std::string 46 nbsd_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 57 /* Return the kinfo_proc2 structure for the process identified by PID. */ 58 59 static bool 60 nbsd_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 70 /* Return the command line for the process identified by PID. */ 71 72 static gdb::unique_xmalloc_ptr<char[]> 73 nbsd_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; 78 if (::sysctl (mib, ARRAY_SIZE (mib), NULL, &size, NULL, 0) == -1 || size == 0) 79 return nullptr; 80 81 gdb::unique_xmalloc_ptr<char[]> args (XNEWVAR (char, size)); 82 83 if (::sysctl (mib, ARRAY_SIZE (mib), args.get (), &size, NULL, 0) == -1 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 97 /* Return true if PTID is still active in the inferior. */ 98 99 bool 100 nbsd_nat_target::thread_alive (ptid_t ptid) 101 { 102 return netbsd_nat::thread_alive (ptid); 103 } 104 105 /* Return the name assigned to a thread by an application. Returns 106 the string in a static buffer. */ 107 108 const char * 109 nbsd_nat_target::thread_name (struct thread_info *thr) 110 { 111 ptid_t ptid = thr->ptid; 112 return netbsd_nat::thread_name (ptid); 113 } 114 115 /* Implement the "post_attach" target_ops method. */ 116 117 static void 118 nbsd_add_threads (nbsd_nat_target *target, pid_t pid) 119 { 120 auto fn 121 = [&target] (ptid_t ptid) 122 { 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 } 130 }; 131 132 netbsd_nat::for_each_thread (pid, fn); 133 } 134 135 /* Implement the virtual inf_ptrace_target::post_startup_inferior method. */ 136 137 void 138 nbsd_nat_target::post_startup_inferior (ptid_t ptid) 139 { 140 netbsd_nat::enable_proc_events (ptid.pid ()); 141 } 142 143 /* Implement the "post_attach" target_ops method. */ 144 145 void 146 nbsd_nat_target::post_attach (int pid) 147 { 148 netbsd_nat::enable_proc_events (pid); 149 nbsd_add_threads (this, pid); 150 } 151 152 /* Implement the "update_thread_list" target_ops method. */ 153 154 void 155 nbsd_nat_target::update_thread_list () 156 { 157 delete_exited_threads (); 158 } 159 160 /* Convert PTID to a string. */ 161 162 std::string 163 nbsd_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 } 176 177 /* Retrieve all the memory regions in the specified process. */ 178 179 static gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> 180 nbsd_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 214 int 215 nbsd_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 { 250 gdb_printf ("Save segment, %ld bytes at %s (%c%c%c)\n", 251 (long) size, 252 paddress (current_inferior ()->arch (), 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' : '-'); 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, false, data); 263 } 264 return 0; 265 } 266 267 /* Implement the "info_proc" target_ops method. */ 268 269 bool 270 nbsd_nat_target::info_proc (const char *args, enum info_proc_what what) 271 { 272 pid_t pid; 273 bool do_cmdline = false; 274 bool do_cwd = false; 275 bool do_exe = false; 276 bool do_mappings = false; 277 bool do_status = false; 278 279 switch (what) 280 { 281 case IP_MINIMAL: 282 do_cmdline = true; 283 do_cwd = true; 284 do_exe = true; 285 break; 286 case IP_STAT: 287 case IP_STATUS: 288 do_status = true; 289 break; 290 case IP_MAPPINGS: 291 do_mappings = true; 292 break; 293 case IP_CMDLINE: 294 do_cmdline = true; 295 break; 296 case IP_EXE: 297 do_exe = true; 298 break; 299 case IP_CWD: 300 do_cwd = true; 301 break; 302 case IP_ALL: 303 do_cmdline = true; 304 do_cwd = true; 305 do_exe = true; 306 do_mappings = true; 307 do_status = true; 308 break; 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) 318 error (_("No current process: you must name one.")); 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 325 gdb_printf (_("process %d\n"), pid); 326 327 if (do_cmdline) 328 { 329 gdb::unique_xmalloc_ptr<char[]> cmdline = nbsd_pid_to_cmdline (pid); 330 if (cmdline != nullptr) 331 gdb_printf ("cmdline = '%s'\n", cmdline.get ()); 332 else 333 warning (_("unable to fetch command line")); 334 } 335 if (do_cwd) 336 { 337 std::string cwd = nbsd_pid_to_cwd (pid); 338 if (cwd != "") 339 gdb_printf ("cwd = '%s'\n", cwd.c_str ()); 340 else 341 warning (_("unable to fetch current working directory")); 342 } 343 if (do_exe) 344 { 345 const char *exe = pid_to_exec_file (pid); 346 if (exe != nullptr) 347 gdb_printf ("exe = '%s'\n", exe); 348 else 349 warning (_("unable to fetch executable path name")); 350 } 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 } 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 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:"); 416 for (int i = 0; i < kp.p_ngroups; i++) 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); 432 int pgtok = getpagesize () / 1024; 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:"); 443 for (size_t i = 0; i < ARRAY_SIZE (kp.p_siglist.__bits); i++) 444 gdb_printf (" %08" PRIx32, kp.p_siglist.__bits[i]); 445 gdb_printf ("\n"); 446 gdb_printf ("Ignored Signals:"); 447 for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigignore.__bits); i++) 448 gdb_printf (" %08" PRIx32, kp.p_sigignore.__bits[i]); 449 gdb_printf ("\n"); 450 gdb_printf ("Caught Signals:"); 451 for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigcatch.__bits); i++) 452 gdb_printf (" %08" PRIx32, kp.p_sigcatch.__bits[i]); 453 gdb_printf ("\n"); 454 } 455 } 456 457 return true; 458 } 459 460 #ifdef PT_STEP 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 466 static void 467 nbsd_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 ()) 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 } 489 } 490 else 491 { 492 /* If ptid is a wildcard, resume all matching threads (they won't run 493 until the process is continued however). */ 494 for (thread_info *tp : all_non_exited_threads (target, ptid)) 495 if (ptrace (PT_RESUME, tp->ptid.pid (), NULL, tp->ptid.lwp ()) == -1) 496 perror_with_name (("ptrace")); 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 512 if (catch_syscall_enabled ()) 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 #endif 524 525 /* Resume execution of thread PTID, or all threads of all inferiors 526 if PTID is -1. If STEP is nonzero, single-step it. If SIGNAL is nonzero, 527 give it that signal. */ 528 529 void 530 nbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal) 531 { 532 #ifdef PT_STEP 533 if (minus_one_ptid != ptid) 534 nbsd_resume (this, ptid, step, signal); 535 else 536 { 537 for (inferior *inf : all_non_exited_inferiors (this)) 538 nbsd_resume (this, ptid_t (inf->pid, 0, 0), step, signal); 539 } 540 #else 541 gdb_assert(step == 0); 542 if (ptid.pid () == -1) 543 ptid = inferior_ptid; 544 inf_ptrace_target::resume (ptid, step, signal); 545 #endif 546 } 547 548 /* Implement a safe wrapper around waitpid(). */ 549 550 static pid_t 551 nbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus, 552 target_wait_flags options) 553 { 554 pid_t pid; 555 int status; 556 557 set_sigint_trap (); 558 559 do 560 { 561 /* The common code passes WNOHANG that leads to crashes, overwrite it. */ 562 pid = waitpid (ptid.pid (), &status, 0); 563 } 564 while (pid == -1 && errno == EINTR); 565 566 clear_sigint_trap (); 567 568 if (pid == -1) 569 perror_with_name (_("Child process unexpectedly missing")); 570 571 *ourstatus = host_status_to_waitstatus (status); 572 return pid; 573 } 574 575 /* Wait for the child specified by PTID to do something. Return the 576 process ID of the child, or MINUS_ONE_PTID in case of error; store 577 the status in *OURSTATUS. */ 578 579 ptid_t 580 nbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, 581 target_wait_flags target_options) 582 { 583 again: 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 = this->find_thread (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 delete_thread (thr); 639 } 640 641 /* The GDB core expects that the rest of the threads are running. */ 642 if (ptrace (PT_CONTINUE, pid, (void *) 1, 0) == -1) 643 perror_with_name (("ptrace")); 644 goto again; 645 } 646 647 if (in_thread_list (this, ptid_t (pid))) 648 thread_change_ptid (this, ptid_t (pid), wptid); 649 650 if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE) 651 { 652 /* If GDB attaches to a multi-threaded process, newborn 653 threads might be added by nbsd_add_threads that have 654 not yet reported their PTRACE_LWP_CREATE event. Ignore 655 born events for an already-known LWP. */ 656 if (in_thread_list (this, wptid)) 657 ourstatus->set_spurious (); 658 else 659 { 660 add_thread (this, wptid); 661 ourstatus->set_thread_created (); 662 } 663 return wptid; 664 } 665 666 if (code == TRAP_EXEC) 667 { 668 ourstatus->set_execd (make_unique_xstrdup (pid_to_exec_file (pid))); 669 return wptid; 670 } 671 672 if (code == TRAP_TRACE) 673 { 674 /* Unhandled at this level. */ 675 return wptid; 676 } 677 678 if (code == TRAP_SCE || code == TRAP_SCX) 679 { 680 int sysnum = si->si_sysnum; 681 682 if (!catch_syscall_enabled () || !catching_syscall_number (sysnum)) 683 { 684 /* If the core isn't interested in this event, ignore it. */ 685 ourstatus->set_spurious (); 686 return wptid; 687 } 688 689 if (code == TRAP_SCE) 690 ourstatus->set_syscall_entry (sysnum); 691 else 692 ourstatus->set_syscall_return (sysnum); 693 return wptid; 694 } 695 696 if (code == TRAP_BRKPT) 697 { 698 /* Unhandled at this level. */ 699 return wptid; 700 } 701 702 /* Unclassified SIGTRAP event. */ 703 ourstatus->set_spurious (); 704 return wptid; 705 } 706 707 /* Implement the "insert_exec_catchpoint" target_ops method. */ 708 709 int 710 nbsd_nat_target::insert_exec_catchpoint (int pid) 711 { 712 /* Nothing to do. */ 713 return 0; 714 } 715 716 /* Implement the "remove_exec_catchpoint" target_ops method. */ 717 718 int 719 nbsd_nat_target::remove_exec_catchpoint (int pid) 720 { 721 /* Nothing to do. */ 722 return 0; 723 } 724 725 /* Implement the "set_syscall_catchpoint" target_ops method. */ 726 727 int 728 nbsd_nat_target::set_syscall_catchpoint (int pid, bool needed, 729 int any_count, 730 gdb::array_view<const int> syscall_counts) 731 { 732 /* Ignore the arguments. inf-ptrace.c will use PT_SYSCALL which 733 will catch all system call entries and exits. The system calls 734 are filtered by GDB rather than the kernel. */ 735 return 0; 736 } 737 738 /* Implement the "supports_multi_process" target_ops method. */ 739 740 bool 741 nbsd_nat_target::supports_multi_process () 742 { 743 return true; 744 } 745 746 /* Implement the "xfer_partial" target_ops method. */ 747 748 enum target_xfer_status 749 nbsd_nat_target::xfer_partial (enum target_object object, 750 const char *annex, gdb_byte *readbuf, 751 const gdb_byte *writebuf, 752 ULONGEST offset, ULONGEST len, 753 ULONGEST *xfered_len) 754 { 755 pid_t pid = inferior_ptid.pid (); 756 757 switch (object) 758 { 759 case TARGET_OBJECT_SIGNAL_INFO: 760 { 761 len = netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset, 762 len); 763 764 if (len == -1) 765 return TARGET_XFER_E_IO; 766 767 *xfered_len = len; 768 return TARGET_XFER_OK; 769 } 770 case TARGET_OBJECT_MEMORY: 771 { 772 size_t xfered; 773 int res; 774 if (writebuf != nullptr) 775 res = netbsd_nat::write_memory (pid, writebuf, offset, len, &xfered); 776 else 777 res = netbsd_nat::read_memory (pid, readbuf, offset, len, &xfered); 778 if (res != 0) 779 { 780 if (res == EACCES) 781 gdb_printf (gdb_stderr, "Cannot %s process at %s (%s). " 782 "Is PaX MPROTECT active? See security(7), " 783 "sysctl(7), paxctl(8)\n", 784 (writebuf ? "write to" : "read from"), 785 pulongest (offset), safe_strerror (errno)); 786 return TARGET_XFER_E_IO; 787 } 788 if (xfered == 0) 789 return TARGET_XFER_EOF; 790 *xfered_len = (ULONGEST) xfered; 791 return TARGET_XFER_OK; 792 } 793 default: 794 return inf_ptrace_target::xfer_partial (object, annex, 795 readbuf, writebuf, offset, 796 len, xfered_len); 797 } 798 } 799 800 /* Implement the "supports_dumpcore" target_ops method. */ 801 802 bool 803 nbsd_nat_target::supports_dumpcore () 804 { 805 return true; 806 } 807 808 /* Implement the "dumpcore" target_ops method. */ 809 810 void 811 nbsd_nat_target::dumpcore (const char *filename) 812 { 813 pid_t pid = inferior_ptid.pid (); 814 815 if (ptrace (PT_DUMPCORE, pid, const_cast<char *>(filename), 816 strlen (filename)) == -1) 817 perror_with_name (("ptrace")); 818 } 819