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