]> Git Repo - binutils.git/blob - gdb/netbsd-nat.c
gdb: handle case where type alignment is unknown
[binutils.git] / gdb / netbsd-nat.c
1 /* Native-dependent code for NetBSD.
2
3    Copyright (C) 2006-2021 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
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 char *
38 nbsd_nat_target::pid_to_exec_file (int pid)
39 {
40   return const_cast<char *> (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 "post_startup_inferior" target_ops 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           fprintf_filtered (gdb_stdout,
251                             "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, 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   printf_filtered (_("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         printf_filtered ("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         printf_filtered ("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         printf_filtered ("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           printf_filtered ("Name: %s\n", kp.p_comm);
403           printf_filtered ("State: %s\n", process_status(kp.p_realstat));
404           printf_filtered ("Parent process: %" PRId32 "\n", kp.p_ppid);
405           printf_filtered ("Process group: %" PRId32 "\n", kp.p__pgid);
406           printf_filtered ("Session id: %" PRId32 "\n", kp.p_sid);
407           printf_filtered ("TTY: %" PRId32 "\n", kp.p_tdev);
408           printf_filtered ("TTY owner process group: %" PRId32 "\n", kp.p_tpgid);
409           printf_filtered ("User IDs (real, effective, saved): "
410                            "%" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
411                            kp.p_ruid, kp.p_uid, kp.p_svuid);
412           printf_filtered ("Group IDs (real, effective, saved): "
413                            "%" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
414                            kp.p_rgid, kp.p_gid, kp.p_svgid);
415
416           printf_filtered ("Groups:");
417           for (int i = 0; i < kp.p_ngroups; i++)
418             printf_filtered (" %" PRIu32, kp.p_groups[i]);
419           printf_filtered ("\n");
420           printf_filtered ("Minor faults (no memory page): %" PRIu64 "\n",
421                            kp.p_uru_minflt);
422           printf_filtered ("Major faults (memory page faults): %" PRIu64 "\n",
423                            kp.p_uru_majflt);
424           printf_filtered ("utime: %" PRIu32 ".%06" PRIu32 "\n",
425                            kp.p_uutime_sec, kp.p_uutime_usec);
426           printf_filtered ("stime: %" PRIu32 ".%06" PRIu32 "\n",
427                            kp.p_ustime_sec, kp.p_ustime_usec);
428           printf_filtered ("utime+stime, children: %" PRIu32 ".%06" PRIu32 "\n",
429                            kp.p_uctime_sec, kp.p_uctime_usec);
430           printf_filtered ("'nice' value: %" PRIu8 "\n", kp.p_nice);
431           printf_filtered ("Start time: %" PRIu32 ".%06" PRIu32 "\n",
432                            kp.p_ustart_sec, kp.p_ustart_usec);
433           int pgtok = getpagesize () / 1024;
434           printf_filtered ("Data size: %" PRIuMAX " kB\n",
435                            (uintmax_t) kp.p_vm_dsize * pgtok);
436           printf_filtered ("Stack size: %" PRIuMAX " kB\n",
437                            (uintmax_t) kp.p_vm_ssize * pgtok);
438           printf_filtered ("Text size: %" PRIuMAX " kB\n",
439                            (uintmax_t) kp.p_vm_tsize * pgtok);
440           printf_filtered ("Resident set size: %" PRIuMAX " kB\n",
441                            (uintmax_t) kp.p_vm_rssize * pgtok);
442           printf_filtered ("Maximum RSS: %" PRIu64 " kB\n", kp.p_uru_maxrss);
443           printf_filtered ("Pending Signals:");
444           for (size_t i = 0; i < ARRAY_SIZE (kp.p_siglist.__bits); i++)
445             printf_filtered (" %08" PRIx32, kp.p_siglist.__bits[i]);
446           printf_filtered ("\n");
447           printf_filtered ("Ignored Signals:");
448           for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigignore.__bits); i++)
449             printf_filtered (" %08" PRIx32, kp.p_sigignore.__bits[i]);
450           printf_filtered ("\n");
451           printf_filtered ("Caught Signals:");
452           for (size_t i = 0; i < ARRAY_SIZE (kp.p_sigcatch.__bits); i++)
453             printf_filtered (" %08" PRIx32, kp.p_sigcatch.__bits[i]);
454           printf_filtered ("\n");
455         }
456     }
457
458   return true;
459 }
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
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 () > 0)
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
528 void
529 nbsd_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
542 static pid_t
543 nbsd_wait (ptid_t ptid, struct target_waitstatus *ourstatus,
544            target_wait_flags options)
545 {
546   pid_t pid;
547   int status;
548
549   set_sigint_trap ();
550
551   do
552     {
553       /* The common code passes WNOHANG that leads to crashes, overwrite it.  */
554       pid = waitpid (ptid.pid (), &status, 0);
555     }
556   while (pid == -1 && errno == EINTR);
557
558   clear_sigint_trap ();
559
560   if (pid == -1)
561     perror_with_name (_("Child process unexpectedly missing"));
562
563   store_waitstatus (ourstatus, status);
564   return pid;
565 }
566
567 /* Wait for the child specified by PTID to do something.  Return the
568    process ID of the child, or MINUS_ONE_PTID in case of error; store
569    the status in *OURSTATUS.  */
570
571 ptid_t
572 nbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
573                        target_wait_flags target_options)
574 {
575   pid_t pid = nbsd_wait (ptid, ourstatus, target_options);
576   ptid_t wptid = ptid_t (pid);
577
578   /* If the child stopped, keep investigating its status.  */
579   if (ourstatus->kind != TARGET_WAITKIND_STOPPED)
580     return wptid;
581
582   /* Extract the event and thread that received a signal.  */
583   ptrace_siginfo_t psi;
584   if (ptrace (PT_GET_SIGINFO, pid, &psi, sizeof (psi)) == -1)
585     perror_with_name (("ptrace"));
586
587   /* Pick child's siginfo_t.  */
588   siginfo_t *si = &psi.psi_siginfo;
589
590   int lwp = psi.psi_lwpid;
591
592   int signo = si->si_signo;
593   const int code = si->si_code;
594
595   /* Construct PTID with a specified thread that received the event.
596      If a signal was targeted to the whole process, lwp is 0.  */
597   wptid = ptid_t (pid, lwp, 0);
598
599   /* Bail out on non-debugger oriented signals..  */
600   if (signo != SIGTRAP)
601     return wptid;
602
603   /* Stop examining non-debugger oriented SIGTRAP codes.  */
604   if (code <= SI_USER || code == SI_NOINFO)
605     return wptid;
606
607   /* Process state for threading events */
608   ptrace_state_t pst = {};
609   if (code == TRAP_LWP)
610     {
611       if (ptrace (PT_GET_PROCESS_STATE, pid, &pst, sizeof (pst)) == -1)
612         perror_with_name (("ptrace"));
613     }
614
615   if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_EXIT)
616     {
617       /* If GDB attaches to a multi-threaded process, exiting
618          threads might be skipped during post_attach that
619          have not yet reported their PTRACE_LWP_EXIT event.
620          Ignore exited events for an unknown LWP.  */
621       thread_info *thr = find_thread_ptid (this, wptid);
622       if (thr == nullptr)
623           ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
624       else
625         {
626           ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
627           /* NetBSD does not store an LWP exit status.  */
628           ourstatus->value.integer = 0;
629
630           if (print_thread_events)
631             printf_unfiltered (_("[%s exited]\n"),
632                                target_pid_to_str (wptid).c_str ());
633           delete_thread (thr);
634         }
635
636       /* The GDB core expects that the rest of the threads are running.  */
637       if (ptrace (PT_CONTINUE, pid, (void *) 1, 0) == -1)
638         perror_with_name (("ptrace"));
639
640       return wptid;
641     }
642
643   if (in_thread_list (this, ptid_t (pid)))
644       thread_change_ptid (this, ptid_t (pid), wptid);
645
646   if (code == TRAP_LWP && pst.pe_report_event == PTRACE_LWP_CREATE)
647     {
648       /* If GDB attaches to a multi-threaded process, newborn
649          threads might be added by nbsd_add_threads that have
650          not yet reported their PTRACE_LWP_CREATE event.  Ignore
651          born events for an already-known LWP.  */
652       if (in_thread_list (this, wptid))
653           ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
654       else
655         {
656           add_thread (this, wptid);
657           ourstatus->kind = TARGET_WAITKIND_THREAD_CREATED;
658         }
659       return wptid;
660     }
661
662   if (code == TRAP_EXEC)
663     {
664       ourstatus->kind = TARGET_WAITKIND_EXECD;
665       ourstatus->value.execd_pathname = xstrdup (pid_to_exec_file (pid));
666       return wptid;
667     }
668
669   if (code == TRAP_TRACE)
670     {
671       /* Unhandled at this level.  */
672       return wptid;
673     }
674
675   if (code == TRAP_SCE || code == TRAP_SCX)
676     {
677       int sysnum = si->si_sysnum;
678
679       if (!catch_syscall_enabled () || !catching_syscall_number (sysnum))
680         {
681           /* If the core isn't interested in this event, ignore it.  */
682           ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
683           return wptid;
684         }
685
686       ourstatus->kind =
687         (code == TRAP_SCE) ? TARGET_WAITKIND_SYSCALL_ENTRY :
688         TARGET_WAITKIND_SYSCALL_RETURN;
689       ourstatus->value.syscall_number = sysnum;
690       return wptid;
691     }
692
693   if (code == TRAP_BRKPT)
694     {
695       /* Unhandled at this level.  */
696       return wptid;
697     }
698
699   /* Unclassified SIGTRAP event.  */
700   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
701   return wptid;
702 }
703
704 /* Implement the "insert_exec_catchpoint" target_ops method.  */
705
706 int
707 nbsd_nat_target::insert_exec_catchpoint (int pid)
708 {
709   /* Nothing to do.  */
710   return 0;
711 }
712
713 /* Implement the "remove_exec_catchpoint" target_ops method.  */
714
715 int
716 nbsd_nat_target::remove_exec_catchpoint (int pid)
717 {
718   /* Nothing to do.  */
719   return 0;
720 }
721
722 /* Implement the "set_syscall_catchpoint" target_ops method.  */
723
724 int
725 nbsd_nat_target::set_syscall_catchpoint (int pid, bool needed,
726                                          int any_count,
727                                          gdb::array_view<const int> syscall_counts)
728 {
729   /* Ignore the arguments.  inf-ptrace.c will use PT_SYSCALL which
730      will catch all system call entries and exits.  The system calls
731      are filtered by GDB rather than the kernel.  */
732   return 0;
733 }
734
735 /* Implement the "supports_multi_process" target_ops method. */
736
737 bool
738 nbsd_nat_target::supports_multi_process ()
739 {
740   return true;
741 }
742
743 /* Implement the "xfer_partial" target_ops method.  */
744
745 enum target_xfer_status
746 nbsd_nat_target::xfer_partial (enum target_object object,
747                                const char *annex, gdb_byte *readbuf,
748                                const gdb_byte *writebuf,
749                                ULONGEST offset, ULONGEST len,
750                                ULONGEST *xfered_len)
751 {
752   pid_t pid = inferior_ptid.pid ();
753
754   switch (object)
755     {
756     case TARGET_OBJECT_SIGNAL_INFO:
757       {
758         len = netbsd_nat::qxfer_siginfo(pid, annex, readbuf, writebuf, offset,
759                                         len);
760
761         if (len == -1)
762           return TARGET_XFER_E_IO;
763
764         *xfered_len = len;
765         return TARGET_XFER_OK;
766       }
767     case TARGET_OBJECT_MEMORY:
768       {
769         size_t xfered;
770         int res;
771         if (writebuf != nullptr)
772           res = netbsd_nat::write_memory (pid, writebuf, offset, len, &xfered);
773         else
774           res = netbsd_nat::read_memory (pid, readbuf, offset, len, &xfered);
775         if (res != 0)
776           {
777             if (res == EACCES)
778               fprintf_unfiltered (gdb_stderr, "Cannot %s process at %s (%s). "
779                                   "Is PaX MPROTECT active? See security(7), "
780                                   "sysctl(7), paxctl(8)\n",
781                                   (writebuf ? "write to" : "read from"),
782                                   pulongest (offset), safe_strerror (errno));
783             return TARGET_XFER_E_IO;
784           }
785         if (xfered == 0)
786           return TARGET_XFER_EOF;
787         *xfered_len = (ULONGEST) xfered;
788         return TARGET_XFER_OK;
789       }
790     default:
791       return inf_ptrace_target::xfer_partial (object, annex,
792                                               readbuf, writebuf, offset,
793                                               len, xfered_len);
794     }
795 }
796
797 /* Implement the "supports_dumpcore" target_ops method.  */
798
799 bool
800 nbsd_nat_target::supports_dumpcore ()
801 {
802   return true;
803 }
804
805 /* Implement the "dumpcore" target_ops method.  */
806
807 void
808 nbsd_nat_target::dumpcore (const char *filename)
809 {
810   pid_t pid = inferior_ptid.pid ();
811
812   if (ptrace (PT_DUMPCORE, pid, const_cast<char *>(filename),
813               strlen (filename)) == -1)
814     perror_with_name (("ptrace"));
815 }
This page took 0.071768 seconds and 4 git commands to generate.