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