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