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