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