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 >
1999-12-23 17:20:14 +03:00
* Copyright ( c ) 1996 - 1999 Wichert Akkerman < wichert @ cistron . nl >
* Copyright ( c ) 1999 IBM Deutschland Entwicklung GmbH , IBM Corporation
* Linux for s390 port by D . J . Barrow
* < barrow_dj @ mail . yahoo . com , djbarrow @ de . ibm . com >
*
1999-02-19 03:21:36 +03:00
* 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 .
*
* $ Id $
*/
# include "defs.h"
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <sys/wait.h>
# include <sys/resource.h>
# include <sys/utsname.h>
# include <sys/user.h>
# include <sys/syscall.h>
# include <signal.h>
# ifdef SUNOS4
# include <machine/reg.h>
# endif /* SUNOS4 */
2000-09-02 01:03:06 +04:00
# ifdef FREEBSD
# include <sys/ptrace.h>
# endif
2001-03-29 00:29:17 +04:00
# if HAVE_ASM_REG_H
# ifdef SPARC
# define fpq kernel_fpq
# define fq kernel_fq
# define fpu kernel_fpu
# endif
# include <asm/reg.h>
# ifdef SPARC
# undef fpq
# undef fq
# undef fpu
# endif
# endif /* HAVE_ASM_REG_H */
1999-07-13 19:45:02 +04:00
# ifdef HAVE_SYS_REG_H
1999-02-19 03:21:36 +03:00
# include <sys / reg.h>
1999-10-06 17:06:34 +04:00
# ifndef PTRACE_PEEKUSR
1999-02-19 03:21:36 +03:00
# define PTRACE_PEEKUSR PTRACE_PEEKUSER
1999-10-06 17:06:34 +04:00
# endif
# ifndef PTRACE_POKEUSR
1999-02-19 03:21:36 +03:00
# define PTRACE_POKEUSR PTRACE_POKEUSER
# endif
2000-02-20 02:59:03 +03:00
# elif defined(HAVE_LINUX_PTRACE_H)
# undef PTRACE_SYSCALL
# include <linux/ptrace.h>
1999-10-06 17:06:34 +04:00
# endif
1999-02-19 03:21:36 +03:00
2000-02-20 02:59:03 +03:00
1999-02-19 03:21:36 +03:00
# ifdef LINUX
1999-05-09 04:29:58 +04:00
# include <asm/posix_types.h>
# undef GETGROUPS_T
# define GETGROUPS_T __kernel_gid_t
1999-02-19 03:21:36 +03:00
# endif /* LINUX */
2000-02-04 00:58:30 +03:00
# if defined(LINUX) && defined(IA64)
# include <asm / ptrace_offsets.h>
# include <asm / rse.h>
# endif
1999-02-19 03:21:36 +03:00
# ifdef HAVE_PRCTL
# include <sys/prctl.h>
# endif
# ifndef WCOREDUMP
# define WCOREDUMP(status) ((status) & 0200)
# endif
1999-12-23 18:08:17 +03:00
/* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
1999-02-19 03:21:36 +03:00
# if defined(HAVE_PRCTL)
static struct xlat prctl_options [ ] = {
# ifdef PR_MAXPROCS
{ PR_MAXPROCS , " PR_MAXPROCS " } ,
# endif
# ifdef PR_ISBLOCKED
{ PR_ISBLOCKED , " PR_ISBLOCKED " } ,
# endif
# ifdef PR_SETSTACKSIZE
{ PR_SETSTACKSIZE , " PR_SETSTACKSIZE " } ,
# endif
# ifdef PR_GETSTACKSIZE
{ PR_GETSTACKSIZE , " PR_GETSTACKSIZE " } ,
# endif
# ifdef PR_MAXPPROCS
{ PR_MAXPPROCS , " PR_MAXPPROCS " } ,
# endif
# ifdef PR_UNBLKONEXEC
{ PR_UNBLKONEXEC , " PR_UNBLKONEXEC " } ,
# endif
# ifdef PR_ATOMICSIM
{ PR_ATOMICSIM , " PR_ATOMICSIM " } ,
# endif
# ifdef PR_SETEXITSIG
{ PR_SETEXITSIG , " PR_SETEXITSIG " } ,
# endif
# ifdef PR_RESIDENT
{ PR_RESIDENT , " PR_RESIDENT " } ,
# endif
# ifdef PR_ATTACHADDR
{ PR_ATTACHADDR , " PR_ATTACHADDR " } ,
# endif
# ifdef PR_DETACHADDR
{ PR_DETACHADDR , " PR_DETACHADDR " } ,
# endif
# ifdef PR_TERMCHILD
{ PR_TERMCHILD , " PR_TERMCHILD " } ,
# endif
# ifdef PR_GETSHMASK
{ PR_GETSHMASK , " PR_GETSHMASK " } ,
# endif
# ifdef PR_GETNSHARE
{ PR_GETNSHARE , " PR_GETNSHARE " } ,
# endif
# if defined(PR_SET_PDEATHSIG)
{ PR_SET_PDEATHSIG , " PR_SET_PDEATHSIG " } ,
1999-06-11 17:18:40 +04:00
# endif
# ifdef PR_COREPID
{ PR_COREPID , " PR_COREPID " } ,
# endif
# ifdef PR_ATTACHADDRPERM
{ PR_ATTACHADDRPERM , " PR_ATTACHADDRPERM " } ,
# endif
# ifdef PR_PTHREADEXIT
{ PR_PTHREADEXIT , " PR_PTHREADEXIT " } ,
1999-11-18 20:09:47 +03:00
# endif
# ifdef PR_SET_PDEATHSIG
{ PR_SET_PDEATHSIG , " PR_SET_PDEATHSIG " } ,
# endif
# ifdef PR_GET_PDEATHSIG
{ PR_GET_PDEATHSIG , " PR_GET_PDEATHSIG " } ,
2000-05-01 05:53:59 +04:00
# endif
# ifdef PR_GET_UNALIGN
{ PR_GET_UNALIGN , " PR_GET_UNALIGN " } ,
# endif
# ifdef PR_SET_UNALIGN
{ PR_SET_UNALIGN , " PR_SET_UNALIGN " } ,
# endif
# ifdef PR_GET_KEEPCAPS
{ PR_GET_KEEPCAPS , " PR_GET_KEEP_CAPS " } ,
# endif
# ifdef PR_SET_KEEPCAPS
{ PR_SET_KEEPCAPS , " PR_SET_KEEP_CAPS " } ,
1999-02-19 03:21:36 +03:00
# endif
{ 0 , NULL } ,
} ;
2000-05-01 05:53:59 +04:00
const char *
unalignctl_string ( unsigned int ctl )
{
static char buf [ 16 ] ;
switch ( ctl ) {
# ifdef PR_UNALIGN_NOPRINT
case PR_UNALIGN_NOPRINT :
return " NOPRINT " ;
# endif
# ifdef PR_UNALIGN_SIGBUS
case PR_UNALIGN_SIGBUS :
return " SIGBUS " ;
# endif
default :
break ;
}
sprintf ( buf , " %x " , ctl ) ;
return buf ;
}
1999-02-19 03:21:36 +03:00
int
sys_prctl ( tcp )
struct tcb * tcp ;
{
int i ;
if ( entering ( tcp ) ) {
printxval ( prctl_options , tcp - > u_arg [ 0 ] , " PR_??? " ) ;
switch ( tcp - > u_arg [ 0 ] ) {
# ifdef PR_GETNSHARE
case PR_GETNSHARE :
break ;
1999-11-18 20:09:47 +03:00
# endif
# ifdef PR_SET_DEATHSIG
case PR_GET_PDEATHSIG :
break ;
2000-05-01 05:53:59 +04:00
# endif
# ifdef PR_SET_UNALIGN
case PR_SET_UNALIGN :
tprintf ( " , %s " , unalignctl_string ( tcp - > u_arg [ 1 ] ) ) ;
break ;
# endif
# ifdef PR_GET_UNALIGN
case PR_GET_UNALIGN :
tprintf ( " , %#lx " , tcp - > u_arg [ 1 ] ) ;
break ;
1999-02-19 03:21:36 +03:00
# endif
default :
for ( i = 1 ; i < tcp - > u_nargs ; i + + )
tprintf ( " , %#lx " , tcp - > u_arg [ i ] ) ;
break ;
}
1999-11-18 20:09:47 +03:00
} else {
switch ( tcp - > u_arg [ 0 ] ) {
# ifdef PR_GET_PDEATHSIG
case PR_GET_PDEATHSIG :
for ( i = 1 ; i < tcp - > u_nargs ; i + + )
1999-12-23 17:20:14 +03:00
tprintf ( " , %#lx " , tcp - > u_arg [ i ] ) ;
1999-11-18 20:09:47 +03:00
break ;
2000-05-01 05:53:59 +04:00
# endif
# ifdef PR_SET_UNALIGN
case PR_SET_UNALIGN :
break ;
# endif
# ifdef PR_GET_UNALIGN
case PR_GET_UNALIGN :
{
int ctl ;
umove ( tcp , tcp - > u_arg [ 1 ] , & ctl ) ;
tcp - > auxstr = unalignctl_string ( ctl ) ;
return RVAL_STR ;
}
1999-11-18 20:09:47 +03:00
# endif
default :
break ;
}
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
# endif /* HAVE_PRCTL */
int
sys_gethostid ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) )
return RVAL_HEX ;
return 0 ;
}
int
sys_sethostname ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
printpathn ( tcp , tcp - > u_arg [ 0 ] , tcp - > u_arg [ 1 ] ) ;
tprintf ( " , %lu " , tcp - > u_arg [ 1 ] ) ;
}
return 0 ;
}
int
sys_gethostname ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else
printpath ( tcp , tcp - > u_arg [ 0 ] ) ;
tprintf ( " , %lu " , tcp - > u_arg [ 1 ] ) ;
}
return 0 ;
}
int
sys_setdomainname ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
printpathn ( tcp , tcp - > u_arg [ 0 ] , tcp - > u_arg [ 1 ] ) ;
tprintf ( " , %lu " , tcp - > u_arg [ 1 ] ) ;
}
return 0 ;
}
1999-03-15 22:49:42 +03:00
# if !defined(LINUX)
1999-02-19 03:21:36 +03:00
int
sys_getdomainname ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else
printpath ( tcp , tcp - > u_arg [ 0 ] ) ;
tprintf ( " , %lu " , tcp - > u_arg [ 1 ] ) ;
}
return 0 ;
}
# endif /* !LINUX */
int
sys_exit ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
fprintf ( stderr , " _exit returned! \n " ) ;
return - 1 ;
}
/* special case: we stop tracing this process, finish line now */
tprintf ( " %ld) " , tcp - > u_arg [ 0 ] ) ;
tabto ( acolumn ) ;
tprintf ( " = ? " ) ;
printtrailer ( tcp ) ;
return 0 ;
}
int
internal_exit ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) )
tcp - > flags | = TCB_EXITING ;
return 0 ;
}
2000-09-02 01:03:06 +04:00
# ifdef USE_PROCFS
1999-02-19 03:21:36 +03:00
int
sys_fork ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
if ( getrval2 ( tcp ) ) {
tcp - > auxstr = " child process " ;
return RVAL_UDECIMAL | RVAL_STR ;
}
}
return 0 ;
}
2001-04-18 19:11:51 +04:00
# if UNIXWARE > 2
int
sys_rfork ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " %ld " , tcp - > u_arg [ 0 ] ) ;
}
else {
if ( getrval2 ( tcp ) ) {
tcp - > auxstr = " child process " ;
return RVAL_UDECIMAL | RVAL_STR ;
}
}
return 0 ;
}
# endif
1999-02-19 03:21:36 +03:00
int
internal_fork ( tcp )
struct tcb * tcp ;
{
struct tcb * tcpchild ;
if ( exiting ( tcp ) ) {
if ( getrval2 ( tcp ) )
return 0 ;
if ( ! followfork )
return 0 ;
if ( nprocs = = MAX_PROCS ) {
tcp - > flags & = ~ TCB_FOLLOWFORK ;
fprintf ( stderr , " sys_fork: tcb table full \n " ) ;
return 0 ;
}
else
tcp - > flags | = TCB_FOLLOWFORK ;
if ( syserror ( tcp ) )
return 0 ;
if ( ( tcpchild = alloctcb ( tcp - > u_rval ) ) = = NULL ) {
fprintf ( stderr , " sys_fork: tcb table full \n " ) ;
return 0 ;
}
2000-09-04 03:57:48 +04:00
if ( proc_open ( tcpchild , 2 ) < 0 )
2000-09-02 01:03:06 +04:00
droptcb ( tcpchild ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
2000-09-02 01:03:06 +04:00
# else /* !USE_PROCFS */
1999-02-19 03:21:36 +03:00
1999-12-23 18:08:17 +03:00
# ifdef LINUX
/* defines copied from linux/sched.h since we can't include that
* ourselves ( it conflicts with * lots * of libc includes )
*/
# define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
# define CLONE_VM 0x00000100 /* set if VM shared between processes */
# define CLONE_FS 0x00000200 /* set if fs info shared between processes */
# define CLONE_FILES 0x00000400 /* set if open files shared between processes */
# define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
# define CLONE_PID 0x00001000 /* set if pid shared */
# define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
# define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
# define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
static struct xlat clone_flags [ ] = {
{ CLONE_VM , " CLONE_VM " } ,
{ CLONE_FS , " CLONE_FS " } ,
{ CLONE_FILES , " CLONE_FILES " } ,
{ CLONE_SIGHAND , " CLONE_SIGHAND " } ,
{ CLONE_PID , " CLONE_PID " } ,
{ CLONE_PTRACE , " CLONE_PTRACE " } ,
{ CLONE_VFORK , " CLONE_VFORK " } ,
{ CLONE_PARENT , " CLONE_PARENT " } ,
{ 0 , NULL } ,
} ;
2000-02-04 00:58:30 +03:00
int
sys_clone ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
tprintf ( " child_stack=%#lx, flags= " , tcp - > u_arg [ 1 ] ) ;
if ( printflags ( clone_flags , tcp - > u_arg [ 0 ] ) = = 0 )
tprintf ( " 0 " ) ;
}
return 0 ;
}
2001-10-10 03:47:38 +04:00
int
sys_clone2 ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
tprintf ( " child_stack=%#lx, stack_size=%#lx, flags= " ,
tcp - > u_arg [ 1 ] , tcp - > u_arg [ 2 ] ) ;
if ( printflags ( clone_flags , tcp - > u_arg [ 0 ] ) = = 0 )
tprintf ( " 0 " ) ;
}
return 0 ;
}
1999-12-23 18:08:17 +03:00
# endif
1999-02-19 03:21:36 +03:00
int
sys_fork ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) )
return RVAL_UDECIMAL ;
return 0 ;
}
2000-02-20 02:59:03 +03:00
int
change_syscall ( tcp , new )
struct tcb * tcp ;
int new ;
{
# if defined(LINUX)
# if defined(I386)
/* Attempt to make vfork into fork, which we can follow. */
if ( ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) ( ORIG_EAX * 4 ) , new ) < 0 )
return - 1 ;
return 0 ;
# elif defined(POWERPC)
2001-04-12 13:00:47 +04:00
if ( ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) ( 4 * PT_R0 ) , new ) < 0 )
2000-02-20 02:59:03 +03:00
return - 1 ;
# elif defined(S390)
long pc ;
if ( upeek ( tcp - > pid , PT_PSWADDR , & pc ) < 0 )
return - 1 ;
if ( ptrace ( PTRACE_POKETEXT , tcp - > pid , ( char * ) ( pc - 4 ) , new ) < 0 )
return - 1 ;
return 0 ;
# elif defined(M68K)
2000-04-11 02:22:31 +04:00
if ( ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) ( 4 * PT_ORIG_D0 ) , new ) < 0 )
2000-02-20 02:59:03 +03:00
return - 1 ;
return 0 ;
2000-05-01 05:53:59 +04:00
# elif defined(SPARC)
2001-03-29 00:29:17 +04:00
struct regs regs ;
2000-05-01 05:53:59 +04:00
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 )
return - 1 ;
2001-03-29 00:29:17 +04:00
regs . r_g1 = new ;
2000-05-01 05:53:59 +04:00
if ( ptrace ( PTRACE_SETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 )
return - 1 ;
return 0 ;
2000-02-20 02:59:03 +03:00
# elif defined(MIPS)
2000-04-11 02:22:31 +04:00
if ( ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) ( REG_V0 ) , new ) < 0 )
2000-02-20 02:59:03 +03:00
return - 1 ;
return 0 ;
# elif defined(ALPHA)
2000-04-11 02:22:31 +04:00
if ( ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) ( REG_A3 ) , new ) < 0 )
2000-02-20 02:59:03 +03:00
return - 1 ;
return 0 ;
2001-10-10 03:47:38 +04:00
# elif defined(IA64)
if ( ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) ( PT_R15 ) , new ) < 0 )
return - 1 ;
return 0 ;
2001-03-27 16:17:16 +04:00
# elif defined(HPPA)
if ( ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) ( PT_GR20 ) , new ) < 0 )
return - 1 ;
return 0 ;
2000-02-20 02:59:03 +03:00
# else
# warning Do not know how to handle change_syscall for this architecture
# endif /* architecture */
# endif /* LINUX */
return - 1 ;
}
2000-02-04 00:58:30 +03:00
int
setarg ( tcp , argnum )
struct tcb * tcp ;
int argnum ;
{
# if defined (IA64)
{
unsigned long * bsp , * ap ;
if ( upeek ( tcp - > pid , PT_AR_BSP , ( long * ) & bsp ) , 0 )
return - 1 ;
ap = ia64_rse_skip_regs ( bsp , argnum ) ;
errno = 0 ;
2001-10-10 03:47:38 +04:00
ptrace ( PTRACE_POKEDATA , tcp - > pid , ( char * ) ap , tcp - > u_arg [ argnum ] ) ;
2000-02-04 00:58:30 +03:00
if ( errno )
return - 1 ;
}
2000-02-14 19:23:40 +03:00
# elif defined(I386)
{
2000-02-20 02:59:03 +03:00
ptrace ( PTRACE_POKEUSER , tcp - > pid , ( char * ) ( 4 * argnum ) , tcp - > u_arg [ argnum ] ) ;
2000-02-14 19:23:40 +03:00
if ( errno )
return - 1 ;
}
2000-08-01 04:06:06 +04:00
# elif defined(MIPS)
{
errno = 0 ;
if ( argnum < 4 )
ptrace ( PTRACE_POKEUSER , tcp - > pid ,
( char * ) ( REG_A0 + argnum ) , tcp - > u_arg [ argnum ] ) ;
else {
unsigned long * sp ;
if ( upeek ( tcp - > pid , REG_SP , ( long * ) & sp ) , 0 )
return - 1 ;
ptrace ( PTRACE_POKEDATA , tcp - > pid ,
( char * ) ( sp + argnum - 4 ) , tcp - > u_arg [ argnum ] ) ;
}
if ( errno )
return - 1 ;
}
2000-02-04 00:58:30 +03:00
# else
2000-02-20 02:59:03 +03:00
# warning Sorry, setargs not implemented for this architecture.
2000-02-04 00:58:30 +03:00
# endif
return 0 ;
}
1999-12-23 18:08:17 +03:00
# ifdef SYS_clone
int
internal_clone ( tcp )
struct tcb * tcp ;
{
1999-12-24 10:22:25 +03:00
struct tcb * tcpchild ;
int pid ;
1999-12-23 18:08:17 +03:00
if ( entering ( tcp ) ) {
2000-02-04 00:58:30 +03:00
if ( ! followfork )
1999-12-23 18:08:17 +03:00
return 0 ;
if ( nprocs = = MAX_PROCS ) {
tcp - > flags & = ~ TCB_FOLLOWFORK ;
fprintf ( stderr , " sys_fork: tcb table full \n " ) ;
return 0 ;
}
tcp - > flags | = TCB_FOLLOWFORK ;
2000-09-04 01:56:29 +04:00
if ( setbpt ( tcp ) < 0 )
return 0 ;
1999-12-23 18:08:17 +03:00
} else {
2000-09-04 01:56:29 +04:00
int bpt = tcp - > flags & TCB_BPTSET ;
1999-12-23 18:08:17 +03:00
if ( ! ( tcp - > flags & TCB_FOLLOWFORK ) )
return 0 ;
2001-10-10 03:47:38 +04:00
if ( syserror ( tcp ) ) {
if ( bpt )
clearbpt ( tcp ) ;
1999-12-23 18:08:17 +03:00
return 0 ;
2001-10-10 03:47:38 +04:00
}
1999-12-23 18:08:17 +03:00
pid = tcp - > u_rval ;
if ( ( tcpchild = alloctcb ( pid ) ) = = NULL ) {
2001-10-10 03:47:38 +04:00
if ( bpt )
clearbpt ( tcp ) ;
1999-12-23 18:08:17 +03:00
fprintf ( stderr , " [tcb table full] \n " ) ;
kill ( pid , SIGKILL ) ; /* XXX */
return 0 ;
}
2000-09-04 01:56:29 +04:00
/* Attach to the new child */
if ( ptrace ( PTRACE_ATTACH , pid , ( char * ) 1 , 0 ) < 0 ) {
2001-10-10 03:47:38 +04:00
if ( bpt )
clearbpt ( tcp ) ;
2000-09-04 01:56:29 +04:00
perror ( " PTRACE_ATTACH " ) ;
fprintf ( stderr , " Too late? \n " ) ;
droptcb ( tcpchild ) ;
return 0 ;
}
2001-10-10 03:47:38 +04:00
if ( bpt )
clearbpt ( tcp ) ;
1999-12-24 10:22:25 +03:00
tcpchild - > flags | = TCB_ATTACHED ;
2000-09-04 01:56:29 +04:00
if ( bpt ) {
tcpchild - > flags | = TCB_BPTSET ;
tcpchild - > baddr = tcp - > baddr ;
memcpy ( tcpchild - > inst , tcp - > inst ,
sizeof tcpchild - > inst ) ;
}
1999-12-24 10:22:25 +03:00
newoutf ( tcpchild ) ;
2001-10-10 03:47:38 +04:00
tcpchild - > parent = tcp ;
1999-12-23 18:08:17 +03:00
tcp - > nchildren + + ;
if ( ! qflag )
fprintf ( stderr , " Process %d attached \n " , pid ) ;
}
return 0 ;
}
# endif
1999-02-19 03:21:36 +03:00
int
internal_fork ( tcp )
struct tcb * tcp ;
{
struct tcb * tcpchild ;
int pid ;
1999-03-30 02:57:54 +04:00
int dont_follow = 0 ;
1999-02-19 03:21:36 +03:00
# ifdef SYS_vfork
1999-03-30 02:57:54 +04:00
if ( tcp - > scno = = SYS_vfork ) {
/* Attempt to make vfork into fork, which we can follow. */
if ( ! followvfork | |
2000-02-01 19:22:52 +03:00
change_syscall ( tcp , SYS_fork ) < 0 )
1999-03-30 02:57:54 +04:00
dont_follow = 1 ;
}
1999-02-19 03:21:36 +03:00
# endif
if ( entering ( tcp ) ) {
1999-03-30 02:57:54 +04:00
if ( ! followfork | | dont_follow )
1999-02-19 03:21:36 +03:00
return 0 ;
if ( nprocs = = MAX_PROCS ) {
tcp - > flags & = ~ TCB_FOLLOWFORK ;
fprintf ( stderr , " sys_fork: tcb table full \n " ) ;
return 0 ;
}
tcp - > flags | = TCB_FOLLOWFORK ;
if ( setbpt ( tcp ) < 0 )
return 0 ;
1999-12-23 18:08:17 +03:00
}
1999-02-19 03:21:36 +03:00
else {
int bpt = tcp - > flags & TCB_BPTSET ;
if ( ! ( tcp - > flags & TCB_FOLLOWFORK ) )
return 0 ;
if ( bpt )
clearbpt ( tcp ) ;
if ( syserror ( tcp ) )
return 0 ;
pid = tcp - > u_rval ;
if ( ( tcpchild = alloctcb ( pid ) ) = = NULL ) {
fprintf ( stderr , " [tcb table full] \n " ) ;
kill ( pid , SIGKILL ) ; /* XXX */
return 0 ;
}
# ifdef LINUX
2001-03-27 16:17:16 +04:00
# ifdef HPPA
/* The child must have run before it can be attached. */
/* This must be a bug in the parisc kernel, but I havn't
* identified it yet . Seems to be an issue associated
* with attaching to a process ( which sends it a signal )
* before that process has ever been scheduled . When
* debugging , I started seeing crashes in
* arch / parisc / kernel / signal . c : do_signal ( ) , apparently
* caused by r8 getting corrupt over the dequeue_signal ( )
* call . Didn ' t make much sense though . . .
*/
{
struct timeval tv ;
tv . tv_sec = 0 ;
tv . tv_usec = 10000 ;
select ( 0 , NULL , NULL , NULL , & tv ) ;
}
# endif
1999-02-19 03:21:36 +03:00
if ( ptrace ( PTRACE_ATTACH , pid , ( char * ) 1 , 0 ) < 0 ) {
perror ( " PTRACE_ATTACH " ) ;
fprintf ( stderr , " Too late? \n " ) ;
droptcb ( tcpchild ) ;
return 0 ;
}
# endif /* LINUX */
# ifdef SUNOS4
# ifdef oldway
/* The child must have run before it can be attached. */
{
struct timeval tv ;
tv . tv_sec = 0 ;
tv . tv_usec = 10000 ;
select ( 0 , NULL , NULL , NULL , & tv ) ;
}
if ( ptrace ( PTRACE_ATTACH , pid , ( char * ) 1 , 0 ) < 0 ) {
perror ( " PTRACE_ATTACH " ) ;
fprintf ( stderr , " Too late? \n " ) ;
droptcb ( tcpchild ) ;
return 0 ;
}
# else /* !oldway */
/* Try to catch the new process as soon as possible. */
{
int i ;
for ( i = 0 ; i < 1024 ; i + + )
if ( ptrace ( PTRACE_ATTACH , pid , ( char * ) 1 , 0 ) > = 0 )
break ;
if ( i = = 1024 ) {
perror ( " PTRACE_ATTACH " ) ;
fprintf ( stderr , " Too late? \n " ) ;
droptcb ( tcpchild ) ;
return 0 ;
}
}
# endif /* !oldway */
# endif /* SUNOS4 */
tcpchild - > flags | = TCB_ATTACHED ;
/* Child has BPT too, must be removed on first occasion */
if ( bpt ) {
tcpchild - > flags | = TCB_BPTSET ;
tcpchild - > baddr = tcp - > baddr ;
memcpy ( tcpchild - > inst , tcp - > inst ,
sizeof tcpchild - > inst ) ;
}
newoutf ( tcpchild ) ;
tcpchild - > parent = tcp ;
tcp - > nchildren + + ;
if ( ! qflag )
fprintf ( stderr , " Process %d attached \n " , pid ) ;
}
return 0 ;
}
2000-09-02 01:03:06 +04:00
# endif /* !USE_PROCFS */
1999-02-19 03:21:36 +03:00
2000-09-02 01:03:06 +04:00
# if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1999-02-19 03:21:36 +03:00
int
sys_vfork ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) )
return RVAL_UDECIMAL ;
return 0 ;
}
2000-09-02 01:03:06 +04:00
# endif /* SUNOS4 || LINUX || FREEBSD */
1999-02-19 03:21:36 +03:00
# ifndef LINUX
static char idstr [ 16 ] ;
int
sys_getpid ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
sprintf ( idstr , " ppid %lu " , getrval2 ( tcp ) ) ;
tcp - > auxstr = idstr ;
return RVAL_STR ;
}
return 0 ;
}
int
sys_getuid ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
sprintf ( idstr , " euid %lu " , getrval2 ( tcp ) ) ;
tcp - > auxstr = idstr ;
return RVAL_STR ;
}
return 0 ;
}
int
sys_getgid ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
sprintf ( idstr , " egid %lu " , getrval2 ( tcp ) ) ;
tcp - > auxstr = idstr ;
return RVAL_STR ;
}
return 0 ;
}
# endif /* !LINUX */
# ifdef LINUX
int
sys_setuid ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " %u " , ( uid_t ) tcp - > u_arg [ 0 ] ) ;
}
return 0 ;
}
int
sys_setgid ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " %u " , ( gid_t ) tcp - > u_arg [ 0 ] ) ;
}
return 0 ;
}
int
sys_getresuid ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
1999-05-09 04:29:58 +04:00
__kernel_uid_t uid ;
if ( syserror ( tcp ) )
tprintf ( " %#lx, %#lx, %#lx " , tcp - > u_arg [ 0 ] ,
tcp - > u_arg [ 1 ] , tcp - > u_arg [ 2 ] ) ;
else {
if ( umove ( tcp , tcp - > u_arg [ 0 ] , & uid ) < 0 )
tprintf ( " %#lx, " , tcp - > u_arg [ 0 ] ) ;
else
tprintf ( " ruid %lu, " , ( unsigned long ) uid ) ;
if ( umove ( tcp , tcp - > u_arg [ 0 ] , & uid ) < 0 )
tprintf ( " %#lx, " , tcp - > u_arg [ 0 ] ) ;
else
tprintf ( " euid %lu, " , ( unsigned long ) uid ) ;
if ( umove ( tcp , tcp - > u_arg [ 0 ] , & uid ) < 0 )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else
tprintf ( " suid %lu " , ( unsigned long ) uid ) ;
}
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
int
sys_getresgid ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
1999-05-09 04:29:58 +04:00
__kernel_gid_t gid ;
if ( syserror ( tcp ) )
tprintf ( " %#lx, %#lx, %#lx " , tcp - > u_arg [ 0 ] ,
tcp - > u_arg [ 1 ] , tcp - > u_arg [ 2 ] ) ;
else {
if ( umove ( tcp , tcp - > u_arg [ 0 ] , & gid ) < 0 )
tprintf ( " %#lx, " , tcp - > u_arg [ 0 ] ) ;
else
tprintf ( " rgid %lu, " , ( unsigned long ) gid ) ;
if ( umove ( tcp , tcp - > u_arg [ 0 ] , & gid ) < 0 )
tprintf ( " %#lx, " , tcp - > u_arg [ 0 ] ) ;
else
tprintf ( " egid %lu, " , ( unsigned long ) gid ) ;
if ( umove ( tcp , tcp - > u_arg [ 0 ] , & gid ) < 0 )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else
tprintf ( " sgid %lu " , ( unsigned long ) gid ) ;
}
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
# endif /* LINUX */
int
sys_setreuid ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " %lu, %lu " ,
( unsigned long ) ( uid_t ) tcp - > u_arg [ 0 ] ,
( unsigned long ) ( uid_t ) tcp - > u_arg [ 1 ] ) ;
}
return 0 ;
}
int
sys_setregid ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " %lu, %lu " ,
( unsigned long ) ( gid_t ) tcp - > u_arg [ 0 ] ,
( unsigned long ) ( gid_t ) tcp - > u_arg [ 1 ] ) ;
}
return 0 ;
}
2000-09-02 01:03:06 +04:00
# if defined(LINUX) || defined(FREEBSD)
1999-02-19 03:21:36 +03:00
int
sys_setresuid ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " ruid %u, euid %u, suid %u " ,
( uid_t ) tcp - > u_arg [ 0 ] ,
( uid_t ) tcp - > u_arg [ 1 ] ,
( uid_t ) tcp - > u_arg [ 2 ] ) ;
}
return 0 ;
}
int
sys_setresgid ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " rgid %u, egid %u, sgid %u " ,
( uid_t ) tcp - > u_arg [ 0 ] ,
( uid_t ) tcp - > u_arg [ 1 ] ,
( uid_t ) tcp - > u_arg [ 2 ] ) ;
}
return 0 ;
}
2000-09-02 01:03:06 +04:00
# endif /* LINUX || FREEBSD */
1999-02-19 03:21:36 +03:00
int
sys_setgroups ( tcp )
struct tcb * tcp ;
{
int i , len ;
GETGROUPS_T * gidset ;
if ( entering ( tcp ) ) {
len = tcp - > u_arg [ 0 ] ;
tprintf ( " %u, " , len ) ;
if ( len < = 0 ) {
tprintf ( " [] " ) ;
return 0 ;
}
gidset = ( GETGROUPS_T * ) malloc ( len * sizeof ( GETGROUPS_T ) ) ;
if ( gidset = = NULL ) {
fprintf ( stderr , " sys_setgroups: out of memory \n " ) ;
return - 1 ;
}
if ( ! verbose ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 1 ] ) ;
else if ( umoven ( tcp , tcp - > u_arg [ 1 ] ,
len * sizeof ( GETGROUPS_T ) , ( char * ) gidset ) < 0 )
tprintf ( " [?] " ) ;
else {
tprintf ( " [ " ) ;
for ( i = 0 ; i < len ; i + + )
tprintf ( " %s%lu " , i ? " , " : " " ,
( unsigned long ) gidset [ i ] ) ;
tprintf ( " ] " ) ;
}
free ( ( char * ) gidset ) ;
}
return 0 ;
}
int
sys_getgroups ( tcp )
struct tcb * tcp ;
{
int i , len ;
GETGROUPS_T * gidset ;
if ( entering ( tcp ) ) {
len = tcp - > u_arg [ 0 ] ;
tprintf ( " %u, " , len ) ;
} else {
len = tcp - > u_rval ;
if ( len < = 0 ) {
tprintf ( " [] " ) ;
return 0 ;
}
gidset = ( GETGROUPS_T * ) malloc ( len * sizeof ( GETGROUPS_T ) ) ;
if ( gidset = = NULL ) {
fprintf ( stderr , " sys_getgroups: out of memory \n " ) ;
return - 1 ;
}
if ( ! tcp - > u_arg [ 1 ] )
tprintf ( " NULL " ) ;
else if ( ! verbose ( tcp ) | | tcp - > u_arg [ 0 ] = = 0 )
tprintf ( " %#lx " , tcp - > u_arg [ 1 ] ) ;
else if ( umoven ( tcp , tcp - > u_arg [ 1 ] ,
len * sizeof ( GETGROUPS_T ) , ( char * ) gidset ) < 0 )
tprintf ( " [?] " ) ;
else {
tprintf ( " [ " ) ;
for ( i = 0 ; i < len ; i + + )
tprintf ( " %s%lu " , i ? " , " : " " ,
( unsigned long ) gidset [ i ] ) ;
tprintf ( " ] " ) ;
}
free ( ( char * ) gidset ) ;
}
return 0 ;
}
int
sys_setpgrp ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
# ifndef SVR4
tprintf ( " %lu, %lu " , tcp - > u_arg [ 0 ] , tcp - > u_arg [ 1 ] ) ;
# endif /* !SVR4 */
}
return 0 ;
}
int
sys_getpgrp ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
# ifndef SVR4
tprintf ( " %lu " , tcp - > u_arg [ 0 ] ) ;
# endif /* !SVR4 */
}
return 0 ;
}
int
sys_getsid ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " %lu " , tcp - > u_arg [ 0 ] ) ;
}
return 0 ;
}
int
sys_setsid ( tcp )
struct tcb * tcp ;
{
return 0 ;
}
int
sys_getpgid ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " %lu " , tcp - > u_arg [ 0 ] ) ;
}
return 0 ;
}
int
sys_setpgid ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
tprintf ( " %lu, %lu " , tcp - > u_arg [ 0 ] , tcp - > u_arg [ 1 ] ) ;
}
return 0 ;
}
void
fake_execve ( tcp , program , argv , envp )
struct tcb * tcp ;
char * program ;
char * argv [ ] ;
char * envp [ ] ;
{
int i ;
# ifdef ARM
if ( ! ( qual_flags [ SYS_execve - __NR_SYSCALL_BASE ] & QUAL_TRACE ) )
return ;
# else
if ( ! ( qual_flags [ SYS_execve ] & QUAL_TRACE ) )
return ;
# endif /* !ARM */
printleader ( tcp ) ;
tprintf ( " execve( " ) ;
string_quote ( program ) ;
tprintf ( " , [ " ) ;
for ( i = 0 ; argv [ i ] ! = NULL ; i + + ) {
if ( i ! = 0 )
tprintf ( " , " ) ;
string_quote ( argv [ i ] ) ;
}
for ( i = 0 ; envp [ i ] ! = NULL ; i + + )
;
tprintf ( " ], [/* %d var%s */]) " , i , ( i ! = 1 ) ? " s " : " " ) ;
tabto ( acolumn ) ;
tprintf ( " = 0 " ) ;
printtrailer ( tcp ) ;
}
static void
printargv ( tcp , addr )
struct tcb * tcp ;
long addr ;
{
char * cp ;
char * sep ;
int max = max_strlen / 2 ;
for ( sep = " " ; - - max > = 0 ; sep = " , " ) {
if ( ! abbrev ( tcp ) )
max + + ;
if ( umove ( tcp , addr , & cp ) < 0 ) {
tprintf ( " %#lx " , addr ) ;
return ;
}
if ( cp = = 0 )
break ;
tprintf ( sep ) ;
printstr ( tcp , ( long ) cp , - 1 ) ;
addr + = sizeof ( char * ) ;
}
if ( cp )
tprintf ( " , ... " ) ;
}
static void
printargc ( fmt , tcp , addr )
char * fmt ;
struct tcb * tcp ;
long addr ;
{
int count ;
char * cp ;
for ( count = 0 ; umove ( tcp , addr , & cp ) > = 0 & & cp ! = NULL ; count + + ) {
addr + = sizeof ( char * ) ;
}
tprintf ( fmt , count , count = = 1 ? " " : " s " ) ;
}
int
sys_execv ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
printpath ( tcp , tcp - > u_arg [ 0 ] ) ;
if ( ! verbose ( tcp ) )
tprintf ( " , %#lx " , tcp - > u_arg [ 1 ] ) ;
#if 0
else if ( abbrev ( tcp ) )
printargc ( " , [/* %d arg%s */] " , tcp , tcp - > u_arg [ 1 ] ) ;
# endif
else {
tprintf ( " , [ " ) ;
printargv ( tcp , tcp - > u_arg [ 1 ] ) ;
tprintf ( " ] " ) ;
}
}
return 0 ;
}
int
sys_execve ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
printpath ( tcp , tcp - > u_arg [ 0 ] ) ;
if ( ! verbose ( tcp ) )
tprintf ( " , %#lx " , tcp - > u_arg [ 1 ] ) ;
#if 0
else if ( abbrev ( tcp ) )
printargc ( " , [/* %d arg%s */] " , tcp , tcp - > u_arg [ 1 ] ) ;
# endif
else {
tprintf ( " , [ " ) ;
printargv ( tcp , tcp - > u_arg [ 1 ] ) ;
tprintf ( " ] " ) ;
}
if ( ! verbose ( tcp ) )
tprintf ( " , %#lx " , tcp - > u_arg [ 2 ] ) ;
else if ( abbrev ( tcp ) )
printargc ( " , [/* %d var%s */] " , tcp , tcp - > u_arg [ 2 ] ) ;
else {
tprintf ( " , [ " ) ;
printargv ( tcp , tcp - > u_arg [ 2 ] ) ;
tprintf ( " ] " ) ;
}
}
# ifdef LINUX
2001-10-10 03:47:38 +04:00
# if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA)
1999-02-19 03:21:36 +03:00
tcp - > flags | = TCB_WAITEXECVE ;
# endif /* ALPHA || SPARC || POWERPC */
# endif /* LINUX */
return 0 ;
}
2001-04-18 19:11:51 +04:00
# if UNIXWARE > 2
int sys_rexecve ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
sys_execve ( tcp ) ;
tprintf ( " , %ld " , tcp - > u_arg [ 3 ] ) ;
}
return 0 ;
}
# endif
1999-02-19 03:21:36 +03:00
int
internal_exec ( tcp )
struct tcb * tcp ;
{
# ifdef SUNOS4
if ( exiting ( tcp ) & & ! syserror ( tcp ) & & followfork )
fixvfork ( tcp ) ;
# endif /* SUNOS4 */
return 0 ;
}
# ifdef LINUX
# ifndef __WCLONE
# define __WCLONE 0x8000000
# endif
# endif /* LINUX */
static struct xlat wait4_options [ ] = {
{ WNOHANG , " WNOHANG " } ,
# ifndef WSTOPPED
{ WUNTRACED , " WUNTRACED " } ,
# endif
# ifdef WEXITED
{ WEXITED , " WEXITED " } ,
# endif
# ifdef WTRAPPED
{ WTRAPPED , " WTRAPPED " } ,
# endif
# ifdef WSTOPPED
{ WSTOPPED , " WSTOPPED " } ,
# endif
# ifdef WCONTINUED
{ WCONTINUED , " WCONTINUED " } ,
# endif
# ifdef WNOWAIT
{ WNOWAIT , " WNOWAIT " } ,
# endif
# ifdef __WCLONE
{ __WCLONE , " __WCLONE " } ,
# endif
{ 0 , NULL } ,
} ;
static int
printstatus ( status )
int status ;
{
int exited = 0 ;
/*
* Here is a tricky presentation problem . This solution
* is still not entirely satisfactory but since there
* are no wait status constructors it will have to do .
*/
if ( WIFSTOPPED ( status ) )
tprintf ( " [WIFSTOPPED(s) && WSTOPSIG(s) == %s] " ,
1999-03-30 03:23:13 +04:00
signame ( WSTOPSIG ( status ) ) ) ;
1999-02-19 03:21:36 +03:00
else if WIFSIGNALED ( status )
tprintf ( " [WIFSIGNALED(s) && WTERMSIG(s) == %s%s] " ,
1999-03-30 03:23:13 +04:00
signame ( WTERMSIG ( status ) ) ,
1999-02-19 03:21:36 +03:00
WCOREDUMP ( status ) ? " && WCOREDUMP(s) " : " " ) ;
else if WIFEXITED ( status ) {
tprintf ( " [WIFEXITED(s) && WEXITSTATUS(s) == %d] " ,
WEXITSTATUS ( status ) ) ;
exited = 1 ;
}
else
tprintf ( " [%#x] " , status ) ;
return exited ;
}
static int
1999-11-18 20:09:47 +03:00
printwaitn ( tcp , n , bitness )
1999-02-19 03:21:36 +03:00
struct tcb * tcp ;
int n ;
1999-11-18 20:09:47 +03:00
int bitness ;
1999-02-19 03:21:36 +03:00
{
int status ;
int exited = 0 ;
if ( entering ( tcp ) ) {
tprintf ( " %ld, " , tcp - > u_arg [ 0 ] ) ;
} else {
/* status */
if ( ! tcp - > u_arg [ 1 ] )
tprintf ( " NULL " ) ;
else if ( syserror ( tcp ) | | tcp - > u_rval = = 0 )
tprintf ( " %#lx " , tcp - > u_arg [ 1 ] ) ;
else if ( umove ( tcp , tcp - > u_arg [ 1 ] , & status ) < 0 )
tprintf ( " [?] " ) ;
else
exited = printstatus ( status ) ;
/* options */
tprintf ( " , " ) ;
if ( ! printflags ( wait4_options , tcp - > u_arg [ 2 ] ) )
tprintf ( " 0 " ) ;
if ( n = = 4 ) {
tprintf ( " , " ) ;
/* usage */
if ( ! tcp - > u_arg [ 3 ] )
tprintf ( " NULL " ) ;
# ifdef LINUX
1999-11-18 20:09:47 +03:00
else if ( tcp - > u_rval > 0 ) {
# ifdef LINUX_64BIT
if ( bitness )
printrusage32 ( tcp , tcp - > u_arg [ 3 ] ) ;
else
# endif
printrusage ( tcp , tcp - > u_arg [ 3 ] ) ;
}
1999-02-19 03:21:36 +03:00
# endif /* LINUX */
# ifdef SUNOS4
else if ( tcp - > u_rval > 0 & & exited )
printrusage ( tcp , tcp - > u_arg [ 3 ] ) ;
# endif /* SUNOS4 */
else
tprintf ( " %#lx " , tcp - > u_arg [ 3 ] ) ;
}
}
return 0 ;
}
int
internal_wait ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
1999-03-15 22:49:42 +03:00
/* WTA: fix bug with hanging children */
1999-02-19 03:21:36 +03:00
if ( ! ( tcp - > u_arg [ 2 ] & WNOHANG ) & & tcp - > nchildren > 0 ) {
/* There are traced children */
tcp - > flags | = TCB_SUSPENDED ;
tcp - > waitpid = tcp - > u_arg [ 0 ] ;
}
}
return 0 ;
}
# ifdef SVR4
int
sys_wait ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
/* The library wrapper stuffs this into the user variable. */
if ( ! syserror ( tcp ) )
printstatus ( getrval2 ( tcp ) ) ;
}
return 0 ;
}
# endif /* SVR4 */
2000-09-02 01:03:06 +04:00
# ifdef FREEBSD
int
sys_wait ( tcp )
struct tcb * tcp ;
{
int status ;
if ( exiting ( tcp ) ) {
if ( ! syserror ( tcp ) ) {
if ( umove ( tcp , tcp - > u_arg [ 0 ] , & status ) < 0 )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else
printstatus ( status ) ;
}
}
return 0 ;
}
# endif
1999-02-19 03:21:36 +03:00
int
sys_waitpid ( tcp )
struct tcb * tcp ;
{
1999-11-18 20:09:47 +03:00
return printwaitn ( tcp , 3 , 0 ) ;
1999-02-19 03:21:36 +03:00
}
int
sys_wait4 ( tcp )
struct tcb * tcp ;
{
1999-11-18 20:09:47 +03:00
return printwaitn ( tcp , 4 , 0 ) ;
}
# ifdef ALPHA
int
sys_osf_wait4 ( tcp )
struct tcb * tcp ;
{
return printwaitn ( tcp , 4 , 1 ) ;
1999-02-19 03:21:36 +03:00
}
1999-11-18 20:09:47 +03:00
# endif
1999-02-19 03:21:36 +03:00
# ifdef SVR4
static struct xlat waitid_types [ ] = {
{ P_PID , " P_PID " } ,
{ P_PPID , " P_PPID " } ,
{ P_PGID , " P_PGID " } ,
{ P_SID , " P_SID " } ,
{ P_CID , " P_CID " } ,
{ P_UID , " P_UID " } ,
{ P_GID , " P_GID " } ,
{ P_ALL , " P_ALL " } ,
# ifdef P_LWPID
{ P_LWPID , " P_LWPID " } ,
# endif
{ 0 , NULL } ,
} ;
int
sys_waitid ( tcp )
struct tcb * tcp ;
{
siginfo_t si ;
int exited ;
if ( entering ( tcp ) ) {
printxval ( waitid_types , tcp - > u_arg [ 0 ] , " P_??? " ) ;
tprintf ( " , %ld, " , tcp - > u_arg [ 1 ] ) ;
if ( tcp - > nchildren > 0 ) {
/* There are traced children */
tcp - > flags | = TCB_SUSPENDED ;
tcp - > waitpid = tcp - > u_arg [ 0 ] ;
}
}
else {
/* siginfo */
exited = 0 ;
if ( ! tcp - > u_arg [ 2 ] )
tprintf ( " NULL " ) ;
else if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 2 ] ) ;
else if ( umove ( tcp , tcp - > u_arg [ 2 ] , & si ) < 0 )
tprintf ( " {???} " ) ;
else
2001-10-18 19:13:53 +04:00
printsiginfo ( & si , verbose ( tcp ) ) ;
1999-02-19 03:21:36 +03:00
/* options */
tprintf ( " , " ) ;
if ( ! printflags ( wait4_options , tcp - > u_arg [ 3 ] ) )
tprintf ( " 0 " ) ;
}
return 0 ;
}
# endif /* SVR4 */
int
sys_alarm ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) )
tprintf ( " %lu " , tcp - > u_arg [ 0 ] ) ;
return 0 ;
}
int
sys_uname ( tcp )
struct tcb * tcp ;
{
struct utsname uname ;
if ( exiting ( tcp ) ) {
if ( syserror ( tcp ) | | ! verbose ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else if ( umove ( tcp , tcp - > u_arg [ 0 ] , & uname ) < 0 )
tprintf ( " {...} " ) ;
else if ( ! abbrev ( tcp ) ) {
tprintf ( " {sysname= \" %s \" , nodename= \" %s \" , " ,
uname . sysname , uname . nodename ) ;
tprintf ( " release= \" %s \" , version= \" %s \" , " ,
uname . release , uname . version ) ;
tprintf ( " machine= \" %s \" " , uname . machine ) ;
# ifdef LINUX
# ifndef __GLIBC__
tprintf ( " , domainname= \" %s \" " , uname . domainname ) ;
# endif /* __GLIBC__ */
# endif /* LINUX */
tprintf ( " } " ) ;
}
else
tprintf ( " {sys= \" %s \" , node= \" %s \" , ...} " ,
uname . sysname , uname . nodename ) ;
}
return 0 ;
}
# ifndef SVR4
static struct xlat ptrace_cmds [ ] = {
2000-09-02 01:03:06 +04:00
# ifndef FREEBSD
1999-02-19 03:21:36 +03:00
{ PTRACE_TRACEME , " PTRACE_TRACEME " } ,
{ PTRACE_PEEKTEXT , " PTRACE_PEEKTEXT " , } ,
{ PTRACE_PEEKDATA , " PTRACE_PEEKDATA " , } ,
{ PTRACE_PEEKUSER , " PTRACE_PEEKUSER " , } ,
{ PTRACE_POKETEXT , " PTRACE_POKETEXT " , } ,
{ PTRACE_POKEDATA , " PTRACE_POKEDATA " , } ,
{ PTRACE_POKEUSER , " PTRACE_POKEUSER " , } ,
{ PTRACE_CONT , " PTRACE_CONT " } ,
{ PTRACE_KILL , " PTRACE_KILL " } ,
{ PTRACE_SINGLESTEP , " PTRACE_SINGLESTEP " } ,
{ PTRACE_ATTACH , " PTRACE_ATTACH " } ,
{ PTRACE_DETACH , " PTRACE_DETACH " } ,
# ifdef SUNOS4
{ PTRACE_GETREGS , " PTRACE_GETREGS " } ,
{ PTRACE_SETREGS , " PTRACE_SETREGS " } ,
{ PTRACE_GETFPREGS , " PTRACE_GETFPREGS " , } ,
{ PTRACE_SETFPREGS , " PTRACE_SETFPREGS " , } ,
{ PTRACE_READDATA , " PTRACE_READDATA " } ,
{ PTRACE_WRITEDATA , " PTRACE_WRITEDATA " } ,
{ PTRACE_READTEXT , " PTRACE_READTEXT " } ,
{ PTRACE_WRITETEXT , " PTRACE_WRITETEXT " } ,
{ PTRACE_GETFPAREGS , " PTRACE_GETFPAREGS " } ,
{ PTRACE_SETFPAREGS , " PTRACE_SETFPAREGS " } ,
# ifdef SPARC
{ PTRACE_GETWINDOW , " PTRACE_GETWINDOW " } ,
{ PTRACE_SETWINDOW , " PTRACE_SETWINDOW " } ,
# else /* !SPARC */
{ PTRACE_22 , " PTRACE_PTRACE_22 " } ,
{ PTRACE_23 , " PTRACE_PTRACE_23 " } ,
# endif /* !SPARC */
# endif /* SUNOS4 */
{ PTRACE_SYSCALL , " PTRACE_SYSCALL " } ,
# ifdef SUNOS4
{ PTRACE_DUMPCORE , " PTRACE_DUMPCORE " } ,
# ifdef I386
{ PTRACE_SETWRBKPT , " PTRACE_SETWRBKPT " } ,
{ PTRACE_SETACBKPT , " PTRACE_SETACBKPT " } ,
{ PTRACE_CLRDR7 , " PTRACE_CLRDR7 " } ,
# else /* !I386 */
{ PTRACE_26 , " PTRACE_26 " } ,
{ PTRACE_27 , " PTRACE_27 " } ,
{ PTRACE_28 , " PTRACE_28 " } ,
# endif /* !I386 */
{ PTRACE_GETUCODE , " PTRACE_GETUCODE " } ,
# endif /* SUNOS4 */
2000-09-02 01:03:06 +04:00
# else /* FREEBSD */
{ PT_TRACE_ME , " PT_TRACE_ME " } ,
{ PT_READ_I , " PT_READ_I " } ,
{ PT_READ_D , " PT_READ_D " } ,
{ PT_WRITE_I , " PT_WRITE_I " } ,
{ PT_WRITE_D , " PT_WRITE_D " } ,
2001-09-28 20:21:30 +04:00
# ifdef PT_READ_U
{ PT_READ_U , " PT_READ_U " } ,
# endif
2000-09-02 01:03:06 +04:00
{ PT_CONTINUE , " PT_CONTINUE " } ,
{ PT_KILL , " PT_KILL " } ,
{ PT_STEP , " PT_STEP " } ,
{ PT_ATTACH , " PT_ATTACH " } ,
{ PT_DETACH , " PT_DETACH " } ,
{ PT_GETREGS , " PT_GETREGS " } ,
{ PT_SETREGS , " PT_SETREGS " } ,
{ PT_GETFPREGS , " PT_GETFPREGS " } ,
{ PT_SETFPREGS , " PT_SETFPREGS " } ,
{ PT_GETDBREGS , " PT_GETDBREGS " } ,
{ PT_SETDBREGS , " PT_SETDBREGS " } ,
# endif /* FREEBSD */
1999-02-19 03:21:36 +03:00
{ 0 , NULL } ,
} ;
2000-09-02 01:03:06 +04:00
# ifndef FREEBSD
1999-02-19 03:21:36 +03:00
# ifndef SUNOS4_KERNEL_ARCH_KLUDGE
static
# endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
struct xlat struct_user_offsets [ ] = {
# ifdef LINUX
1999-12-23 17:20:14 +03:00
# ifdef S390
{ PT_PSWMASK , " psw_mask " } ,
{ PT_PSWADDR , " psw_addr " } ,
{ PT_GPR0 , " gpr0 " } ,
{ PT_GPR1 , " gpr1 " } ,
{ PT_GPR2 , " gpr2 " } ,
{ PT_GPR3 , " gpr3 " } ,
{ PT_GPR4 , " gpr4 " } ,
{ PT_GPR5 , " gpr5 " } ,
{ PT_GPR6 , " gpr6 " } ,
{ PT_GPR7 , " gpr7 " } ,
{ PT_GPR8 , " gpr8 " } ,
{ PT_GPR9 , " gpr9 " } ,
{ PT_GPR10 , " gpr10 " } ,
{ PT_GPR11 , " gpr11 " } ,
{ PT_GPR12 , " gpr12 " } ,
{ PT_GPR13 , " gpr13 " } ,
{ PT_GPR14 , " gpr14 " } ,
{ PT_GPR15 , " gpr15 " } ,
{ PT_ACR0 , " acr0 " } ,
{ PT_ACR1 , " acr1 " } ,
{ PT_ACR2 , " acr2 " } ,
{ PT_ACR3 , " acr3 " } ,
{ PT_ACR4 , " acr4 " } ,
{ PT_ACR5 , " acr5 " } ,
{ PT_ACR6 , " acr6 " } ,
{ PT_ACR7 , " acr7 " } ,
{ PT_ACR8 , " acr8 " } ,
{ PT_ACR9 , " acr9 " } ,
{ PT_ACR10 , " acr10 " } ,
{ PT_ACR11 , " acr11 " } ,
{ PT_ACR12 , " acr12 " } ,
{ PT_ACR13 , " acr13 " } ,
{ PT_ACR14 , " acr14 " } ,
{ PT_ACR15 , " acr15 " } ,
{ PT_ORIGGPR2 , " orig_gpr2 " } ,
{ PT_FPC , " fpc " } ,
{ PT_FPR0_HI , " fpr0.hi " } ,
{ PT_FPR0_LO , " fpr0.lo " } ,
{ PT_FPR1_HI , " fpr1.hi " } ,
{ PT_FPR1_LO , " fpr1.lo " } ,
{ PT_FPR2_HI , " fpr2.hi " } ,
{ PT_FPR2_LO , " fpr2.lo " } ,
{ PT_FPR3_HI , " fpr3.hi " } ,
{ PT_FPR3_LO , " fpr3.lo " } ,
{ PT_FPR4_HI , " fpr4.hi " } ,
{ PT_FPR4_LO , " fpr4.lo " } ,
{ PT_FPR5_HI , " fpr5.hi " } ,
{ PT_FPR5_LO , " fpr5.lo " } ,
{ PT_FPR6_HI , " fpr6.hi " } ,
{ PT_FPR6_LO , " fpr6.lo " } ,
{ PT_FPR7_HI , " fpr7.hi " } ,
{ PT_FPR7_LO , " fpr7.lo " } ,
{ PT_FPR8_HI , " fpr8.hi " } ,
{ PT_FPR8_LO , " fpr8.lo " } ,
{ PT_FPR9_HI , " fpr9.hi " } ,
{ PT_FPR9_LO , " fpr9.lo " } ,
{ PT_FPR10_HI , " fpr10.hi " } ,
{ PT_FPR10_LO , " fpr10.lo " } ,
{ PT_FPR11_HI , " fpr11.hi " } ,
{ PT_FPR11_LO , " fpr11.lo " } ,
{ PT_FPR12_HI , " fpr12.hi " } ,
{ PT_FPR12_LO , " fpr12.lo " } ,
{ PT_FPR13_HI , " fpr13.hi " } ,
{ PT_FPR13_LO , " fpr13.lo " } ,
{ PT_FPR14_HI , " fpr14.hi " } ,
{ PT_FPR14_LO , " fpr14.lo " } ,
{ PT_FPR15_HI , " fpr15.hi " } ,
{ PT_FPR15_LO , " fpr15.lo " } ,
{ PT_CR_9 , " cr9 " } ,
{ PT_CR_10 , " cr10 " } ,
{ PT_CR_11 , " cr11 " } ,
# endif
# if defined(SPARC)
1999-02-19 03:21:36 +03:00
/* XXX No support for these offsets yet. */
2001-03-27 16:17:16 +04:00
# elif defined(HPPA)
/* XXX No support for these offsets yet. */
1999-02-19 03:21:36 +03:00
# elif defined(POWERPC)
1999-12-23 17:20:14 +03:00
{ 4 * PT_R0 , " 4*PT_R0 " } ,
{ 4 * PT_R1 , " 4*PT_R1 " } ,
{ 4 * PT_R2 , " 4*PT_R2 " } ,
{ 4 * PT_R3 , " 4*PT_R3 " } ,
{ 4 * PT_R4 , " 4*PT_R4 " } ,
{ 4 * PT_R5 , " 4*PT_R5 " } ,
{ 4 * PT_R6 , " 4*PT_R6 " } ,
{ 4 * PT_R7 , " 4*PT_R7 " } ,
{ 4 * PT_R8 , " 4*PT_R8 " } ,
{ 4 * PT_R9 , " 4*PT_R9 " } ,
{ 4 * PT_R10 , " 4*PT_R10 " } ,
{ 4 * PT_R11 , " 4*PT_R11 " } ,
{ 4 * PT_R12 , " 4*PT_R12 " } ,
{ 4 * PT_R13 , " 4*PT_R13 " } ,
{ 4 * PT_R14 , " 4*PT_R14 " } ,
{ 4 * PT_R15 , " 4*PT_R15 " } ,
{ 4 * PT_R16 , " 4*PT_R16 " } ,
{ 4 * PT_R17 , " 4*PT_R17 " } ,
{ 4 * PT_R18 , " 4*PT_R18 " } ,
{ 4 * PT_R19 , " 4*PT_R19 " } ,
{ 4 * PT_R20 , " 4*PT_R20 " } ,
{ 4 * PT_R21 , " 4*PT_R21 " } ,
{ 4 * PT_R22 , " 4*PT_R22 " } ,
{ 4 * PT_R23 , " 4*PT_R23 " } ,
{ 4 * PT_R24 , " 4*PT_R24 " } ,
{ 4 * PT_R25 , " 4*PT_R25 " } ,
{ 4 * PT_R26 , " 4*PT_R26 " } ,
{ 4 * PT_R27 , " 4*PT_R27 " } ,
{ 4 * PT_R28 , " 4*PT_R28 " } ,
{ 4 * PT_R29 , " 4*PT_R29 " } ,
{ 4 * PT_R30 , " 4*PT_R30 " } ,
{ 4 * PT_R31 , " 4*PT_R31 " } ,
{ 4 * PT_NIP , " 4*PT_NIP " } ,
{ 4 * PT_MSR , " 4*PT_MSR " } ,
{ 4 * PT_ORIG_R3 , " 4*PT_ORIG_R3 " } ,
{ 4 * PT_CTR , " 4*PT_CTR " } ,
{ 4 * PT_LNK , " 4*PT_LNK " } ,
{ 4 * PT_XER , " 4*PT_XER " } ,
{ 4 * PT_CCR , " 4*PT_CCR " } ,
{ 4 * PT_FPR0 , " 4*PT_FPR0 " } ,
1999-02-19 03:21:36 +03:00
# else
# ifdef ALPHA
1999-12-23 17:20:14 +03:00
{ 0 , " r0 " } ,
{ 1 , " r1 " } ,
{ 2 , " r2 " } ,
{ 3 , " r3 " } ,
{ 4 , " r4 " } ,
{ 5 , " r5 " } ,
{ 6 , " r6 " } ,
{ 7 , " r7 " } ,
{ 8 , " r8 " } ,
{ 9 , " r9 " } ,
{ 10 , " r10 " } ,
{ 11 , " r11 " } ,
{ 12 , " r12 " } ,
{ 13 , " r13 " } ,
{ 14 , " r14 " } ,
{ 15 , " r15 " } ,
{ 16 , " r16 " } ,
{ 17 , " r17 " } ,
{ 18 , " r18 " } ,
{ 19 , " r19 " } ,
{ 20 , " r20 " } ,
{ 21 , " r21 " } ,
{ 22 , " r22 " } ,
{ 23 , " r23 " } ,
{ 24 , " r24 " } ,
{ 25 , " r25 " } ,
{ 26 , " r26 " } ,
{ 27 , " r27 " } ,
{ 28 , " r28 " } ,
{ 29 , " gp " } ,
{ 30 , " fp " } ,
{ 31 , " zero " } ,
{ 32 , " fp0 " } ,
{ 33 , " fp " } ,
{ 34 , " fp2 " } ,
{ 35 , " fp3 " } ,
{ 36 , " fp4 " } ,
{ 37 , " fp5 " } ,
{ 38 , " fp6 " } ,
{ 39 , " fp7 " } ,
{ 40 , " fp8 " } ,
{ 41 , " fp9 " } ,
{ 42 , " fp10 " } ,
{ 43 , " fp11 " } ,
{ 44 , " fp12 " } ,
{ 45 , " fp13 " } ,
{ 46 , " fp14 " } ,
{ 47 , " fp15 " } ,
{ 48 , " fp16 " } ,
{ 49 , " fp17 " } ,
{ 50 , " fp18 " } ,
{ 51 , " fp19 " } ,
{ 52 , " fp20 " } ,
{ 53 , " fp21 " } ,
{ 54 , " fp22 " } ,
{ 55 , " fp23 " } ,
{ 56 , " fp24 " } ,
{ 57 , " fp25 " } ,
{ 58 , " fp26 " } ,
{ 59 , " fp27 " } ,
{ 60 , " fp28 " } ,
{ 61 , " fp29 " } ,
{ 62 , " fp30 " } ,
{ 63 , " fp31 " } ,
{ 64 , " pc " } ,
1999-02-19 03:21:36 +03:00
# else /* !ALPHA */
2000-02-04 00:58:30 +03:00
# ifdef IA64
{ PT_F32 , " f32 " } , { PT_F33 , " f33 " } , { PT_F34 , " f34 " } ,
{ PT_F35 , " f35 " } , { PT_F36 , " f36 " } , { PT_F37 , " f37 " } ,
{ PT_F38 , " f38 " } , { PT_F39 , " f39 " } , { PT_F40 , " f40 " } ,
{ PT_F41 , " f41 " } , { PT_F42 , " f42 " } , { PT_F43 , " f43 " } ,
{ PT_F44 , " f44 " } , { PT_F45 , " f45 " } , { PT_F46 , " f46 " } ,
{ PT_F47 , " f47 " } , { PT_F48 , " f48 " } , { PT_F49 , " f49 " } ,
{ PT_F50 , " f50 " } , { PT_F51 , " f51 " } , { PT_F52 , " f52 " } ,
{ PT_F53 , " f53 " } , { PT_F54 , " f54 " } , { PT_F55 , " f55 " } ,
{ PT_F56 , " f56 " } , { PT_F57 , " f57 " } , { PT_F58 , " f58 " } ,
{ PT_F59 , " f59 " } , { PT_F60 , " f60 " } , { PT_F61 , " f61 " } ,
{ PT_F62 , " f62 " } , { PT_F63 , " f63 " } , { PT_F64 , " f64 " } ,
{ PT_F65 , " f65 " } , { PT_F66 , " f66 " } , { PT_F67 , " f67 " } ,
{ PT_F68 , " f68 " } , { PT_F69 , " f69 " } , { PT_F70 , " f70 " } ,
{ PT_F71 , " f71 " } , { PT_F72 , " f72 " } , { PT_F73 , " f73 " } ,
{ PT_F74 , " f74 " } , { PT_F75 , " f75 " } , { PT_F76 , " f76 " } ,
{ PT_F77 , " f77 " } , { PT_F78 , " f78 " } , { PT_F79 , " f79 " } ,
{ PT_F80 , " f80 " } , { PT_F81 , " f81 " } , { PT_F82 , " f82 " } ,
{ PT_F83 , " f83 " } , { PT_F84 , " f84 " } , { PT_F85 , " f85 " } ,
{ PT_F86 , " f86 " } , { PT_F87 , " f87 " } , { PT_F88 , " f88 " } ,
{ PT_F89 , " f89 " } , { PT_F90 , " f90 " } , { PT_F91 , " f91 " } ,
{ PT_F92 , " f92 " } , { PT_F93 , " f93 " } , { PT_F94 , " f94 " } ,
{ PT_F95 , " f95 " } , { PT_F96 , " f96 " } , { PT_F97 , " f97 " } ,
{ PT_F98 , " f98 " } , { PT_F99 , " f99 " } , { PT_F100 , " f100 " } ,
{ PT_F101 , " f101 " } , { PT_F102 , " f102 " } , { PT_F103 , " f103 " } ,
{ PT_F104 , " f104 " } , { PT_F105 , " f105 " } , { PT_F106 , " f106 " } ,
{ PT_F107 , " f107 " } , { PT_F108 , " f108 " } , { PT_F109 , " f109 " } ,
{ PT_F110 , " f110 " } , { PT_F111 , " f111 " } , { PT_F112 , " f112 " } ,
{ PT_F113 , " f113 " } , { PT_F114 , " f114 " } , { PT_F115 , " f115 " } ,
{ PT_F116 , " f116 " } , { PT_F117 , " f117 " } , { PT_F118 , " f118 " } ,
{ PT_F119 , " f119 " } , { PT_F120 , " f120 " } , { PT_F121 , " f121 " } ,
{ PT_F122 , " f122 " } , { PT_F123 , " f123 " } , { PT_F124 , " f124 " } ,
{ PT_F125 , " f125 " } , { PT_F126 , " f126 " } , { PT_F127 , " f127 " } ,
/* switch stack: */
{ PT_F2 , " f2 " } , { PT_F3 , " f3 " } , { PT_F4 , " f4 " } ,
{ PT_F5 , " f5 " } , { PT_F10 , " f10 " } , { PT_F11 , " f11 " } ,
{ PT_F12 , " f12 " } , { PT_F13 , " f13 " } , { PT_F14 , " f14 " } ,
{ PT_F15 , " f15 " } , { PT_F16 , " f16 " } , { PT_F17 , " f17 " } ,
{ PT_F18 , " f18 " } , { PT_F19 , " f19 " } , { PT_F20 , " f20 " } ,
{ PT_F21 , " f21 " } , { PT_F22 , " f22 " } , { PT_F23 , " f23 " } ,
{ PT_F24 , " f24 " } , { PT_F25 , " f25 " } , { PT_F26 , " f26 " } ,
{ PT_F27 , " f27 " } , { PT_F28 , " f28 " } , { PT_F29 , " f29 " } ,
{ PT_F30 , " f30 " } , { PT_F31 , " f31 " } , { PT_R4 , " r4 " } ,
{ PT_R5 , " r5 " } , { PT_R6 , " r6 " } , { PT_R7 , " r7 " } ,
2001-08-03 15:51:28 +04:00
{ PT_B0 , " kb0 " } ,
2000-02-04 00:58:30 +03:00
{ PT_B1 , " b1 " } , { PT_B2 , " b2 " } , { PT_B3 , " b3 " } ,
{ PT_B4 , " b4 " } , { PT_B5 , " b5 " } ,
2001-08-03 15:51:28 +04:00
{ PT_AR_PFS , " kar.pfs " } ,
{ PT_AR_LC , " ar.lc " } , { PT_AR_UNAT , " kar.unat " } ,
{ PT_AR_RNAT , " kar.rnat " } , { PT_AR_BSPSTORE , " kar.bspstore " } ,
{ PT_PR , " k.pr " } ,
2000-02-04 00:58:30 +03:00
/* pt_regs */
{ PT_CR_IPSR , " cr.ipsr " } , { PT_CR_IIP , " cr.iip " } ,
2001-08-03 15:51:28 +04:00
/*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT , " ar.unat " } ,
2000-02-04 00:58:30 +03:00
{ PT_AR_PFS , " ar.pfs " } , { PT_AR_RSC , " ar.rsc " } ,
{ PT_AR_RNAT , " ar.rnat " } , { PT_AR_BSPSTORE , " ar.bspstore " } ,
{ PT_PR , " pr " } , { PT_B6 , " b6 " } , { PT_AR_BSP , " ar.bsp " } ,
{ PT_R1 , " r1 " } , { PT_R2 , " r2 " } , { PT_R3 , " r3 " } ,
{ PT_R12 , " r12 " } , { PT_R13 , " r13 " } , { PT_R14 , " r14 " } ,
{ PT_R15 , " r15 " } , { PT_R8 , " r8 " } , { PT_R9 , " r9 " } ,
{ PT_R10 , " r10 " } , { PT_R11 , " r11 " } , { PT_R16 , " r16 " } ,
{ PT_R17 , " r17 " } , { PT_R18 , " r18 " } , { PT_R19 , " r19 " } ,
{ PT_R20 , " r20 " } , { PT_R21 , " r21 " } , { PT_R22 , " r22 " } ,
{ PT_R23 , " r23 " } , { PT_R24 , " r24 " } , { PT_R25 , " r25 " } ,
{ PT_R26 , " r26 " } , { PT_R27 , " r27 " } , { PT_R28 , " r28 " } ,
{ PT_R29 , " r29 " } , { PT_R30 , " r30 " } , { PT_R31 , " r31 " } ,
{ PT_AR_CCV , " ar.ccv " } , { PT_AR_FPSR , " ar.fpsr " } ,
{ PT_B0 , " b0 " } , { PT_B7 , " b7 " } , { PT_F6 , " f6 " } ,
{ PT_F7 , " f7 " } , { PT_F8 , " f8 " } , { PT_F9 , " f9 " } ,
# else /* !IA64 */
1999-02-19 03:21:36 +03:00
# ifdef I386
{ 4 * EBX , " 4*EBX " } ,
{ 4 * ECX , " 4*ECX " } ,
{ 4 * EDX , " 4*EDX " } ,
{ 4 * ESI , " 4*ESI " } ,
{ 4 * EDI , " 4*EDI " } ,
{ 4 * EBP , " 4*EBP " } ,
{ 4 * EAX , " 4*EAX " } ,
{ 4 * DS , " 4*DS " } ,
{ 4 * ES , " 4*ES " } ,
{ 4 * FS , " 4*FS " } ,
{ 4 * GS , " 4*GS " } ,
{ 4 * ORIG_EAX , " 4*ORIG_EAX " } ,
{ 4 * EIP , " 4*EIP " } ,
{ 4 * CS , " 4*CS " } ,
{ 4 * EFL , " 4*EFL " } ,
{ 4 * UESP , " 4*UESP " } ,
{ 4 * SS , " 4*SS " } ,
# else /* !I386 */
# ifdef M68K
{ 4 * PT_D1 , " 4*PT_D1 " } ,
{ 4 * PT_D2 , " 4*PT_D2 " } ,
{ 4 * PT_D3 , " 4*PT_D3 " } ,
{ 4 * PT_D4 , " 4*PT_D4 " } ,
{ 4 * PT_D5 , " 4*PT_D5 " } ,
{ 4 * PT_D6 , " 4*PT_D6 " } ,
{ 4 * PT_D7 , " 4*PT_D7 " } ,
{ 4 * PT_A0 , " 4*PT_A0 " } ,
{ 4 * PT_A1 , " 4*PT_A1 " } ,
{ 4 * PT_A2 , " 4*PT_A2 " } ,
{ 4 * PT_A3 , " 4*PT_A3 " } ,
{ 4 * PT_A4 , " 4*PT_A4 " } ,
{ 4 * PT_A5 , " 4*PT_A5 " } ,
{ 4 * PT_A6 , " 4*PT_A6 " } ,
{ 4 * PT_D0 , " 4*PT_D0 " } ,
{ 4 * PT_USP , " 4*PT_USP " } ,
{ 4 * PT_ORIG_D0 , " 4*PT_ORIG_D0 " } ,
{ 4 * PT_SR , " 4*PT_SR " } ,
{ 4 * PT_PC , " 4*PT_PC " } ,
# endif /* M68K */
# endif /* !I386 */
2000-02-14 19:23:40 +03:00
# if !defined(S390) && !defined(MIPS)
1999-02-19 03:21:36 +03:00
{ uoff ( u_fpvalid ) , " offsetof(struct user, u_fpvalid) " } ,
1999-11-01 00:15:38 +03:00
# endif
1999-02-19 03:21:36 +03:00
# ifdef I386
{ uoff ( i387 ) , " offsetof(struct user, i387) " } ,
# else /* !I386 */
# ifdef M68K
{ uoff ( m68kfp ) , " offsetof(struct user, m68kfp) " } ,
# endif /* M68K */
# endif /* !I386 */
{ uoff ( u_tsize ) , " offsetof(struct user, u_tsize) " } ,
{ uoff ( u_dsize ) , " offsetof(struct user, u_dsize) " } ,
{ uoff ( u_ssize ) , " offsetof(struct user, u_ssize) " } ,
{ uoff ( start_code ) , " offsetof(struct user, start_code) " } ,
{ uoff ( start_stack ) , " offsetof(struct user, start_stack) " } ,
{ uoff ( signal ) , " offsetof(struct user, signal) " } ,
2000-02-14 19:23:40 +03:00
# if !defined(S390) && !defined(MIPS)
1999-02-19 03:21:36 +03:00
{ uoff ( reserved ) , " offsetof(struct user, reserved) " } ,
1999-11-01 00:15:38 +03:00
# endif
1999-02-19 03:21:36 +03:00
{ uoff ( u_ar0 ) , " offsetof(struct user, u_ar0) " } ,
1999-12-23 17:20:14 +03:00
# if !defined(ARM) && !defined(MIPS) && !defined(S390)
1999-02-19 03:21:36 +03:00
{ uoff ( u_fpstate ) , " offsetof(struct user, u_fpstate) " } ,
# endif
{ uoff ( magic ) , " offsetof(struct user, magic) " } ,
{ uoff ( u_comm ) , " offsetof(struct user, u_comm) " } ,
# ifdef I386
{ uoff ( u_debugreg ) , " offsetof(struct user, u_debugreg) " } ,
# endif /* I386 */
2000-02-04 00:58:30 +03:00
# endif /* !IA64 */
1999-02-19 03:21:36 +03:00
# endif /* !ALPHA */
# endif /* !POWERPC/!SPARC */
# endif /* LINUX */
# ifdef SUNOS4
{ uoff ( u_pcb ) , " offsetof(struct user, u_pcb) " } ,
{ uoff ( u_procp ) , " offsetof(struct user, u_procp) " } ,
{ uoff ( u_ar0 ) , " offsetof(struct user, u_ar0) " } ,
{ uoff ( u_comm [ 0 ] ) , " offsetof(struct user, u_comm[0]) " } ,
{ uoff ( u_arg [ 0 ] ) , " offsetof(struct user, u_arg[0]) " } ,
{ uoff ( u_ap ) , " offsetof(struct user, u_ap) " } ,
{ uoff ( u_qsave ) , " offsetof(struct user, u_qsave) " } ,
{ uoff ( u_rval1 ) , " offsetof(struct user, u_rval1) " } ,
{ uoff ( u_rval2 ) , " offsetof(struct user, u_rval2) " } ,
{ uoff ( u_error ) , " offsetof(struct user, u_error) " } ,
{ uoff ( u_eosys ) , " offsetof(struct user, u_eosys) " } ,
{ uoff ( u_ssave ) , " offsetof(struct user, u_ssave) " } ,
{ uoff ( u_signal [ 0 ] ) , " offsetof(struct user, u_signal) " } ,
{ uoff ( u_sigmask [ 0 ] ) , " offsetof(struct user, u_sigmask) " } ,
{ uoff ( u_sigonstack ) , " offsetof(struct user, u_sigonstack) " } ,
{ uoff ( u_sigintr ) , " offsetof(struct user, u_sigintr) " } ,
{ uoff ( u_sigreset ) , " offsetof(struct user, u_sigreset) " } ,
{ uoff ( u_oldmask ) , " offsetof(struct user, u_oldmask) " } ,
{ uoff ( u_code ) , " offsetof(struct user, u_code) " } ,
{ uoff ( u_addr ) , " offsetof(struct user, u_addr) " } ,
{ uoff ( u_sigstack ) , " offsetof(struct user, u_sigstack) " } ,
{ uoff ( u_ofile ) , " offsetof(struct user, u_ofile) " } ,
{ uoff ( u_pofile ) , " offsetof(struct user, u_pofile) " } ,
{ uoff ( u_ofile_arr [ 0 ] ) , " offsetof(struct user, u_ofile_arr[0]) " } ,
{ uoff ( u_pofile_arr [ 0 ] ) , " offsetof(struct user, u_pofile_arr[0]) " } ,
{ uoff ( u_lastfile ) , " offsetof(struct user, u_lastfile) " } ,
{ uoff ( u_cwd ) , " offsetof(struct user, u_cwd) " } ,
{ uoff ( u_cdir ) , " offsetof(struct user, u_cdir) " } ,
{ uoff ( u_rdir ) , " offsetof(struct user, u_rdir) " } ,
{ uoff ( u_cmask ) , " offsetof(struct user, u_cmask) " } ,
{ uoff ( u_ru ) , " offsetof(struct user, u_ru) " } ,
{ uoff ( u_cru ) , " offsetof(struct user, u_cru) " } ,
{ uoff ( u_timer [ 0 ] ) , " offsetof(struct user, u_timer[0]) " } ,
{ uoff ( u_XXX [ 0 ] ) , " offsetof(struct user, u_XXX[0]) " } ,
{ uoff ( u_ioch ) , " offsetof(struct user, u_ioch) " } ,
{ uoff ( u_start ) , " offsetof(struct user, u_start) " } ,
{ uoff ( u_acflag ) , " offsetof(struct user, u_acflag) " } ,
{ uoff ( u_prof . pr_base ) , " offsetof(struct user, u_prof.pr_base) " } ,
{ uoff ( u_prof . pr_size ) , " offsetof(struct user, u_prof.pr_size) " } ,
{ uoff ( u_prof . pr_off ) , " offsetof(struct user, u_prof.pr_off) " } ,
{ uoff ( u_prof . pr_scale ) , " offsetof(struct user, u_prof.pr_scale) " } ,
{ uoff ( u_rlimit [ 0 ] ) , " offsetof(struct user, u_rlimit) " } ,
{ uoff ( u_exdata . Ux_A ) , " offsetof(struct user, u_exdata.Ux_A) " } ,
{ uoff ( u_exdata . ux_shell [ 0 ] ) , " offsetof(struct user, u_exdata.ux_shell[0]) " } ,
{ uoff ( u_lofault ) , " offsetof(struct user, u_lofault) " } ,
# endif /* SUNOS4 */
2001-03-27 16:17:16 +04:00
# ifndef HPPA
1999-02-19 03:21:36 +03:00
{ sizeof ( struct user ) , " sizeof(struct user) " } ,
2001-03-27 16:17:16 +04:00
# endif
1999-02-19 03:21:36 +03:00
{ 0 , NULL } ,
} ;
2000-09-02 01:03:06 +04:00
# endif
1999-02-19 03:21:36 +03:00
int
sys_ptrace ( tcp )
struct tcb * tcp ;
{
char * cmd ;
struct xlat * x ;
long addr ;
cmd = xlookup ( ptrace_cmds , tcp - > u_arg [ 0 ] ) ;
if ( ! cmd )
2000-09-02 01:03:06 +04:00
# ifndef FREEBSD
1999-02-19 03:21:36 +03:00
cmd = " PTRACE_??? " ;
2000-09-02 01:03:06 +04:00
# else
cmd = " PT_??? " ;
# endif
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
tprintf ( " %s, %lu, " , cmd , tcp - > u_arg [ 1 ] ) ;
addr = tcp - > u_arg [ 2 ] ;
2000-09-02 01:03:06 +04:00
# ifndef FREEBSD
1999-02-19 03:21:36 +03:00
if ( tcp - > u_arg [ 0 ] = = PTRACE_PEEKUSER
| | tcp - > u_arg [ 0 ] = = PTRACE_POKEUSER ) {
for ( x = struct_user_offsets ; x - > str ; x + + ) {
if ( x - > val > = addr )
break ;
}
if ( ! x - > str )
tprintf ( " %#lx, " , addr ) ;
else if ( x - > val > addr & & x ! = struct_user_offsets ) {
x - - ;
tprintf ( " %s + %ld, " , x - > str , addr - x - > val ) ;
}
else
tprintf ( " %s, " , x - > str ) ;
}
else
2000-09-02 01:03:06 +04:00
# endif
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx, " , tcp - > u_arg [ 2 ] ) ;
# ifdef LINUX
switch ( tcp - > u_arg [ 0 ] ) {
case PTRACE_PEEKDATA :
case PTRACE_PEEKTEXT :
case PTRACE_PEEKUSER :
break ;
case PTRACE_CONT :
case PTRACE_SINGLESTEP :
case PTRACE_SYSCALL :
case PTRACE_DETACH :
printsignal ( tcp - > u_arg [ 3 ] ) ;
break ;
default :
tprintf ( " %#lx " , tcp - > u_arg [ 3 ] ) ;
break ;
}
} else {
switch ( tcp - > u_arg [ 0 ] ) {
case PTRACE_PEEKDATA :
case PTRACE_PEEKTEXT :
case PTRACE_PEEKUSER :
printnum ( tcp , tcp - > u_arg [ 3 ] , " %#x " ) ;
break ;
}
}
# endif /* LINUX */
# ifdef SUNOS4
if ( tcp - > u_arg [ 0 ] = = PTRACE_WRITEDATA | |
tcp - > u_arg [ 0 ] = = PTRACE_WRITETEXT ) {
tprintf ( " %lu, " , tcp - > u_arg [ 3 ] ) ;
printstr ( tcp , tcp - > u_arg [ 4 ] , tcp - > u_arg [ 3 ] ) ;
} else if ( tcp - > u_arg [ 0 ] ! = PTRACE_READDATA & &
tcp - > u_arg [ 0 ] ! = PTRACE_READTEXT ) {
tprintf ( " %#lx " , tcp - > u_arg [ 3 ] ) ;
}
} else {
if ( tcp - > u_arg [ 0 ] = = PTRACE_READDATA | |
tcp - > u_arg [ 0 ] = = PTRACE_READTEXT ) {
tprintf ( " %lu, " , tcp - > u_arg [ 3 ] ) ;
printstr ( tcp , tcp - > u_arg [ 4 ] , tcp - > u_arg [ 3 ] ) ;
}
}
# endif /* SUNOS4 */
2000-09-02 01:03:06 +04:00
# ifdef FREEBSD
tprintf ( " %lu " , tcp - > u_arg [ 3 ] ) ;
}
# endif /* FREEBSD */
1999-02-19 03:21:36 +03:00
return 0 ;
}
# endif /* !SVR4 */