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