linux-ptrace.c revision 1.4 1 1.1 christos /* Linux-specific ptrace manipulation routines.
2 1.4 christos Copyright (C) 2012-2016 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of GDB.
5 1.1 christos
6 1.1 christos This program is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3 of the License, or
9 1.1 christos (at your option) any later version.
10 1.1 christos
11 1.1 christos This program is distributed in the hope that it will be useful,
12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 christos GNU General Public License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 1.1 christos
19 1.1 christos #include "common-defs.h"
20 1.1 christos #include "linux-ptrace.h"
21 1.1 christos #include "linux-procfs.h"
22 1.1 christos #include "linux-waitpid.h"
23 1.1 christos #include "buffer.h"
24 1.1 christos #include "gdb_wait.h"
25 1.4 christos #include "gdb_ptrace.h"
26 1.4 christos #include <sys/procfs.h>
27 1.1 christos
28 1.3 christos /* Stores the ptrace options supported by the running kernel.
29 1.3 christos A value of -1 means we did not check for features yet. A value
30 1.3 christos of 0 means there are no supported features. */
31 1.3 christos static int supported_ptrace_options = -1;
32 1.1 christos
33 1.1 christos /* Find all possible reasons we could fail to attach PID and append
34 1.1 christos these as strings to the already initialized BUFFER. '\0'
35 1.1 christos termination of BUFFER must be done by the caller. */
36 1.1 christos
37 1.1 christos void
38 1.1 christos linux_ptrace_attach_fail_reason (pid_t pid, struct buffer *buffer)
39 1.1 christos {
40 1.1 christos pid_t tracerpid;
41 1.1 christos
42 1.1 christos tracerpid = linux_proc_get_tracerpid_nowarn (pid);
43 1.1 christos if (tracerpid > 0)
44 1.1 christos buffer_xml_printf (buffer, _("process %d is already traced "
45 1.1 christos "by process %d"),
46 1.1 christos (int) pid, (int) tracerpid);
47 1.1 christos
48 1.1 christos if (linux_proc_pid_is_zombie_nowarn (pid))
49 1.1 christos buffer_xml_printf (buffer, _("process %d is a zombie "
50 1.1 christos "- the process has already terminated"),
51 1.1 christos (int) pid);
52 1.1 christos }
53 1.1 christos
54 1.1 christos /* See linux-ptrace.h. */
55 1.1 christos
56 1.1 christos char *
57 1.1 christos linux_ptrace_attach_fail_reason_string (ptid_t ptid, int err)
58 1.1 christos {
59 1.1 christos static char *reason_string;
60 1.1 christos struct buffer buffer;
61 1.1 christos char *warnings;
62 1.1 christos long lwpid = ptid_get_lwp (ptid);
63 1.1 christos
64 1.1 christos xfree (reason_string);
65 1.1 christos
66 1.1 christos buffer_init (&buffer);
67 1.1 christos linux_ptrace_attach_fail_reason (lwpid, &buffer);
68 1.1 christos buffer_grow_str0 (&buffer, "");
69 1.1 christos warnings = buffer_finish (&buffer);
70 1.1 christos if (warnings[0] != '\0')
71 1.1 christos reason_string = xstrprintf ("%s (%d), %s",
72 1.3 christos safe_strerror (err), err, warnings);
73 1.1 christos else
74 1.1 christos reason_string = xstrprintf ("%s (%d)",
75 1.3 christos safe_strerror (err), err);
76 1.1 christos xfree (warnings);
77 1.1 christos return reason_string;
78 1.1 christos }
79 1.1 christos
80 1.1 christos #if defined __i386__ || defined __x86_64__
81 1.1 christos
82 1.1 christos /* Address of the 'ret' instruction in asm code block below. */
83 1.3 christos EXTERN_C void linux_ptrace_test_ret_to_nx_instr (void);
84 1.1 christos
85 1.1 christos #include <sys/reg.h>
86 1.1 christos #include <sys/mman.h>
87 1.1 christos #include <signal.h>
88 1.1 christos
89 1.1 christos #endif /* defined __i386__ || defined __x86_64__ */
90 1.1 christos
91 1.1 christos /* Test broken off-trunk Linux kernel patchset for NX support on i386. It was
92 1.1 christos removed in Fedora kernel 88fa1f0332d188795ed73d7ac2b1564e11a0b4cd.
93 1.1 christos
94 1.1 christos Test also x86_64 arch for PaX support. */
95 1.1 christos
96 1.1 christos static void
97 1.1 christos linux_ptrace_test_ret_to_nx (void)
98 1.1 christos {
99 1.1 christos #if defined __i386__ || defined __x86_64__
100 1.1 christos pid_t child, got_pid;
101 1.1 christos gdb_byte *return_address, *pc;
102 1.1 christos long l;
103 1.1 christos int status, kill_status;
104 1.4 christos elf_gregset_t regs;
105 1.1 christos
106 1.4 christos return_address
107 1.4 christos = (gdb_byte *) mmap (NULL, 2, PROT_READ | PROT_WRITE,
108 1.1 christos MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
109 1.1 christos if (return_address == MAP_FAILED)
110 1.1 christos {
111 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: Cannot mmap: %s"),
112 1.3 christos safe_strerror (errno));
113 1.1 christos return;
114 1.1 christos }
115 1.1 christos
116 1.1 christos /* Put there 'int3'. */
117 1.1 christos *return_address = 0xcc;
118 1.1 christos
119 1.1 christos child = fork ();
120 1.1 christos switch (child)
121 1.1 christos {
122 1.1 christos case -1:
123 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: Cannot fork: %s"),
124 1.3 christos safe_strerror (errno));
125 1.1 christos return;
126 1.1 christos
127 1.1 christos case 0:
128 1.1 christos l = ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) NULL,
129 1.1 christos (PTRACE_TYPE_ARG4) NULL);
130 1.1 christos if (l != 0)
131 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_TRACEME: %s"),
132 1.3 christos safe_strerror (errno));
133 1.1 christos else
134 1.1 christos {
135 1.1 christos #if defined __i386__
136 1.1 christos asm volatile ("pushl %0;"
137 1.1 christos ".globl linux_ptrace_test_ret_to_nx_instr;"
138 1.1 christos "linux_ptrace_test_ret_to_nx_instr:"
139 1.1 christos "ret"
140 1.1 christos : : "r" (return_address) : "%esp", "memory");
141 1.1 christos #elif defined __x86_64__
142 1.1 christos asm volatile ("pushq %0;"
143 1.1 christos ".globl linux_ptrace_test_ret_to_nx_instr;"
144 1.1 christos "linux_ptrace_test_ret_to_nx_instr:"
145 1.1 christos "ret"
146 1.1 christos : : "r" ((uint64_t) (uintptr_t) return_address)
147 1.1 christos : "%rsp", "memory");
148 1.1 christos #else
149 1.1 christos # error "!__i386__ && !__x86_64__"
150 1.1 christos #endif
151 1.1 christos gdb_assert_not_reached ("asm block did not terminate");
152 1.1 christos }
153 1.1 christos
154 1.1 christos _exit (1);
155 1.1 christos }
156 1.1 christos
157 1.1 christos errno = 0;
158 1.1 christos got_pid = waitpid (child, &status, 0);
159 1.1 christos if (got_pid != child)
160 1.1 christos {
161 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: waitpid returned %ld: %s"),
162 1.3 christos (long) got_pid, safe_strerror (errno));
163 1.1 christos return;
164 1.1 christos }
165 1.1 christos
166 1.1 christos if (WIFSIGNALED (status))
167 1.1 christos {
168 1.1 christos if (WTERMSIG (status) != SIGKILL)
169 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: WTERMSIG %d is not SIGKILL!"),
170 1.1 christos (int) WTERMSIG (status));
171 1.1 christos else
172 1.1 christos warning (_("Cannot call inferior functions, Linux kernel PaX "
173 1.1 christos "protection forbids return to non-executable pages!"));
174 1.1 christos return;
175 1.1 christos }
176 1.1 christos
177 1.1 christos if (!WIFSTOPPED (status))
178 1.1 christos {
179 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: status %d is not WIFSTOPPED!"),
180 1.1 christos status);
181 1.1 christos return;
182 1.1 christos }
183 1.1 christos
184 1.1 christos /* We may get SIGSEGV due to missing PROT_EXEC of the return_address. */
185 1.1 christos if (WSTOPSIG (status) != SIGTRAP && WSTOPSIG (status) != SIGSEGV)
186 1.1 christos {
187 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: "
188 1.1 christos "WSTOPSIG %d is neither SIGTRAP nor SIGSEGV!"),
189 1.1 christos (int) WSTOPSIG (status));
190 1.1 christos return;
191 1.1 christos }
192 1.1 christos
193 1.4 christos if (ptrace (PTRACE_GETREGS, child, (PTRACE_TYPE_ARG3) 0,
194 1.4 christos (PTRACE_TYPE_ARG4) ®s) < 0)
195 1.4 christos {
196 1.4 christos warning (_("linux_ptrace_test_ret_to_nx: Cannot PTRACE_GETREGS: %s"),
197 1.4 christos safe_strerror (errno));
198 1.4 christos }
199 1.1 christos #if defined __i386__
200 1.4 christos pc = (gdb_byte *) (uintptr_t) regs[EIP];
201 1.1 christos #elif defined __x86_64__
202 1.4 christos pc = (gdb_byte *) (uintptr_t) regs[RIP];
203 1.1 christos #else
204 1.1 christos # error "!__i386__ && !__x86_64__"
205 1.1 christos #endif
206 1.1 christos
207 1.1 christos kill (child, SIGKILL);
208 1.1 christos ptrace (PTRACE_KILL, child, (PTRACE_TYPE_ARG3) NULL,
209 1.1 christos (PTRACE_TYPE_ARG4) NULL);
210 1.1 christos
211 1.1 christos errno = 0;
212 1.1 christos got_pid = waitpid (child, &kill_status, 0);
213 1.1 christos if (got_pid != child)
214 1.1 christos {
215 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: "
216 1.1 christos "PTRACE_KILL waitpid returned %ld: %s"),
217 1.3 christos (long) got_pid, safe_strerror (errno));
218 1.1 christos return;
219 1.1 christos }
220 1.1 christos if (!WIFSIGNALED (kill_status))
221 1.1 christos {
222 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: "
223 1.1 christos "PTRACE_KILL status %d is not WIFSIGNALED!"),
224 1.1 christos status);
225 1.1 christos return;
226 1.1 christos }
227 1.1 christos
228 1.1 christos /* + 1 is there as x86* stops after the 'int3' instruction. */
229 1.1 christos if (WSTOPSIG (status) == SIGTRAP && pc == return_address + 1)
230 1.1 christos {
231 1.1 christos /* PASS */
232 1.1 christos return;
233 1.1 christos }
234 1.1 christos
235 1.1 christos /* We may get SIGSEGV due to missing PROT_EXEC of the RETURN_ADDRESS page. */
236 1.1 christos if (WSTOPSIG (status) == SIGSEGV && pc == return_address)
237 1.1 christos {
238 1.1 christos /* PASS */
239 1.1 christos return;
240 1.1 christos }
241 1.1 christos
242 1.1 christos if ((void (*) (void)) pc != &linux_ptrace_test_ret_to_nx_instr)
243 1.1 christos warning (_("linux_ptrace_test_ret_to_nx: PC %p is neither near return "
244 1.1 christos "address %p nor is the return instruction %p!"),
245 1.1 christos pc, return_address, &linux_ptrace_test_ret_to_nx_instr);
246 1.1 christos else
247 1.1 christos warning (_("Cannot call inferior functions on this system - "
248 1.1 christos "Linux kernel with broken i386 NX (non-executable pages) "
249 1.1 christos "support detected!"));
250 1.1 christos #endif /* defined __i386__ || defined __x86_64__ */
251 1.1 christos }
252 1.1 christos
253 1.1 christos /* Helper function to fork a process and make the child process call
254 1.1 christos the function FUNCTION, passing CHILD_STACK as parameter.
255 1.1 christos
256 1.1 christos For MMU-less targets, clone is used instead of fork, and
257 1.1 christos CHILD_STACK is used as stack space for the cloned child. If NULL,
258 1.1 christos stack space is allocated via malloc (and subsequently passed to
259 1.1 christos FUNCTION). For MMU targets, CHILD_STACK is ignored. */
260 1.1 christos
261 1.1 christos static int
262 1.4 christos linux_fork_to_function (gdb_byte *child_stack, int (*function) (void *))
263 1.1 christos {
264 1.1 christos int child_pid;
265 1.1 christos
266 1.1 christos /* Sanity check the function pointer. */
267 1.1 christos gdb_assert (function != NULL);
268 1.1 christos
269 1.1 christos #if defined(__UCLIBC__) && defined(HAS_NOMMU)
270 1.1 christos #define STACK_SIZE 4096
271 1.1 christos
272 1.1 christos if (child_stack == NULL)
273 1.1 christos child_stack = xmalloc (STACK_SIZE * 4);
274 1.1 christos
275 1.1 christos /* Use CLONE_VM instead of fork, to support uClinux (no MMU). */
276 1.1 christos #ifdef __ia64__
277 1.1 christos child_pid = __clone2 (function, child_stack, STACK_SIZE,
278 1.1 christos CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);
279 1.1 christos #else /* !__ia64__ */
280 1.1 christos child_pid = clone (function, child_stack + STACK_SIZE,
281 1.1 christos CLONE_VM | SIGCHLD, child_stack + STACK_SIZE * 2);
282 1.1 christos #endif /* !__ia64__ */
283 1.1 christos #else /* !defined(__UCLIBC) && defined(HAS_NOMMU) */
284 1.1 christos child_pid = fork ();
285 1.1 christos
286 1.1 christos if (child_pid == 0)
287 1.1 christos function (NULL);
288 1.1 christos #endif /* defined(__UCLIBC) && defined(HAS_NOMMU) */
289 1.1 christos
290 1.1 christos if (child_pid == -1)
291 1.1 christos perror_with_name (("fork"));
292 1.1 christos
293 1.1 christos return child_pid;
294 1.1 christos }
295 1.1 christos
296 1.1 christos /* A helper function for linux_check_ptrace_features, called after
297 1.1 christos the child forks a grandchild. */
298 1.1 christos
299 1.4 christos static int
300 1.4 christos linux_grandchild_function (void *child_stack)
301 1.1 christos {
302 1.1 christos /* Free any allocated stack. */
303 1.1 christos xfree (child_stack);
304 1.1 christos
305 1.1 christos /* This code is only reacheable by the grandchild (child's child)
306 1.1 christos process. */
307 1.1 christos _exit (0);
308 1.1 christos }
309 1.1 christos
310 1.1 christos /* A helper function for linux_check_ptrace_features, called after
311 1.1 christos the parent process forks a child. The child allows itself to
312 1.1 christos be traced by its parent. */
313 1.1 christos
314 1.4 christos static int
315 1.4 christos linux_child_function (void *child_stack)
316 1.1 christos {
317 1.1 christos ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);
318 1.1 christos kill (getpid (), SIGSTOP);
319 1.1 christos
320 1.1 christos /* Fork a grandchild. */
321 1.4 christos linux_fork_to_function ((gdb_byte *) child_stack, linux_grandchild_function);
322 1.1 christos
323 1.1 christos /* This code is only reacheable by the child (grandchild's parent)
324 1.1 christos process. */
325 1.1 christos _exit (0);
326 1.1 christos }
327 1.1 christos
328 1.1 christos static void linux_test_for_tracesysgood (int child_pid);
329 1.1 christos static void linux_test_for_tracefork (int child_pid);
330 1.1 christos static void linux_test_for_exitkill (int child_pid);
331 1.1 christos
332 1.1 christos /* Determine ptrace features available on this target. */
333 1.1 christos
334 1.3 christos void
335 1.1 christos linux_check_ptrace_features (void)
336 1.1 christos {
337 1.1 christos int child_pid, ret, status;
338 1.1 christos
339 1.1 christos /* Initialize the options. */
340 1.3 christos supported_ptrace_options = 0;
341 1.1 christos
342 1.1 christos /* Fork a child so we can do some testing. The child will call
343 1.1 christos linux_child_function and will get traced. The child will
344 1.1 christos eventually fork a grandchild so we can test fork event
345 1.1 christos reporting. */
346 1.1 christos child_pid = linux_fork_to_function (NULL, linux_child_function);
347 1.1 christos
348 1.1 christos ret = my_waitpid (child_pid, &status, 0);
349 1.1 christos if (ret == -1)
350 1.1 christos perror_with_name (("waitpid"));
351 1.1 christos else if (ret != child_pid)
352 1.1 christos error (_("linux_check_ptrace_features: waitpid: unexpected result %d."),
353 1.1 christos ret);
354 1.1 christos if (! WIFSTOPPED (status))
355 1.1 christos error (_("linux_check_ptrace_features: waitpid: unexpected status %d."),
356 1.1 christos status);
357 1.1 christos
358 1.1 christos linux_test_for_tracesysgood (child_pid);
359 1.1 christos
360 1.1 christos linux_test_for_tracefork (child_pid);
361 1.1 christos
362 1.1 christos linux_test_for_exitkill (child_pid);
363 1.1 christos
364 1.1 christos /* Clean things up and kill any pending children. */
365 1.1 christos do
366 1.1 christos {
367 1.1 christos ret = ptrace (PTRACE_KILL, child_pid, (PTRACE_TYPE_ARG3) 0,
368 1.1 christos (PTRACE_TYPE_ARG4) 0);
369 1.1 christos if (ret != 0)
370 1.1 christos warning (_("linux_check_ptrace_features: failed to kill child"));
371 1.1 christos my_waitpid (child_pid, &status, 0);
372 1.1 christos }
373 1.1 christos while (WIFSTOPPED (status));
374 1.1 christos }
375 1.1 christos
376 1.1 christos /* Determine if PTRACE_O_TRACESYSGOOD can be used to catch
377 1.1 christos syscalls. */
378 1.1 christos
379 1.1 christos static void
380 1.1 christos linux_test_for_tracesysgood (int child_pid)
381 1.1 christos {
382 1.1 christos int ret;
383 1.1 christos
384 1.1 christos ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,
385 1.1 christos (PTRACE_TYPE_ARG4) PTRACE_O_TRACESYSGOOD);
386 1.1 christos
387 1.1 christos if (ret == 0)
388 1.3 christos supported_ptrace_options |= PTRACE_O_TRACESYSGOOD;
389 1.1 christos }
390 1.1 christos
391 1.1 christos /* Determine if PTRACE_O_TRACEFORK can be used to follow fork
392 1.1 christos events. */
393 1.1 christos
394 1.1 christos static void
395 1.1 christos linux_test_for_tracefork (int child_pid)
396 1.1 christos {
397 1.1 christos int ret, status;
398 1.1 christos long second_pid;
399 1.1 christos
400 1.1 christos /* First, set the PTRACE_O_TRACEFORK option. If this fails, we
401 1.1 christos know for sure that it is not supported. */
402 1.1 christos ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,
403 1.1 christos (PTRACE_TYPE_ARG4) PTRACE_O_TRACEFORK);
404 1.1 christos
405 1.1 christos if (ret != 0)
406 1.1 christos return;
407 1.1 christos
408 1.3 christos /* Check if the target supports PTRACE_O_TRACEVFORKDONE. */
409 1.3 christos ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,
410 1.3 christos (PTRACE_TYPE_ARG4) (PTRACE_O_TRACEFORK
411 1.3 christos | PTRACE_O_TRACEVFORKDONE));
412 1.3 christos if (ret == 0)
413 1.3 christos supported_ptrace_options |= PTRACE_O_TRACEVFORKDONE;
414 1.1 christos
415 1.1 christos /* Setting PTRACE_O_TRACEFORK did not cause an error, however we
416 1.1 christos don't know for sure that the feature is available; old
417 1.1 christos versions of PTRACE_SETOPTIONS ignored unknown options.
418 1.1 christos Therefore, we attach to the child process, use PTRACE_SETOPTIONS
419 1.1 christos to enable fork tracing, and let it fork. If the process exits,
420 1.1 christos we assume that we can't use PTRACE_O_TRACEFORK; if we get the
421 1.1 christos fork notification, and we can extract the new child's PID, then
422 1.1 christos we assume that we can.
423 1.1 christos
424 1.1 christos We do not explicitly check for vfork tracing here. It is
425 1.1 christos assumed that vfork tracing is available whenever fork tracing
426 1.1 christos is available. */
427 1.1 christos ret = ptrace (PTRACE_CONT, child_pid, (PTRACE_TYPE_ARG3) 0,
428 1.1 christos (PTRACE_TYPE_ARG4) 0);
429 1.1 christos if (ret != 0)
430 1.1 christos warning (_("linux_test_for_tracefork: failed to resume child"));
431 1.1 christos
432 1.1 christos ret = my_waitpid (child_pid, &status, 0);
433 1.1 christos
434 1.1 christos /* Check if we received a fork event notification. */
435 1.1 christos if (ret == child_pid && WIFSTOPPED (status)
436 1.1 christos && linux_ptrace_get_extended_event (status) == PTRACE_EVENT_FORK)
437 1.1 christos {
438 1.1 christos /* We did receive a fork event notification. Make sure its PID
439 1.1 christos is reported. */
440 1.1 christos second_pid = 0;
441 1.1 christos ret = ptrace (PTRACE_GETEVENTMSG, child_pid, (PTRACE_TYPE_ARG3) 0,
442 1.1 christos (PTRACE_TYPE_ARG4) &second_pid);
443 1.1 christos if (ret == 0 && second_pid != 0)
444 1.1 christos {
445 1.1 christos int second_status;
446 1.1 christos
447 1.1 christos /* We got the PID from the grandchild, which means fork
448 1.1 christos tracing is supported. */
449 1.3 christos supported_ptrace_options |= PTRACE_O_TRACECLONE;
450 1.3 christos supported_ptrace_options |= (PTRACE_O_TRACEFORK
451 1.3 christos | PTRACE_O_TRACEVFORK
452 1.3 christos | PTRACE_O_TRACEEXEC);
453 1.1 christos
454 1.1 christos /* Do some cleanup and kill the grandchild. */
455 1.1 christos my_waitpid (second_pid, &second_status, 0);
456 1.1 christos ret = ptrace (PTRACE_KILL, second_pid, (PTRACE_TYPE_ARG3) 0,
457 1.1 christos (PTRACE_TYPE_ARG4) 0);
458 1.1 christos if (ret != 0)
459 1.1 christos warning (_("linux_test_for_tracefork: "
460 1.1 christos "failed to kill second child"));
461 1.1 christos my_waitpid (second_pid, &status, 0);
462 1.1 christos }
463 1.1 christos }
464 1.1 christos else
465 1.1 christos warning (_("linux_test_for_tracefork: unexpected result from waitpid "
466 1.1 christos "(%d, status 0x%x)"), ret, status);
467 1.1 christos }
468 1.1 christos
469 1.1 christos /* Determine if PTRACE_O_EXITKILL can be used. */
470 1.1 christos
471 1.1 christos static void
472 1.1 christos linux_test_for_exitkill (int child_pid)
473 1.1 christos {
474 1.1 christos int ret;
475 1.1 christos
476 1.1 christos ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0,
477 1.1 christos (PTRACE_TYPE_ARG4) PTRACE_O_EXITKILL);
478 1.1 christos
479 1.1 christos if (ret == 0)
480 1.3 christos supported_ptrace_options |= PTRACE_O_EXITKILL;
481 1.1 christos }
482 1.1 christos
483 1.1 christos /* Enable reporting of all currently supported ptrace events.
484 1.3 christos OPTIONS is a bit mask of extended features we want enabled,
485 1.3 christos if supported by the kernel. PTRACE_O_TRACECLONE is always
486 1.3 christos enabled, if supported. */
487 1.1 christos
488 1.1 christos void
489 1.3 christos linux_enable_event_reporting (pid_t pid, int options)
490 1.1 christos {
491 1.1 christos /* Check if we have initialized the ptrace features for this
492 1.1 christos target. If not, do it now. */
493 1.3 christos if (supported_ptrace_options == -1)
494 1.1 christos linux_check_ptrace_features ();
495 1.1 christos
496 1.3 christos /* We always want clone events. */
497 1.3 christos options |= PTRACE_O_TRACECLONE;
498 1.3 christos
499 1.3 christos /* Filter out unsupported options. */
500 1.3 christos options &= supported_ptrace_options;
501 1.1 christos
502 1.1 christos /* Set the options. */
503 1.1 christos ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0,
504 1.3 christos (PTRACE_TYPE_ARG4) (uintptr_t) options);
505 1.1 christos }
506 1.1 christos
507 1.1 christos /* Disable reporting of all currently supported ptrace events. */
508 1.1 christos
509 1.1 christos void
510 1.1 christos linux_disable_event_reporting (pid_t pid)
511 1.1 christos {
512 1.1 christos /* Set the options. */
513 1.1 christos ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0, 0);
514 1.1 christos }
515 1.1 christos
516 1.1 christos /* Returns non-zero if PTRACE_OPTIONS is contained within
517 1.3 christos SUPPORTED_PTRACE_OPTIONS, therefore supported. Returns 0
518 1.1 christos otherwise. */
519 1.1 christos
520 1.1 christos static int
521 1.1 christos ptrace_supports_feature (int ptrace_options)
522 1.1 christos {
523 1.3 christos if (supported_ptrace_options == -1)
524 1.1 christos linux_check_ptrace_features ();
525 1.1 christos
526 1.3 christos return ((supported_ptrace_options & ptrace_options) == ptrace_options);
527 1.1 christos }
528 1.1 christos
529 1.1 christos /* Returns non-zero if PTRACE_EVENT_FORK is supported by ptrace,
530 1.1 christos 0 otherwise. Note that if PTRACE_EVENT_FORK is supported so is
531 1.1 christos PTRACE_EVENT_CLONE, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,
532 1.1 christos since they were all added to the kernel at the same time. */
533 1.1 christos
534 1.1 christos int
535 1.1 christos linux_supports_tracefork (void)
536 1.1 christos {
537 1.1 christos return ptrace_supports_feature (PTRACE_O_TRACEFORK);
538 1.1 christos }
539 1.1 christos
540 1.4 christos /* Returns non-zero if PTRACE_EVENT_EXEC is supported by ptrace,
541 1.4 christos 0 otherwise. Note that if PTRACE_EVENT_FORK is supported so is
542 1.4 christos PTRACE_EVENT_CLONE, PTRACE_EVENT_FORK and PTRACE_EVENT_VFORK,
543 1.4 christos since they were all added to the kernel at the same time. */
544 1.4 christos
545 1.4 christos int
546 1.4 christos linux_supports_traceexec (void)
547 1.4 christos {
548 1.4 christos return ptrace_supports_feature (PTRACE_O_TRACEEXEC);
549 1.4 christos }
550 1.4 christos
551 1.1 christos /* Returns non-zero if PTRACE_EVENT_CLONE is supported by ptrace,
552 1.1 christos 0 otherwise. Note that if PTRACE_EVENT_CLONE is supported so is
553 1.1 christos PTRACE_EVENT_FORK, PTRACE_EVENT_EXEC and PTRACE_EVENT_VFORK,
554 1.1 christos since they were all added to the kernel at the same time. */
555 1.1 christos
556 1.1 christos int
557 1.1 christos linux_supports_traceclone (void)
558 1.1 christos {
559 1.1 christos return ptrace_supports_feature (PTRACE_O_TRACECLONE);
560 1.1 christos }
561 1.1 christos
562 1.1 christos /* Returns non-zero if PTRACE_O_TRACEVFORKDONE is supported by
563 1.1 christos ptrace, 0 otherwise. */
564 1.1 christos
565 1.1 christos int
566 1.1 christos linux_supports_tracevforkdone (void)
567 1.1 christos {
568 1.1 christos return ptrace_supports_feature (PTRACE_O_TRACEVFORKDONE);
569 1.1 christos }
570 1.1 christos
571 1.1 christos /* Returns non-zero if PTRACE_O_TRACESYSGOOD is supported by ptrace,
572 1.1 christos 0 otherwise. */
573 1.1 christos
574 1.1 christos int
575 1.1 christos linux_supports_tracesysgood (void)
576 1.1 christos {
577 1.1 christos return ptrace_supports_feature (PTRACE_O_TRACESYSGOOD);
578 1.1 christos }
579 1.1 christos
580 1.1 christos /* Display possible problems on this system. Display them only once per GDB
581 1.1 christos execution. */
582 1.1 christos
583 1.1 christos void
584 1.1 christos linux_ptrace_init_warnings (void)
585 1.1 christos {
586 1.1 christos static int warned = 0;
587 1.1 christos
588 1.1 christos if (warned)
589 1.1 christos return;
590 1.1 christos warned = 1;
591 1.1 christos
592 1.1 christos linux_ptrace_test_ret_to_nx ();
593 1.1 christos }
594 1.1 christos
595 1.1 christos /* Extract extended ptrace event from wait status. */
596 1.1 christos
597 1.1 christos int
598 1.1 christos linux_ptrace_get_extended_event (int wstat)
599 1.1 christos {
600 1.1 christos return (wstat >> 16);
601 1.1 christos }
602 1.1 christos
603 1.1 christos /* Determine whether wait status denotes an extended event. */
604 1.1 christos
605 1.1 christos int
606 1.1 christos linux_is_extended_waitstatus (int wstat)
607 1.1 christos {
608 1.1 christos return (linux_ptrace_get_extended_event (wstat) != 0);
609 1.1 christos }
610 1.3 christos
611 1.3 christos /* Return true if the event in LP may be caused by breakpoint. */
612 1.3 christos
613 1.3 christos int
614 1.3 christos linux_wstatus_maybe_breakpoint (int wstat)
615 1.3 christos {
616 1.3 christos return (WIFSTOPPED (wstat)
617 1.3 christos && (WSTOPSIG (wstat) == SIGTRAP
618 1.3 christos /* SIGILL and SIGSEGV are also treated as traps in case a
619 1.3 christos breakpoint is inserted at the current PC. */
620 1.3 christos || WSTOPSIG (wstat) == SIGILL
621 1.3 christos || WSTOPSIG (wstat) == SIGSEGV));
622 1.3 christos }
623