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