1999-02-19 03:21:36 +03:00
/*
* Copyright ( c ) 1991 , 1992 Paul Kranenburg < pk @ cs . few . eur . nl >
* Copyright ( c ) 1993 Branko Lankester < branko @ hacktic . nl >
* Copyright ( c ) 1993 , 1994 , 1995 , 1996 Rick Sladkey < jrs @ world . std . com >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2005-02-02 07:44:57 +03:00
# ifdef HAVE_CONFIG_H
2012-02-25 05:42:32 +04:00
# include "config.h"
2005-02-02 07:44:57 +03:00
# endif
2003-01-14 12:46:18 +03:00
# ifdef _LARGEFILE64_SOURCE
/* This is the macro everything checks before using foo64 names. */
# ifndef _LFS64_LARGEFILE
# define _LFS64_LARGEFILE 1
# endif
# endif
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
# ifdef MIPS
# include <sgidefs.h>
# endif
# include <features.h>
2012-03-16 15:02:22 +04:00
# ifdef HAVE_STDBOOL_H
# include <stdbool.h>
# endif
# include <stdint.h>
# include <inttypes.h>
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
# include <sys/types.h>
2012-03-16 15:02:22 +04:00
# ifdef STDC_HEADERS
# include <stddef.h>
# endif
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
# include <unistd.h>
# include <stdlib.h>
# include <stdio.h>
# include <ctype.h>
# include <string.h>
2012-03-16 15:02:22 +04:00
# include <errno.h>
# include <signal.h>
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
# include <time.h>
# include <sys/time.h>
# include <sys/syscall.h>
2003-01-14 12:46:18 +03:00
2012-03-15 18:02:49 +04:00
# ifndef HAVE_STRERROR
const char * strerror ( int ) ;
# endif
# ifndef HAVE_STPCPY
/* Some libc have stpcpy, some don't. Sigh...
* Roll our private implementation . . .
*/
# undef stpcpy
# define stpcpy strace_stpcpy
extern char * stpcpy ( char * dst , const char * src ) ;
# endif
# if !defined __GNUC__
# define __attribute__(x) /*nothing*/
# endif
2012-03-21 17:39:22 +04:00
# ifndef offsetof
# define offsetof(type, member) \
( ( ( char * ) & ( ( ( type * ) NULL ) - > member ) ) - ( ( char * ) ( type * ) NULL ) )
# endif
2012-03-15 18:02:49 +04:00
# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
2012-03-23 14:29:01 +04:00
/* Glibc has an efficient macro for sigemptyset
* ( it just does one or two assignments of 0 to internal vector of longs ) .
*/
# if defined(__GLIBC__) && defined(__sigemptyset) && !defined(sigemptyset)
# define sigemptyset __sigemptyset
# endif
Set saner MAX_ARGS (6 or 8) for X86_64 and I386
I noticed that tcp->u_args[MAX_ARGS] array is way larger than
I'd expect: for all arches except HPPA it has 32 (!) elements.
I looked at the code and so far I spotted only one abuser of
this fact: sys_sigreturn. On several arches, it saves sigset_t
into tcp->u_args[1...N] on entry and prints it on exit, a-la
memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t))
The problem here is that in glibc sigset_t is insanely large:
128 bytes, and using sizeof(sigset_t) in memcpy will overrun
&tcp->u_args[1] even with MAX_ARGS == 32:
On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes!
We may already have a bug there!
This commit changes the code to save NSIG / 8 bytes only.
NSIG can't ever be > 256, and in practice is <= 129,
thus NSIG / 8 is <= 16 bytes == 4 32-bit words,
and even MAX_ARGS == 5 should be enough for saving signal masks.
* defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8
for FreeBSD and to 6 for everyone else. Add comment about current
state of needed MAX_ARGS.
* signal.c: Add comment about size of sigset_t.
(sprintsigmask): Reduce static string buffer from 8k to 2k.
(sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes,
not sizeof(sigset_t) bytes.
* linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7.
* linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
/* Configuration section */
1999-02-19 03:21:36 +03:00
# ifndef MAX_QUALS
2012-02-25 05:42:32 +04:00
# if defined(MIPS)
# define MAX_QUALS 7000 /* maximum number of syscalls, signals, etc. */
# else
# define MAX_QUALS 2048 /* maximum number of syscalls, signals, etc. */
# endif
2000-05-01 05:53:59 +04:00
# endif
1999-02-19 03:21:36 +03:00
# ifndef DEFAULT_STRLEN
2011-08-18 14:48:56 +04:00
/* default maximum # of bytes printed in `printstr', change with -s switch */
2012-02-25 05:42:32 +04:00
# define DEFAULT_STRLEN 32
1999-02-19 03:21:36 +03:00
# endif
# ifndef DEFAULT_ACOLUMN
2012-02-25 05:42:32 +04:00
# define DEFAULT_ACOLUMN 40 /* default alignment column for results */
1999-02-19 03:21:36 +03:00
# endif
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
/*
* Maximum number of args to a syscall .
Set saner MAX_ARGS (6 or 8) for X86_64 and I386
I noticed that tcp->u_args[MAX_ARGS] array is way larger than
I'd expect: for all arches except HPPA it has 32 (!) elements.
I looked at the code and so far I spotted only one abuser of
this fact: sys_sigreturn. On several arches, it saves sigset_t
into tcp->u_args[1...N] on entry and prints it on exit, a-la
memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t))
The problem here is that in glibc sigset_t is insanely large:
128 bytes, and using sizeof(sigset_t) in memcpy will overrun
&tcp->u_args[1] even with MAX_ARGS == 32:
On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes!
We may already have a bug there!
This commit changes the code to save NSIG / 8 bytes only.
NSIG can't ever be > 256, and in practice is <= 129,
thus NSIG / 8 is <= 16 bytes == 4 32-bit words,
and even MAX_ARGS == 5 should be enough for saving signal masks.
* defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8
for FreeBSD and to 6 for everyone else. Add comment about current
state of needed MAX_ARGS.
* signal.c: Add comment about size of sigset_t.
(sprintsigmask): Reduce static string buffer from 8k to 2k.
(sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes,
not sizeof(sigset_t) bytes.
* linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7.
* linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
*
2012-02-25 18:19:02 +04:00
* Make sure that all entries in all syscallent . h files have nargs < = MAX_ARGS !
2011-08-23 20:04:25 +04:00
* linux / < ARCH > / syscallent . h : all have nargs < = 6.
Set saner MAX_ARGS (6 or 8) for X86_64 and I386
I noticed that tcp->u_args[MAX_ARGS] array is way larger than
I'd expect: for all arches except HPPA it has 32 (!) elements.
I looked at the code and so far I spotted only one abuser of
this fact: sys_sigreturn. On several arches, it saves sigset_t
into tcp->u_args[1...N] on entry and prints it on exit, a-la
memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t))
The problem here is that in glibc sigset_t is insanely large:
128 bytes, and using sizeof(sigset_t) in memcpy will overrun
&tcp->u_args[1] even with MAX_ARGS == 32:
On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes!
We may already have a bug there!
This commit changes the code to save NSIG / 8 bytes only.
NSIG can't ever be > 256, and in practice is <= 129,
thus NSIG / 8 is <= 16 bytes == 4 32-bit words,
and even MAX_ARGS == 5 should be enough for saving signal masks.
* defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8
for FreeBSD and to 6 for everyone else. Add comment about current
state of needed MAX_ARGS.
* signal.c: Add comment about size of sigset_t.
(sprintsigmask): Reduce static string buffer from 8k to 2k.
(sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes,
not sizeof(sigset_t) bytes.
* linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7.
* linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6.
* linux/i386/syscallent.h: Likewise.
* linux/m68k/syscallent.h: Likewise.
* linux/powerpc/syscallent.h: Likewise.
* linux/s390/syscallent.h: Likewise.
* linux/s390x/syscallent.h: Likewise.
* linux/sh/syscallent.h: Likewise.
* linux/sh64/syscallent.h: Likewise.
* linux/sparc/syscallent.h: Likewise.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
*/
1999-02-19 03:21:36 +03:00
# ifndef MAX_ARGS
2012-02-25 05:42:32 +04:00
# define MAX_ARGS 6
1999-02-19 03:21:36 +03:00
# endif
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
/* default sorting method for call profiling */
1999-02-19 03:21:36 +03:00
# ifndef DEFAULT_SORTBY
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
# define DEFAULT_SORTBY "time"
2012-02-25 05:42:32 +04:00
# endif
# if defined(SPARC) || defined(SPARC64)
# define LINUXSPARC
# endif
# if defined(MIPS) && _MIPS_SIM == _MIPS_SIM_ABI32
# define LINUX_MIPSO32
# endif
# if defined(MIPS) && _MIPS_SIM == _MIPS_SIM_NABI32
# define LINUX_MIPSN32
# define LINUX_MIPS64
# endif
# if defined(MIPS) && _MIPS_SIM == _MIPS_SIM_ABI64
# define LINUX_MIPSN64
# define LINUX_MIPS64
# endif
# if (defined(LINUXSPARC) || defined(X86_64) || defined(ARM) || defined(AVR32)) && defined(__GLIBC__)
# include <sys / ptrace.h>
# else
1999-02-19 03:21:36 +03:00
/* Work around awkward prototype in ptrace.h. */
2012-02-25 05:42:32 +04:00
# define ptrace xptrace
# include <sys / ptrace.h>
# undef ptrace
# ifdef POWERPC
# define __KERNEL__
# include <asm / ptrace.h>
# undef __KERNEL__
2011-08-26 21:25:09 +04:00
# endif
2012-02-25 05:42:32 +04:00
extern long ptrace ( int , int , char * , long ) ;
# endif
1999-02-19 03:21:36 +03:00
1999-04-19 02:50:50 +04:00
# if !defined(__GLIBC__)
2012-02-25 05:42:32 +04:00
# define PTRACE_PEEKUSER PTRACE_PEEKUSR
# define PTRACE_POKEUSER PTRACE_POKEUSR
1999-02-19 03:21:36 +03:00
# endif
Add x32 support to strace
X32 support is added to Linux kernel 3.4. In a nutshell, x32 is x86-64 with
32bit pointers. At system call level, x32 is also identical to x86-64,
as shown by many changes like "defined(X86_64) || defined(X32)". The
main differerence bewteen x32 and x86-64 is off_t in x32 is long long
instead of long.
This patch adds x32 support to strace. Tested on Linux/x32.
* configure.ac: Support X32.
* defs.h: Set SUPPORTED_PERSONALITIES to 3 for X86_64,
Set PERSONALITY2_WORDSIZE to 4 for X86_64.
Add tcb::ext_arg for X32.
* file.c (stat): New for X32.
(sys_lseek): Use 64-bit version for X32.
(printstat64): Check current_personality != 1 for X86_64.
* ipc.c (indirect_ipccall): Check current_personality == 1
for X86_64.
* mem.c (sys_mmap64): Also use tcp->u_arg for X32. Print NULL
for zero address. Call printllval for offset for X32.
* pathtrace.c (pathtrace_match): Don't check sys_old_mmap for
X32.
* process.c (ARG_FLAGS): Defined for X32.
(ARG_STACK): Likewise.
(ARG_PTID): Likewise.
(change_syscall): Handle X32.
(struct_user_offsets): Support X32.
(sys_arch_prctl): Likewise.
* signal.c: Include <asm/sigcontext.h> for X32.
(SA_RESTORER): Also define for X32.
* syscall.c (update_personality): Support X32 for X86_64.
(is_restart_error): Likewise.
(syscall_fixup_on_sysenter): Likewise.
(get_syscall_args): Likewise.
(get_syscall_result): Likewise.
(get_error): Likewise.
(__X32_SYSCALL_BIT): Define if not defined.
(__X32_SYSCALL_MASK): Likewise.
(get_scno): Check DS register value for X32. Use
__X32_SYSCALL_MASK on X32 system calls.
* util.c (printllval): Use ext_arg for X32.
(printcall): Support X32.
(change_syscall): Likewise.
(arg0_offset): Likewise.
(arg1_offset): Likewise.
* Makefile.am (EXTRA_DIST): Add linux/x32/errnoent.h,
linux/x32/ioctlent.h.in, linux/x32/signalent.h,
linux/x32/syscallent.h, linux/x86_64/errnoent2.h,
linux/x86_64/ioctlent2.h, linux/x86_64/signalent2.h and
linux/x86_64/syscallent2.h.
* linux/x32/errnoent.h: New.
* linux/x32/ioctlent.h.in: Likewise.
* linux/x32/signalent.h: Likewise.
* linux/x32/syscallent.h: Likewise.
* linux/x86_64/errnoent2.h: Likewise.
* linux/x86_64/ioctlent2.h: Likewise.
* linux/x86_64/signalent2.h: Likewise.
* linux/x86_64/syscallent2.h: Likewise.
Signed-off-by: H.J. Lu <hongjiu.lu@intel.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-04-16 15:00:01 +04:00
# if defined(X86_64) || defined(X32) || defined(I386)
2011-08-30 20:53:49 +04:00
/* For struct pt_regs. x86 strace uses PTRACE_GETREGS.
* PTRACE_GETREGS returns registers in the layout of this struct .
*/
2012-02-25 05:42:32 +04:00
# include <asm / ptrace.h>
2011-08-30 20:53:49 +04:00
# endif
1999-02-19 03:21:36 +03:00
# ifdef ALPHA
2012-02-25 05:42:32 +04:00
# define REG_R0 0
# define REG_A0 16
# define REG_A3 19
# define REG_FP 30
# define REG_PC 64
1999-02-19 03:21:36 +03:00
# endif /* ALPHA */
1999-11-01 00:15:38 +03:00
# ifdef MIPS
2012-02-25 05:42:32 +04:00
# define REG_V0 2
# define REG_A0 4
# define REG_A3 7
# define REG_SP 29
# define REG_EPC 64
1999-11-01 00:15:38 +03:00
# endif /* MIPS */
2001-03-27 16:17:16 +04:00
# ifdef HPPA
2012-02-25 05:42:32 +04:00
# define PT_GR20 (20*4)
# define PT_GR26 (26*4)
# define PT_GR28 (28*4)
# define PT_IAOQ0 (106*4)
# define PT_IAOQ1 (107*4)
2001-03-27 16:17:16 +04:00
# endif /* HPPA */
2003-06-27 02:40:42 +04:00
# ifdef SH64
/* SH64 Linux - this code assumes the following kernel API for system calls:
2003-06-02 23:18:58 +04:00
PC Offset 0
System Call Offset 16 ( actually , ( syscall no . ) | ( 0x1 n < < 16 ) ,
where n = no . of parameters .
Other regs Offset 24 +
On entry : R2 - 7 = parameters 1 - 6 ( as many as necessary )
On return : R9 = result . */
/* Offset for peeks of registers */
2012-02-25 05:42:32 +04:00
# define REG_OFFSET (24)
# define REG_GENERAL(x) (8*(x)+REG_OFFSET)
# define REG_PC (0*8)
# define REG_SYSCALL (2*8)
2003-06-27 02:40:42 +04:00
# endif /* SH64 */
1999-02-19 03:21:36 +03:00
# define SUPPORTED_PERSONALITIES 1
# define DEFAULT_PERSONALITY 0
# ifdef LINUXSPARC
sparc/linux: Rewrite to use asm/ptrace.h
The current sparc/linux code uses asm/reg.h, but recent Linux kernels
dropped that header completely. So switch over to the ptrace headers
as those should stick around indefinitely as part of the ABI.
* defs.h [LINUXSPARC] (U_REG_G1, U_REG_O0, U_REG_O1): Define.
* process.c: Drop asm/regs.h include.
[SPARC || SPARC64] (change_syscall): Change struct regs to struct pt_regs.
* signal.c: Drop asm/regs.h include.
(m_siginfo_t): Unify [SPARC || SPARC64] and [MIPS].
[SPARC || SPARC64] (sys_sigreturn): Change struct regs to struct pt_regs.
* syscall.c: Drop asm/regs.h include.
[SPARC || SPARC64] (internal_syscall, get_scno, get_error, force_result,
syscall_enter): Change struct regs to struct pt_regs.
* util.c: Drop asm/regs.h include.
(_hack_syscall5, _ptrace): Delete.
[SPARC || SPARC64] (getpc, printcall, arg_setup_state): Change
struct regs to struct pt_regs.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2009-10-12 19:05:14 +04:00
/* Indexes into the pt_regs.u_reg[] array -- UREG_XX from kernel are all off
* by 1 and use Ix instead of Ox . These work for both 32 and 64 bit Linux . */
2012-02-25 05:42:32 +04:00
# define U_REG_G1 0
# define U_REG_O0 7
# define U_REG_O1 8
# define PERSONALITY0_WORDSIZE 4
# define PERSONALITY1_WORDSIZE 4
# undef SUPPORTED_PERSONALITIES
# if defined(SPARC64)
# include <asm / psrcompat.h>
# define SUPPORTED_PERSONALITIES 3
# define PERSONALITY2_WORDSIZE 8
# else
# include <asm / psr.h>
# define SUPPORTED_PERSONALITIES 2
# endif /* SPARC64 */
1999-02-19 03:21:36 +03:00
# endif /* LINUXSPARC */
2002-09-23 19:41:01 +04:00
# ifdef X86_64
2012-02-25 05:42:32 +04:00
# undef SUPPORTED_PERSONALITIES
Add x32 support to strace
X32 support is added to Linux kernel 3.4. In a nutshell, x32 is x86-64 with
32bit pointers. At system call level, x32 is also identical to x86-64,
as shown by many changes like "defined(X86_64) || defined(X32)". The
main differerence bewteen x32 and x86-64 is off_t in x32 is long long
instead of long.
This patch adds x32 support to strace. Tested on Linux/x32.
* configure.ac: Support X32.
* defs.h: Set SUPPORTED_PERSONALITIES to 3 for X86_64,
Set PERSONALITY2_WORDSIZE to 4 for X86_64.
Add tcb::ext_arg for X32.
* file.c (stat): New for X32.
(sys_lseek): Use 64-bit version for X32.
(printstat64): Check current_personality != 1 for X86_64.
* ipc.c (indirect_ipccall): Check current_personality == 1
for X86_64.
* mem.c (sys_mmap64): Also use tcp->u_arg for X32. Print NULL
for zero address. Call printllval for offset for X32.
* pathtrace.c (pathtrace_match): Don't check sys_old_mmap for
X32.
* process.c (ARG_FLAGS): Defined for X32.
(ARG_STACK): Likewise.
(ARG_PTID): Likewise.
(change_syscall): Handle X32.
(struct_user_offsets): Support X32.
(sys_arch_prctl): Likewise.
* signal.c: Include <asm/sigcontext.h> for X32.
(SA_RESTORER): Also define for X32.
* syscall.c (update_personality): Support X32 for X86_64.
(is_restart_error): Likewise.
(syscall_fixup_on_sysenter): Likewise.
(get_syscall_args): Likewise.
(get_syscall_result): Likewise.
(get_error): Likewise.
(__X32_SYSCALL_BIT): Define if not defined.
(__X32_SYSCALL_MASK): Likewise.
(get_scno): Check DS register value for X32. Use
__X32_SYSCALL_MASK on X32 system calls.
* util.c (printllval): Use ext_arg for X32.
(printcall): Support X32.
(change_syscall): Likewise.
(arg0_offset): Likewise.
(arg1_offset): Likewise.
* Makefile.am (EXTRA_DIST): Add linux/x32/errnoent.h,
linux/x32/ioctlent.h.in, linux/x32/signalent.h,
linux/x32/syscallent.h, linux/x86_64/errnoent2.h,
linux/x86_64/ioctlent2.h, linux/x86_64/signalent2.h and
linux/x86_64/syscallent2.h.
* linux/x32/errnoent.h: New.
* linux/x32/ioctlent.h.in: Likewise.
* linux/x32/signalent.h: Likewise.
* linux/x32/syscallent.h: Likewise.
* linux/x86_64/errnoent2.h: Likewise.
* linux/x86_64/ioctlent2.h: Likewise.
* linux/x86_64/signalent2.h: Likewise.
* linux/x86_64/syscallent2.h: Likewise.
Signed-off-by: H.J. Lu <hongjiu.lu@intel.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-04-16 15:00:01 +04:00
# define SUPPORTED_PERSONALITIES 3
2012-02-25 05:42:32 +04:00
# define PERSONALITY0_WORDSIZE 8
# define PERSONALITY1_WORDSIZE 4
Add x32 support to strace
X32 support is added to Linux kernel 3.4. In a nutshell, x32 is x86-64 with
32bit pointers. At system call level, x32 is also identical to x86-64,
as shown by many changes like "defined(X86_64) || defined(X32)". The
main differerence bewteen x32 and x86-64 is off_t in x32 is long long
instead of long.
This patch adds x32 support to strace. Tested on Linux/x32.
* configure.ac: Support X32.
* defs.h: Set SUPPORTED_PERSONALITIES to 3 for X86_64,
Set PERSONALITY2_WORDSIZE to 4 for X86_64.
Add tcb::ext_arg for X32.
* file.c (stat): New for X32.
(sys_lseek): Use 64-bit version for X32.
(printstat64): Check current_personality != 1 for X86_64.
* ipc.c (indirect_ipccall): Check current_personality == 1
for X86_64.
* mem.c (sys_mmap64): Also use tcp->u_arg for X32. Print NULL
for zero address. Call printllval for offset for X32.
* pathtrace.c (pathtrace_match): Don't check sys_old_mmap for
X32.
* process.c (ARG_FLAGS): Defined for X32.
(ARG_STACK): Likewise.
(ARG_PTID): Likewise.
(change_syscall): Handle X32.
(struct_user_offsets): Support X32.
(sys_arch_prctl): Likewise.
* signal.c: Include <asm/sigcontext.h> for X32.
(SA_RESTORER): Also define for X32.
* syscall.c (update_personality): Support X32 for X86_64.
(is_restart_error): Likewise.
(syscall_fixup_on_sysenter): Likewise.
(get_syscall_args): Likewise.
(get_syscall_result): Likewise.
(get_error): Likewise.
(__X32_SYSCALL_BIT): Define if not defined.
(__X32_SYSCALL_MASK): Likewise.
(get_scno): Check DS register value for X32. Use
__X32_SYSCALL_MASK on X32 system calls.
* util.c (printllval): Use ext_arg for X32.
(printcall): Support X32.
(change_syscall): Likewise.
(arg0_offset): Likewise.
(arg1_offset): Likewise.
* Makefile.am (EXTRA_DIST): Add linux/x32/errnoent.h,
linux/x32/ioctlent.h.in, linux/x32/signalent.h,
linux/x32/syscallent.h, linux/x86_64/errnoent2.h,
linux/x86_64/ioctlent2.h, linux/x86_64/signalent2.h and
linux/x86_64/syscallent2.h.
* linux/x32/errnoent.h: New.
* linux/x32/ioctlent.h.in: Likewise.
* linux/x32/signalent.h: Likewise.
* linux/x32/syscallent.h: Likewise.
* linux/x86_64/errnoent2.h: Likewise.
* linux/x86_64/ioctlent2.h: Likewise.
* linux/x86_64/signalent2.h: Likewise.
* linux/x86_64/syscallent2.h: Likewise.
Signed-off-by: H.J. Lu <hongjiu.lu@intel.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-04-16 15:00:01 +04:00
# define PERSONALITY2_WORDSIZE 4
2002-12-18 07:16:10 +03:00
# endif
2008-05-20 05:35:55 +04:00
# ifdef ARM
2012-02-25 05:42:32 +04:00
# undef SUPPORTED_PERSONALITIES
# define SUPPORTED_PERSONALITIES 2
# define PERSONALITY0_WORDSIZE 4
# define PERSONALITY1_WORDSIZE 4
2008-05-20 05:35:55 +04:00
# endif
2010-07-12 23:39:57 +04:00
# ifdef POWERPC64
2012-02-25 05:42:32 +04:00
# undef SUPPORTED_PERSONALITIES
# define SUPPORTED_PERSONALITIES 2
# define PERSONALITY0_WORDSIZE 8
# define PERSONALITY1_WORDSIZE 4
2010-07-12 23:39:57 +04:00
# endif
2012-03-19 12:36:42 +04:00
# ifndef PERSONALITY0_WORDSIZE
# define PERSONALITY0_WORDSIZE sizeof(long)
# endif
2012-02-25 05:42:32 +04:00
# if !HAVE_DECL_PTRACE_SETOPTIONS
# define PTRACE_SETOPTIONS 0x4200
# endif
# if !HAVE_DECL_PTRACE_GETEVENTMSG
# define PTRACE_GETEVENTMSG 0x4201
# endif
# if !HAVE_DECL_PTRACE_GETSIGINFO
# define PTRACE_GETSIGINFO 0x4202
# endif
2011-07-20 02:13:11 +04:00
2012-02-25 05:42:32 +04:00
# if !HAVE_DECL_PTRACE_O_TRACESYSGOOD
# define PTRACE_O_TRACESYSGOOD 0x00000001
# endif
# if !HAVE_DECL_PTRACE_O_TRACEFORK
# define PTRACE_O_TRACEFORK 0x00000002
# endif
# if !HAVE_DECL_PTRACE_O_TRACEVFORK
# define PTRACE_O_TRACEVFORK 0x00000004
# endif
# if !HAVE_DECL_PTRACE_O_TRACECLONE
# define PTRACE_O_TRACECLONE 0x00000008
# endif
# if !HAVE_DECL_PTRACE_O_TRACEEXEC
# define PTRACE_O_TRACEEXEC 0x00000010
# endif
# if !HAVE_DECL_PTRACE_O_TRACEEXIT
# define PTRACE_O_TRACEEXIT 0x00000040
# endif
2010-11-12 12:25:19 +03:00
2012-02-25 05:42:32 +04:00
# if !HAVE_DECL_PTRACE_EVENT_FORK
# define PTRACE_EVENT_FORK 1
# endif
# if !HAVE_DECL_PTRACE_EVENT_VFORK
# define PTRACE_EVENT_VFORK 2
# endif
# if !HAVE_DECL_PTRACE_EVENT_CLONE
# define PTRACE_EVENT_CLONE 3
# endif
# if !HAVE_DECL_PTRACE_EVENT_EXEC
# define PTRACE_EVENT_EXEC 4
# endif
# if !HAVE_DECL_PTRACE_EVENT_VFORK_DONE
# define PTRACE_EVENT_VFORK_DONE 5
# endif
# if !HAVE_DECL_PTRACE_EVENT_EXIT
# define PTRACE_EVENT_EXIT 6
# endif
2012-01-29 05:01:44 +04:00
/* Experimental code using PTRACE_SEIZE can be enabled here: */
//# define USE_SEIZE 1
2012-02-25 05:42:32 +04:00
# ifdef USE_SEIZE
# undef PTRACE_SEIZE
# define PTRACE_SEIZE 0x4206
# undef PTRACE_INTERRUPT
# define PTRACE_INTERRUPT 0x4207
# undef PTRACE_LISTEN
# define PTRACE_LISTEN 0x4208
# undef PTRACE_SEIZE_DEVEL
# define PTRACE_SEIZE_DEVEL 0x80000000
# undef PTRACE_EVENT_STOP
# define PTRACE_EVENT_STOP 7
# define PTRACE_EVENT_STOP1 128
# endif
2012-01-29 05:01:44 +04:00
2012-02-25 05:42:32 +04:00
# if defined(I386)
2012-01-17 22:37:13 +04:00
extern struct pt_regs i386_regs ;
2012-02-25 05:42:32 +04:00
# endif
2012-03-15 18:02:49 +04:00
# if defined(IA64)
extern long ia32 ;
# endif
Display mask on enter to sigreturn, not on exit
sys_sigreturn() performs ugly manipulations in order to show
signal mask which is restored by this syscall: on syscall entry,
fetches it from the stack, saves it in tcp->u_arg[]
(where it used to overflow this array - fixed sometime ago),
then retrieves the mask and displays it on syscall exit.
Apparently, the motivation is to make it slightly more obvious
to user that signal mask is restored only when this syscall returns.
IMO, this hardly justifies the necessary hacks. It is much easier
to display the mask at the point when we fetch it - on syscall entry.
While at it, I made it so that we do display returned value/errno.
I see no point in hiding it and showing uninformative "= ?" instead.
Example of pause() being interrupted by ALRM which has installed handler
which re-arms ALRM:
Before the patch:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() = ? (mask now [INT])
After:
rt_sigsuspend([INT]) = ? ERESTARTNOHAND (To be restarted)
--- {si_signo=SIGALRM, si_code=SI_KERNEL} (Alarm clock) ---
alarm(1) = 0
sigreturn() (mask [INT]) = -1 EINTR (Interrupted system call)
* defs.h: Declare struct pt_regs i386_regs and struct pt_regs x86_64_regs.
* syscall.c: Remove "static" keywork from these structures' definitions.
* signal.c (sys_sigreturn): Display mask on enter, not on exit.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2012-01-10 19:40:35 +04:00
1999-02-19 03:21:36 +03:00
/* Trace Control Block */
struct tcb {
2011-08-20 03:39:05 +04:00
int flags ; /* See below for TCB_ values */
1999-02-19 03:21:36 +03:00
int pid ; /* Process Id of this entry */
2011-08-20 15:44:56 +04:00
int u_nargs ; /* System call argument count */
2011-08-25 02:25:08 +04:00
int u_error ; /* Error code */
long scno ; /* System call number */
1999-02-19 03:21:36 +03:00
long u_arg [ MAX_ARGS ] ; /* System call arguments */
Add x32 support to strace
X32 support is added to Linux kernel 3.4. In a nutshell, x32 is x86-64 with
32bit pointers. At system call level, x32 is also identical to x86-64,
as shown by many changes like "defined(X86_64) || defined(X32)". The
main differerence bewteen x32 and x86-64 is off_t in x32 is long long
instead of long.
This patch adds x32 support to strace. Tested on Linux/x32.
* configure.ac: Support X32.
* defs.h: Set SUPPORTED_PERSONALITIES to 3 for X86_64,
Set PERSONALITY2_WORDSIZE to 4 for X86_64.
Add tcb::ext_arg for X32.
* file.c (stat): New for X32.
(sys_lseek): Use 64-bit version for X32.
(printstat64): Check current_personality != 1 for X86_64.
* ipc.c (indirect_ipccall): Check current_personality == 1
for X86_64.
* mem.c (sys_mmap64): Also use tcp->u_arg for X32. Print NULL
for zero address. Call printllval for offset for X32.
* pathtrace.c (pathtrace_match): Don't check sys_old_mmap for
X32.
* process.c (ARG_FLAGS): Defined for X32.
(ARG_STACK): Likewise.
(ARG_PTID): Likewise.
(change_syscall): Handle X32.
(struct_user_offsets): Support X32.
(sys_arch_prctl): Likewise.
* signal.c: Include <asm/sigcontext.h> for X32.
(SA_RESTORER): Also define for X32.
* syscall.c (update_personality): Support X32 for X86_64.
(is_restart_error): Likewise.
(syscall_fixup_on_sysenter): Likewise.
(get_syscall_args): Likewise.
(get_syscall_result): Likewise.
(get_error): Likewise.
(__X32_SYSCALL_BIT): Define if not defined.
(__X32_SYSCALL_MASK): Likewise.
(get_scno): Check DS register value for X32. Use
__X32_SYSCALL_MASK on X32 system calls.
* util.c (printllval): Use ext_arg for X32.
(printcall): Support X32.
(change_syscall): Likewise.
(arg0_offset): Likewise.
(arg1_offset): Likewise.
* Makefile.am (EXTRA_DIST): Add linux/x32/errnoent.h,
linux/x32/ioctlent.h.in, linux/x32/signalent.h,
linux/x32/syscallent.h, linux/x86_64/errnoent2.h,
linux/x86_64/ioctlent2.h, linux/x86_64/signalent2.h and
linux/x86_64/syscallent2.h.
* linux/x32/errnoent.h: New.
* linux/x32/ioctlent.h.in: Likewise.
* linux/x32/signalent.h: Likewise.
* linux/x32/syscallent.h: Likewise.
* linux/x86_64/errnoent2.h: Likewise.
* linux/x86_64/ioctlent2.h: Likewise.
* linux/x86_64/signalent2.h: Likewise.
* linux/x86_64/syscallent2.h: Likewise.
Signed-off-by: H.J. Lu <hongjiu.lu@intel.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-04-16 15:00:01 +04:00
# if defined(LINUX_MIPSN32) || defined(X32)
2008-05-20 05:11:56 +04:00
long long ext_arg [ MAX_ARGS ] ; /* System call arguments */
# endif
2012-04-16 14:16:45 +04:00
long u_rval ; /* return value */
# if defined(LINUX_MIPSN32) || defined(X32)
long long u_lrval ; /* long long return value */
# endif
2011-12-23 04:50:49 +04:00
# if SUPPORTED_PERSONALITIES > 1
int currpers ; /* Personality at the time of scno update */
# endif
2009-10-27 18:27:13 +03:00
int curcol ; /* Output column for this process */
2011-08-25 02:25:08 +04:00
FILE * outf ; /* Output file for this process */
2000-06-27 21:33:32 +04:00
const char * auxstr ; /* Auxiliary info from syscall (see RVAL_STR) */
1999-02-19 03:21:36 +03:00
struct timeval stime ; /* System time usage as of last process wait */
struct timeval dtime ; /* Delta for system time usage */
struct timeval etime ; /* Syscall entry time */
2012-03-17 15:41:27 +04:00
/* Support for tracing forked processes: */
long inst [ 2 ] ; /* Saved clone args (badly named) */
1999-02-19 03:21:36 +03:00
} ;
/* TCB flags */
2011-09-05 16:05:46 +04:00
# define TCB_INUSE 00001 /* This table entry is in use */
2012-03-15 16:02:31 +04:00
/* We have attached to this process, but did not see it stopping yet */
2011-09-05 16:05:46 +04:00
# define TCB_STARTUP 00002
# define TCB_IGNORE_ONE_SIGSTOP 00004 /* Next SIGSTOP is to be ignored */
2011-08-21 20:03:23 +04:00
/*
* Are we in system call entry or in syscall exit ?
*
* This bit is set after all syscall entry processing is done .
* Therefore , this bit will be set when next ptrace stop occurs ,
* which should be syscall exit stop . Other stops which are possible
* directly after syscall entry ( death , ptrace event stop )
* are simpler and handled without calling trace_syscall ( ) , therefore
* the places where TCB_INSYSCALL can be set but we aren ' t in syscall stop
* are limited to trace ( ) , this condition is never observed in trace_syscall ( )
* and below .
* The bit is cleared after all syscall exit processing is done .
* User - generated SIGTRAPs and post - execve SIGTRAP make it necessary
* to be very careful and NOT set TCB_INSYSCALL bit when they are encountered .
* TCB_WAITEXECVE bit is used for this purpose ( see below ) .
*
* Use entering ( tcp ) / exiting ( tcp ) to check this bit to make code more readable .
*/
2011-09-05 16:05:46 +04:00
# define TCB_INSYSCALL 00010
2012-03-09 18:15:24 +04:00
# define TCB_ATTACHED 00020 /* It is attached already */
/* Are we PROG from "strace PROG [ARGS]" invocation? */
2012-03-21 17:39:22 +04:00
# define TCB_STRACE_CHILD 0040
1999-02-19 03:21:36 +03:00
# define TCB_BPTSET 00100 /* "Breakpoint" set after fork(2) */
2012-03-21 17:39:22 +04:00
# define TCB_REPRINT 00200 /* We should reprint this syscall on exit */
# define TCB_FILTERED 00400 /* This system call has been filtered out */
2009-06-03 03:49:22 +04:00
/* x86 does not need TCB_WAITEXECVE.
2011-08-21 20:03:23 +04:00
* It can detect SIGTRAP by looking at eax / rax .
2011-08-25 12:40:14 +04:00
* See " not a syscall entry (eax = %ld) \n " message
* in syscall_fixup_on_sysenter ( ) .
2009-01-02 21:02:45 +03:00
*/
2012-02-25 05:42:32 +04:00
# if defined(ALPHA) || defined(AVR32) || defined(SPARC) || defined(SPARC64) \
2009-03-06 03:33:24 +03:00
| | defined ( POWERPC ) | | defined ( IA64 ) | | defined ( HPPA ) \
| | defined ( SH ) | | defined ( SH64 ) | | defined ( S390 ) | | defined ( S390X ) \
2009-12-28 18:00:15 +03:00
| | defined ( ARM ) | | defined ( MIPS ) | | defined ( BFIN ) | | defined ( TILE )
2011-08-21 20:03:23 +04:00
/* This tracee has entered into execve syscall. Expect post-execve SIGTRAP
* to happen . ( When it is detected , tracee is continued and this bit is cleared . )
*/
2012-03-21 17:39:22 +04:00
# define TCB_WAITEXECVE 01000
2012-02-25 05:42:32 +04:00
# endif
1999-02-19 03:21:36 +03:00
/* qualifier flags */
# define QUAL_TRACE 0001 /* this system call should be traced */
# define QUAL_ABBREV 0002 /* abbreviate the structures of this syscall */
# define QUAL_VERBOSE 0004 /* decode the structures of this syscall */
# define QUAL_RAW 0010 /* print all args in hex for this syscall */
# define QUAL_SIGNAL 0020 /* report events with this signal */
# define QUAL_FAULT 0040 /* report events with this fault */
# define QUAL_READ 0100 /* dump data read on this file descriptor */
# define QUAL_WRITE 0200 /* dump data written to this file descriptor */
# define entering(tcp) (!((tcp)->flags & TCB_INSYSCALL))
# define exiting(tcp) ((tcp)->flags & TCB_INSYSCALL)
# define syserror(tcp) ((tcp)->u_error != 0)
# define verbose(tcp) (qual_flags[(tcp)->scno] & QUAL_VERBOSE)
# define abbrev(tcp) (qual_flags[(tcp)->scno] & QUAL_ABBREV)
2011-04-08 00:25:40 +04:00
# define filtered(tcp) ((tcp)->flags & TCB_FILTERED)
1999-02-19 03:21:36 +03:00
struct xlat {
int val ;
2010-09-07 02:08:24 +04:00
const char * str ;
1999-02-19 03:21:36 +03:00
} ;
2009-01-13 21:30:55 +03:00
extern const struct xlat open_mode_flags [ ] ;
extern const struct xlat addrfams [ ] ;
extern const struct xlat struct_user_offsets [ ] ;
extern const struct xlat open_access_modes [ ] ;
1999-02-19 03:21:36 +03:00
/* Format of syscall return values */
# define RVAL_DECIMAL 000 /* decimal format */
# define RVAL_HEX 001 /* hex format */
# define RVAL_OCTAL 002 /* octal format */
# define RVAL_UDECIMAL 003 /* unsigned decimal format */
2012-04-16 14:16:45 +04:00
# if defined(LINUX_MIPSN32) || defined(X32)
# if 0 /* unused so far */
# define RVAL_LDECIMAL 004 /* long decimal format */
# define RVAL_LHEX 005 /* long hex format */
# define RVAL_LOCTAL 006 /* long octal format */
# endif
# define RVAL_LUDECIMAL 007 /* long unsigned decimal format */
# endif
# define RVAL_MASK 007 /* mask for these values */
1999-02-19 03:21:36 +03:00
# define RVAL_STR 010 /* Print `auxstr' field after return val */
# define RVAL_NONE 020 /* Print nothing */
# define TRACE_FILE 001 /* Trace file-related syscalls. */
# define TRACE_IPC 002 /* Trace IPC-related syscalls. */
# define TRACE_NETWORK 004 /* Trace network-related syscalls. */
# define TRACE_PROCESS 010 /* Trace process-related syscalls. */
# define TRACE_SIGNAL 020 /* Trace signal-related syscalls. */
2005-07-05 07:25:35 +04:00
# define TRACE_DESC 040 /* Trace file descriptor-related syscalls. */
2011-02-05 04:07:08 +03:00
# define SYSCALL_NEVER_FAILS 0100 /* Syscall is always successful. */
1999-02-19 03:21:36 +03:00
2010-03-28 23:24:54 +04:00
typedef enum {
CFLAG_NONE = 0 ,
CFLAG_ONLY_STATS ,
CFLAG_BOTH
} cflag_t ;
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
extern cflag_t cflag ;
2006-01-12 12:50:49 +03:00
extern int * qual_flags ;
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
extern bool debug_flag ;
extern bool Tflag ;
extern bool qflag ;
extern bool not_failing_only ;
extern bool show_fd_path ;
extern bool tracing_paths ;
extern unsigned int xflag ;
extern unsigned int followfork ;
2011-06-21 16:34:10 +04:00
extern unsigned int ptrace_setoptions ;
Tidy up order of includes; make bool variables explicit.
Bool variables are more compact in data and (on x86) on code too:
text data bss dec hex filename
237950 676 19044 257670 3ee86 strace.before
237838 676 19012 257526 3edf6 strace
* defs.h: Group library includes at the top of the file.
Rename dtime to Tflag, debug to debug_flag.
Change debug_flag,Tflag,qflag,not_failing_only,show_fd_path,tracing_paths
variable declarations from int to bool.
* strace.c: Change corresponding definitions. Do the same for static
variables iflag,rflag,print_pid_pfx.
Rename dtime to Tflag, debug to debug_flag.
* syscall.c: Rename dtime to Tflag, debug to debug_flag.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2012-03-15 15:49:52 +04:00
extern unsigned int max_strlen ;
2006-12-13 20:10:11 +03:00
enum bitness_t { BITNESS_CURRENT = 0 , BITNESS_32 } ;
2011-05-27 16:36:01 +04:00
void error_msg ( const char * fmt , . . . ) __attribute__ ( ( format ( printf , 1 , 2 ) ) ) ;
void perror_msg ( const char * fmt , . . . ) __attribute__ ( ( format ( printf , 1 , 2 ) ) ) ;
void error_msg_and_die ( const char * fmt , . . . ) __attribute__ ( ( noreturn , format ( printf , 1 , 2 ) ) ) ;
void perror_msg_and_die ( const char * fmt , . . . ) __attribute__ ( ( noreturn , format ( printf , 1 , 2 ) ) ) ;
2011-08-31 16:00:02 +04:00
void die_out_of_memory ( void ) __attribute__ ( ( noreturn ) ) ;
2011-05-27 16:36:01 +04:00
2012-04-16 20:22:19 +04:00
# ifdef USE_CUSTOM_PRINTF
/*
* Speed - optimized vfprintf implementation .
* See comment in vsprintf . c for allowed formats .
* Short version : % h [ h ] u , % zu , % tu are not allowed , use % [ l [ l ] ] u .
*
* It results in strace using about 5 % less CPU in user space
* ( compared to glibc version ) .
* But strace spends a lot of time in kernel space ,
* so overall it does not appear to be a significant win .
* Thus disabled by default .
*/
int strace_vfprintf ( FILE * fp , const char * fmt , va_list args ) ;
# else
# define strace_vfprintf vfprintf
# endif
2010-09-07 02:08:24 +04:00
extern void set_sortby ( const char * ) ;
2009-10-27 18:56:43 +03:00
extern void set_overhead ( int ) ;
2010-09-07 02:08:24 +04:00
extern void qualify ( const char * ) ;
2009-10-27 18:56:43 +03:00
extern int trace_syscall ( struct tcb * ) ;
2011-08-21 19:47:40 +04:00
extern void count_syscall ( struct tcb * , struct timeval * ) ;
2012-03-23 14:26:36 +04:00
extern void call_summary ( FILE * ) ;
extern int umoven ( struct tcb * , long , int , char * ) ;
# define umove(pid, addr, objp) \
umoven ( ( pid ) , ( addr ) , sizeof ( * ( objp ) ) , ( char * ) ( objp ) )
extern int umovestr ( struct tcb * , long , int , char * ) ;
extern int upeek ( struct tcb * , long , long * ) ;
# if defined(SPARC) || defined(SPARC64) || defined(IA64) || defined(SH)
extern long getrval2 ( struct tcb * ) ;
# endif
/*
* On Linux , " setbpt " is a misnomer : we don ' t set a breakpoint
* ( IOW : no poking in user ' s text segment ) ,
* instead we change fork / vfork / clone into clone ( CLONE_PTRACE ) .
* On newer kernels , we use PTRACE_O_TRACECLONE / TRACE [ V ] FORK instead .
*/
extern int setbpt ( struct tcb * ) ;
extern int clearbpt ( struct tcb * ) ;
extern const char * signame ( int ) ;
extern int is_restart_error ( struct tcb * ) ;
extern int pathtrace_select ( const char * ) ;
extern int pathtrace_match ( struct tcb * ) ;
extern const char * getfdpath ( struct tcb * , int ) ;
extern const char * xlookup ( const struct xlat * , int ) ;
2012-03-26 01:49:48 +04:00
extern int string_to_uint ( const char * str ) ;
2012-03-23 14:26:36 +04:00
# if HAVE_LONG_LONG
/* _l refers to the lower numbered u_arg,
* _h refers to the higher numbered u_arg
*/
# if HAVE_LITTLE_ENDIAN_LONG_LONG
# define LONG_LONG(_l,_h) \
( ( long long ) ( ( unsigned long long ) ( unsigned ) ( _l ) | ( ( unsigned long long ) ( _h ) < < 32 ) ) )
# else
# define LONG_LONG(_l,_h) \
( ( long long ) ( ( unsigned long long ) ( unsigned ) ( _h ) | ( ( unsigned long long ) ( _l ) < < 32 ) ) )
# endif
extern int printllval ( struct tcb * , const char * , int ) ;
# endif
2009-10-27 18:56:43 +03:00
extern void printxval ( const struct xlat * , int , const char * ) ;
extern int printargs ( struct tcb * ) ;
2012-02-27 17:18:02 +04:00
extern int printargs_lu ( struct tcb * ) ;
extern int printargs_ld ( struct tcb * ) ;
2011-08-19 20:06:46 +04:00
extern void addflags ( const struct xlat * , int ) ;
2009-10-27 18:56:43 +03:00
extern int printflags ( const struct xlat * , int , const char * ) ;
extern const char * sprintflags ( const char * , const struct xlat * , int ) ;
extern void dumpiov ( struct tcb * , int , long ) ;
extern void dumpstr ( struct tcb * , long , int ) ;
extern void printstr ( struct tcb * , long , int ) ;
2010-09-07 02:08:24 +04:00
extern void printnum ( struct tcb * , long , const char * ) ;
extern void printnum_int ( struct tcb * , long , const char * ) ;
2009-10-27 18:56:43 +03:00
extern void printpath ( struct tcb * , long ) ;
extern void printpathn ( struct tcb * , long , int ) ;
2012-01-20 14:04:04 +04:00
# define TIMESPEC_TEXT_BUFSIZE (sizeof(long)*3 * 2 + sizeof("{%u, %u}"))
# define TIMEVAL_TEXT_BUFSIZE TIMESPEC_TEXT_BUFSIZE
2009-10-27 18:56:43 +03:00
extern void printtv_bitness ( struct tcb * , long , enum bitness_t , int ) ;
2012-03-23 14:26:36 +04:00
# define printtv(tcp, addr) \
printtv_bitness ( ( tcp ) , ( addr ) , BITNESS_CURRENT , 0 )
# define printtv_special(tcp, addr) \
printtv_bitness ( ( tcp ) , ( addr ) , BITNESS_CURRENT , 1 )
2012-01-20 14:04:04 +04:00
extern char * sprinttv ( char * , struct tcb * , long , enum bitness_t , int special ) ;
2009-10-27 18:56:43 +03:00
extern void print_timespec ( struct tcb * , long ) ;
extern void sprint_timespec ( char * , struct tcb * , long ) ;
2001-10-18 19:13:53 +04:00
# ifdef HAVE_SIGINFO_T
2009-10-27 18:56:43 +03:00
extern void printsiginfo ( siginfo_t * , int ) ;
# endif
Fix decoding of file descriptors
* defs.h (printfd): New function prototype.
* util.c (printfd): New function.
* file.c (print_dirfd): Update prototype to use printfd().
(sys_openat, sys_faccessat, sys_newfstatat, sys_mkdirat, sys_linkat,
sys_unlinkat, sys_readlinkat, sys_renameat, sys_fchownat, sys_fchmodat,
sys_futimesat, sys_utimensat, sys_mknodat): Update use of print_dirfd().
(sys_lseek, sys_llseek, sys_readahead, sys_ftruncate, sys_ftruncate64,
sys_fstat, sys_fstat64, sys_oldfstat, sys_fstatfs, sys_fstatfs64,
sys_fchdir, sys_fchroot, sys_linkat, sys_fchown, sys_fchmod, sys_fsync,
sys_readdir, sys_getdents, sys_getdirentries, sys_fsetxattr,
sys_fgetxattr, sys_flistxattr, sys_fremovexattr, sys_fadvise64,
sys_fadvise64_64, sys_inotify_add_watch, sys_inotify_rm_watch,
sys_fallocate): Use printfd() for decoding of file descriptors.
* desc.c (sys_fcntl, sys_flock, sys_close, sys_dup, do_dup2,
decode_select, sys_epoll_ctl, epoll_wait_common): Use printfd() for
decoding of file descriptors.
* io.c (sys_read, sys_write, sys_readv, sys_writev, sys_pread,
sys_pwrite, sys_sendfile, sys_sendfile64, sys_pread64, sys_pwrite64,
sys_ioctl): Likewise.
* mem.c (print_mmap, sys_mmap64): Likewise.
* signal.c (do_signalfd): Likewise.
* stream.c (decode_poll): Likewise.
* time.c (sys_timerfd_settime, sys_timerfd_gettime): Likewise.
Based on patch from Grant Edwards <grant.b.edwards@gmail.com>.
2011-03-04 05:08:02 +03:00
extern void printfd ( struct tcb * , int ) ;
2009-10-27 18:56:43 +03:00
extern void printsock ( struct tcb * , long , int ) ;
extern void print_sock_optmgmt ( struct tcb * , long , int ) ;
extern void printrusage ( struct tcb * , long ) ;
2011-08-11 19:04:53 +04:00
# ifdef ALPHA
extern void printrusage32 ( struct tcb * , long ) ;
# endif
2009-10-27 18:56:43 +03:00
extern void printuid ( const char * , unsigned long ) ;
extern void printcall ( struct tcb * ) ;
extern void print_sigset ( struct tcb * , long , int ) ;
extern void printsignal ( int ) ;
2011-06-14 02:58:44 +04:00
extern void tprint_iov ( struct tcb * , unsigned long , unsigned long , int decode_iov ) ;
2009-10-27 18:56:43 +03:00
extern void tprint_open_modes ( mode_t ) ;
extern const char * sprint_open_modes ( mode_t ) ;
2012-04-05 06:22:01 +04:00
extern void print_loff_t ( struct tcb * , long ) ;
2011-04-08 00:25:40 +04:00
2009-10-27 18:56:43 +03:00
extern const struct ioctlent * ioctl_lookup ( long ) ;
extern const struct ioctlent * ioctl_next_match ( const struct ioctlent * ) ;
extern int ioctl_decode ( struct tcb * , long , long ) ;
extern int term_ioctl ( struct tcb * , long , long ) ;
extern int sock_ioctl ( struct tcb * , long , long ) ;
extern int proc_ioctl ( struct tcb * , int , int ) ;
extern int rtc_ioctl ( struct tcb * , long , long ) ;
extern int scsi_ioctl ( struct tcb * , long , long ) ;
2011-01-15 23:15:31 +03:00
extern int block_ioctl ( struct tcb * , long , long ) ;
2012-04-05 06:22:01 +04:00
extern int mtd_ioctl ( struct tcb * , long , long ) ;
1999-02-19 03:21:36 +03:00
2009-10-27 18:56:43 +03:00
extern int tv_nz ( struct timeval * ) ;
extern int tv_cmp ( struct timeval * , struct timeval * ) ;
extern double tv_float ( struct timeval * ) ;
extern void tv_add ( struct timeval * , struct timeval * , struct timeval * ) ;
extern void tv_sub ( struct timeval * , struct timeval * , struct timeval * ) ;
extern void tv_mul ( struct timeval * , struct timeval * , int ) ;
extern void tv_div ( struct timeval * , struct timeval * , int ) ;
1999-02-19 03:21:36 +03:00
2012-03-13 14:44:31 +04:00
/* Strace log generation machinery.
*
* printing_tcp : tcb which has incomplete line being printed right now .
* NULL if last line has been completed ( ' \n ' - terminated ) .
* printleader ( tcp ) examines it , finishes incomplete line if needed ,
* the sets it to tcp .
* line_ended ( ) clears printing_tcp and resets - > curcol = 0.
* tcp - > curcol = = 0 check is also used to detect completeness
* of last line , since in - ff mode just checking printing_tcp for NULL
* is not enough .
*
* If you change this code , test log generation in both - f and - ff modes
* using :
* strace - oLOG - f [ f ] test / threaded_execve
* strace - oLOG - f [ f ] test / sigkill_rain
* strace - oLOG - f [ f ] - p " `pidof web_browser` "
*/
extern struct tcb * printing_tcp ;
extern void printleader ( struct tcb * ) ;
extern void line_ended ( void ) ;
extern void tabto ( void ) ;
extern void tprintf ( const char * fmt , . . . ) __attribute__ ( ( format ( printf , 1 , 2 ) ) ) ;
extern void tprints ( const char * str ) ;
2012-03-19 12:36:42 +04:00
# if SUPPORTED_PERSONALITIES > 1
extern void set_personality ( int personality ) ;
1999-02-19 03:21:36 +03:00
extern int current_personality ;
2006-12-13 20:08:08 +03:00
extern const int personality_wordsize [ ] ;
2012-03-19 12:36:42 +04:00
# define current_wordsize (personality_wordsize[current_personality])
# else
# define set_personality(personality) ((void)0)
# define current_personality 0
# define current_wordsize PERSONALITY0_WORDSIZE
# endif
1999-02-19 03:21:36 +03:00
struct sysent {
2011-08-23 15:24:17 +04:00
unsigned nargs ;
1999-02-19 03:21:36 +03:00
int sys_flags ;
int ( * sys_func ) ( ) ;
2004-09-03 Roland McGrath <roland@redhat.com>
* syscall.c (sysent0, sysent1, sysent2, sysent): Add const to defn.
(nsyscalls0, nsyscalls1, nsyscalls2): Likewise.
(errnoent0, errnoent1, errnoent2, errnoent): Likewise.
(nerrnos0, nerrnos1, nerrnos2): Likewise.
* signal.c (signalent0, signalent1, signalent2): Likewise.
(nsignals0, nsignals1, nsignals2): Likewise.
(signame): LIkewise.
* ioctl.c (ioctlent0, ioctlent1, ioctlent2): Likewise.
(nioctlents0, nioctlents1, nioctlents2): Likewise.
(ioctl_lookup, ioctl_next_match): Likewise.
* defs.h: Update decls.
* io.c (sys_ioctl): Update users.
2004-09-04 07:53:10 +04:00
const char * sys_name ;
1999-02-19 03:21:36 +03:00
} ;
struct ioctlent {
2004-09-03 Roland McGrath <roland@redhat.com>
* syscall.c (sysent0, sysent1, sysent2, sysent): Add const to defn.
(nsyscalls0, nsyscalls1, nsyscalls2): Likewise.
(errnoent0, errnoent1, errnoent2, errnoent): Likewise.
(nerrnos0, nerrnos1, nerrnos2): Likewise.
* signal.c (signalent0, signalent1, signalent2): Likewise.
(nsignals0, nsignals1, nsignals2): Likewise.
(signame): LIkewise.
* ioctl.c (ioctlent0, ioctlent1, ioctlent2): Likewise.
(nioctlents0, nioctlents1, nioctlents2): Likewise.
(ioctl_lookup, ioctl_next_match): Likewise.
* defs.h: Update decls.
* io.c (sys_ioctl): Update users.
2004-09-04 07:53:10 +04:00
const char * doth ;
const char * symbol ;
1999-02-19 03:21:36 +03:00
unsigned long code ;
} ;
Small optimization in signal and ioctl tables
Trivial shuffling of data tables puts them all in one file,
allowing gcc to see their sizes and eliminate variables
which store these sizes.
Surprisingly, in C mode gcc does not optimize out static const int
variables. Help it by using enums instead.
* defs.h: Stop exporting ioctlent{0,1,2}, nioctlents{0,1,2},
signalent{0,1,2}, nsignals{0,1,2}.
* ioctl.c: Remove definitions of ioctlent{,0,1,2} and nioctlents{,0,1,2}.
* signal.c: Remove definitions of signalent{,0,1,2} and nsignals{,0,1,2}.
* syscall.c: Move above definitions to this file. Make them static const
or enums if suitable.
2011-08-20 04:12:33 +04:00
extern const struct sysent * sysent ;
2011-08-23 15:29:01 +04:00
extern unsigned nsyscalls ;
Small optimization in signal and ioctl tables
Trivial shuffling of data tables puts them all in one file,
allowing gcc to see their sizes and eliminate variables
which store these sizes.
Surprisingly, in C mode gcc does not optimize out static const int
variables. Help it by using enums instead.
* defs.h: Stop exporting ioctlent{0,1,2}, nioctlents{0,1,2},
signalent{0,1,2}, nsignals{0,1,2}.
* ioctl.c: Remove definitions of ioctlent{,0,1,2} and nioctlents{,0,1,2}.
* signal.c: Remove definitions of signalent{,0,1,2} and nsignals{,0,1,2}.
* syscall.c: Move above definitions to this file. Make them static const
or enums if suitable.
2011-08-20 04:12:33 +04:00
extern const char * const * errnoent ;
2011-08-23 15:29:01 +04:00
extern unsigned nerrnos ;
2004-09-03 Roland McGrath <roland@redhat.com>
* syscall.c (sysent0, sysent1, sysent2, sysent): Add const to defn.
(nsyscalls0, nsyscalls1, nsyscalls2): Likewise.
(errnoent0, errnoent1, errnoent2, errnoent): Likewise.
(nerrnos0, nerrnos1, nerrnos2): Likewise.
* signal.c (signalent0, signalent1, signalent2): Likewise.
(nsignals0, nsignals1, nsignals2): Likewise.
(signame): LIkewise.
* ioctl.c (ioctlent0, ioctlent1, ioctlent2): Likewise.
(nioctlents0, nioctlents1, nioctlents2): Likewise.
(ioctl_lookup, ioctl_next_match): Likewise.
* defs.h: Update decls.
* io.c (sys_ioctl): Update users.
2004-09-04 07:53:10 +04:00
extern const struct ioctlent * ioctlent ;
2011-08-23 15:29:01 +04:00
extern unsigned nioctlents ;
2004-09-03 Roland McGrath <roland@redhat.com>
* syscall.c (sysent0, sysent1, sysent2, sysent): Add const to defn.
(nsyscalls0, nsyscalls1, nsyscalls2): Likewise.
(errnoent0, errnoent1, errnoent2, errnoent): Likewise.
(nerrnos0, nerrnos1, nerrnos2): Likewise.
* signal.c (signalent0, signalent1, signalent2): Likewise.
(nsignals0, nsignals1, nsignals2): Likewise.
(signame): LIkewise.
* ioctl.c (ioctlent0, ioctlent1, ioctlent2): Likewise.
(nioctlents0, nioctlents1, nioctlents2): Likewise.
(ioctl_lookup, ioctl_next_match): Likewise.
* defs.h: Update decls.
* io.c (sys_ioctl): Update users.
2004-09-04 07:53:10 +04:00
extern const char * const * signalent ;
2011-08-23 15:29:01 +04:00
extern unsigned nsignals ;
1999-02-19 03:21:36 +03:00
2012-02-03 22:19:55 +04:00
# define SCNO_IN_RANGE(scno) \
( ( unsigned long ) ( scno ) < nsyscalls & & sysent [ scno ] . sys_func )