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