Back to index

glibc  2.9
ptrace.c
Go to the documentation of this file.
00001 /* Copyright (C) 1995-1998,2000,2003,2006 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003 
00004    The GNU C Library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Lesser General Public
00006    License as published by the Free Software Foundation; either
00007    version 2.1 of the License, or (at your option) any later version.
00008 
00009    The GNU C Library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Lesser General Public License for more details.
00013 
00014    You should have received a copy of the GNU Lesser General Public
00015    License along with the GNU C Library; if not, write to the Free
00016    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00017    02111-1307 USA.  */
00018 
00019 #include <errno.h>
00020 #include <sys/types.h>
00021 #include <sys/ptrace.h>
00022 #include <sys/user.h>
00023 #include <stdarg.h>
00024 #include <signal.h>
00025 
00026 #include <sysdep.h>
00027 #include <sys/syscall.h>
00028 #include <bp-checks.h>
00029 
00030 long int
00031 ptrace (enum __ptrace_request request, ...)
00032 {
00033   long int res, ret;
00034   va_list ap;
00035   pid_t pid;
00036   void *addr, *data;
00037 
00038   va_start (ap, request);
00039   pid = va_arg (ap, pid_t);
00040   addr = va_arg (ap, void *);
00041   data = va_arg (ap, void *);
00042   va_end (ap);
00043 
00044   if (request > 0 && request < 4)
00045     data = &ret;
00046 
00047 #if __BOUNDED_POINTERS__
00048   switch (request)
00049     {
00050     case PTRACE_PEEKTEXT:
00051     case PTRACE_PEEKDATA:
00052     case PTRACE_PEEKUSER:
00053     case PTRACE_POKETEXT:
00054     case PTRACE_POKEDATA:
00055     case PTRACE_POKEUSER:
00056       (void) CHECK_1 ((int *) addr);
00057       (void) CHECK_1 ((int *) data);
00058       break;
00059 
00060     case PTRACE_GETREGS:
00061     case PTRACE_SETREGS:
00062 #ifdef __i386__
00063       (void) CHECK_1 ((struct user_regs_struct *) data);
00064 #else
00065       /* We don't know the size of data, so the best we can do is ensure
00066         that `data' is valid for at least one word.  */
00067       (void) CHECK_1 ((int *) data);
00068 #endif
00069       break;
00070 
00071     case PTRACE_GETFPREGS:
00072     case PTRACE_SETFPREGS:
00073 #ifdef __i386__
00074       (void) CHECK_1 ((struct user_fpregs_struct *) data);
00075 #else
00076       /* We don't know the size of data, so the best we can do is ensure
00077         that `data' is valid for at least one word.  */
00078       (void) CHECK_1 ((int *) data);
00079 #endif
00080       break;
00081 
00082     case PTRACE_GETFPXREGS:
00083     case PTRACE_SETFPXREGS:
00084 #ifdef __i386__
00085       (void) CHECK_1 ((struct user_fpxregs_struct *) data);
00086 #else
00087       /* We don't know the size of data, so the best we can do is ensure
00088         that `data' is valid for at least one word.  */
00089       (void) CHECK_1 ((int *) data);
00090 #endif
00091       break;
00092 
00093     case PTRACE_GETSIGINFO:
00094     case PTRACE_SETSIGINFO:
00095       (void) CHECK_1 ((siginfo_t *) data);
00096       break;
00097 
00098     case PTRACE_GETEVENTMSG:
00099       (void) CHECK_1 ((unsigned long *) data);
00100       break;
00101 
00102     case PTRACE_SETOPTIONS:
00103       (void) CHECK_1 ((long *) data);
00104       break;
00105 
00106     case PTRACE_TRACEME:
00107     case PTRACE_CONT:
00108     case PTRACE_KILL:
00109     case PTRACE_SINGLESTEP:
00110     case PTRACE_ATTACH:
00111     case PTRACE_DETACH:
00112     case PTRACE_SYSCALL:
00113       /* Neither `data' nor `addr' needs any checks.  */
00114       break;
00115     };
00116 #endif
00117 
00118   res = INLINE_SYSCALL (ptrace, 4, request, pid,
00119                      __ptrvalue (addr), __ptrvalue (data));
00120   if (res >= 0 && request > 0 && request < 4)
00121     {
00122       __set_errno (0);
00123       return ret;
00124     }
00125 
00126   return res;
00127 }